summaryrefslogtreecommitdiff
path: root/print-mptcp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2013-04-14 16:55:45 -0700
committerGuy Harris <guy@alum.mit.edu>2013-04-14 16:55:45 -0700
commit9716f7bd0f54ba52ef3faa6339ea8902fd39b0c3 (patch)
treea8f63ab3c23d94c88cbeeac0a645f54da14c6c84 /print-mptcp.c
parent02da852383cf2aac72b3ad77e69799a44adb97e8 (diff)
parent62e953465041494c8b3be83927267f373e9dd6ef (diff)
downloadtcpdump-9716f7bd0f54ba52ef3faa6339ea8902fd39b0c3.tar.gz
Merge branch 'master' of git+ssh://bpf.tcpdump.org/tcpdump/master/git/tcpdump
Diffstat (limited to 'print-mptcp.c')
-rw-r--r--print-mptcp.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/print-mptcp.c b/print-mptcp.c
new file mode 100644
index 00000000..66b3adb1
--- /dev/null
+++ b/print-mptcp.c
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2012
+ *
+ * Gregory Detal <gregory.detal@uclouvain.be>
+ * Christoph Paasch <christoph.paasch@uclouvain.be>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "ipproto.h"
+#include "mptcp.h"
+
+static int dummy_print(const u_char *opt, u_int opt_len)
+{
+ return 1;
+}
+
+static int mp_capable_print(const u_char *opt, u_int opt_len)
+{
+ struct mp_capable *mpc = (struct mp_capable *) opt;
+
+ if (mpc->c)
+ printf(" csum");
+ printf(" {0x%" PRIx64, mpc->sender_key);
+ if (opt_len == 20)
+ printf(",0x%" PRIx64, mpc->receiver_key);
+ printf("}");
+ return 1;
+}
+
+static int mp_join_print(const u_char *opt, u_int opt_len)
+{
+ struct mp_join *mpj = (struct mp_join *) opt;
+
+ if (mpj->b)
+ printf(" backup");
+ printf(" id %" PRIu8, mpj->addr_id);
+
+ if (opt_len == 12)
+ printf(" token 0x%" PRIx32, mpj->u.syn.token);
+
+ return 1;
+}
+
+static u_int mp_dss_len(struct mp_dss *m, u_int csum)
+{
+ return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2);
+}
+
+static int mp_dss_print(const u_char *opt, u_int opt_len)
+{
+ struct mp_dss *mdss = (struct mp_dss *) opt;
+
+ if (mdss->F)
+ printf(" fin");
+
+ opt += 4;
+ if (mdss->A) {
+ printf(" ack ");
+ if (mdss->a)
+ printf("%" PRIu64, EXTRACT_64BITS(opt));
+ else
+ printf("%" PRIu32, EXTRACT_32BITS(opt));
+ opt += mdss->a ? 8 : 4;
+ }
+
+ if (mdss->M) {
+ printf(" seq ");
+ if (mdss->m)
+ printf("%" PRIu64, EXTRACT_64BITS(opt));
+ else
+ printf("%" PRIu32, EXTRACT_32BITS(opt));
+ opt += mdss->m ? 8 : 4;
+ printf(" subseq %" PRIu32, EXTRACT_32BITS(opt));
+ opt += 4;
+ printf(" len %" PRIu16, EXTRACT_16BITS(opt));
+ opt += 2;
+
+ if (opt_len == mp_dss_len(mdss, 1))
+ printf(" csum 0x%" PRIx16, EXTRACT_16BITS(opt));
+ }
+ return 1;
+}
+
+static int add_addr_print(const u_char *opt, u_int opt_len)
+{
+ struct mp_add_addr *add_addr = (struct mp_add_addr *) opt;
+
+ printf(" id %" PRIu8, add_addr->addr_id);
+ switch (add_addr->ipver) {
+ case 4:
+ printf(" %s", ipaddr_string(&add_addr->u.v4.addr));
+ break;
+#ifdef INET6
+ case 6:
+ printf(" %s", ip6addr_string(&add_addr->u.v6.addr));
+ break;
+#endif
+ default:
+ return 0;
+ }
+ if (opt_len == 10 || opt_len == 22)
+ printf(":%" PRIu16, ntohs(add_addr->ipver == 4 ?
+ add_addr->u.v4.port :
+ add_addr->u.v6.port));
+ return 1;
+}
+
+static int remove_addr_print(const u_char *opt, u_int opt_len)
+{
+ struct mp_remove_addr *rem_addr = (struct mp_remove_addr *) opt;
+ u_int8_t *addr_id = &rem_addr->addrs_id;
+
+ opt_len -= 3;
+ printf(" id");
+ while (opt_len--)
+ printf(" %" PRIu8, *addr_id++);
+ return 1;
+}
+
+static int mp_prio_print(const u_char *opt, u_int opt_len)
+{
+ struct mp_prio *mpp = (struct mp_prio *) opt;
+
+ if (mpp->b)
+ printf(" backup");
+ else
+ printf(" non-backup");
+ if (opt_len == 4)
+ printf(" id %" PRIu8, mpp->addr_id);
+
+ return 1;
+}
+
+static int mp_fail_print(const u_char *opt, u_int opt_len)
+{
+ opt += 4;
+ printf(" seq %" PRIu64, EXTRACT_64BITS(opt));
+}
+
+static int mp_fast_close_print(const u_char *opt, u_int opt_len)
+{
+ opt += 4;
+ printf(" key 0x%" PRIx64, *((uint64_t *)opt));
+}
+
+static struct {
+ const char *name;
+ int (*print)(const u_char *, u_int);
+} mptcp_options[] = {
+ { "capable", mp_capable_print },
+ { "join", mp_join_print },
+ { "dss", mp_dss_print },
+ { "add-addr", add_addr_print },
+ { "rem-addr", remove_addr_print },
+ { "prio", mp_prio_print },
+ { "fail", mp_fail_print },
+ { "fast-close", mp_fast_close_print },
+ { "unknown", dummy_print },
+};
+
+int mptcp_print(const u_char *cp, u_int len)
+{
+ struct mptcp_option *opt = (struct mptcp_option *) cp;
+ u_int subtype = min(opt->sub, MPTCP_SUB_FCLOSE + 1);
+
+ printf(" %s", mptcp_options[subtype].name);
+ return mptcp_options[subtype].print(cp, len);
+}