summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Amend <markus.amend@telekom.de>2018-01-12 08:27:12 +0100
committerTobias Klauser <tklauser@distanz.ch>2018-01-12 10:37:55 +0100
commit92609553c7c6da3214482b1f39bef7cce41a6fdf (patch)
treec8eb1ad53564a149f04003f7bae49854bfaa81ed
parent5bef83d56ab496a7d1f039e0ffc9c52828164d56 (diff)
netsniff-ng: add DCCP support
Adds a first rudimentary support for the DCCP protocol. Signed-off-by: Markus Amend <markus.amend@telekom.de> [tk: minor formatting tweaks] Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--dissector_eth.c1
-rw-r--r--netsniff-ng/Makefile1
-rw-r--r--proto_dccp.c154
-rw-r--r--protos.h1
4 files changed, 157 insertions, 0 deletions
diff --git a/dissector_eth.c b/dissector_eth.c
index 7041aac..3a93f40 100644
--- a/dissector_eth.c
+++ b/dissector_eth.c
@@ -57,6 +57,7 @@ static void dissector_init_layer_3(int type)
INSERT_HASH_PROTOS(ipv6_routing_ops, eth_lay3);
INSERT_HASH_PROTOS(tcp_ops, eth_lay3);
INSERT_HASH_PROTOS(udp_ops, eth_lay3);
+ INSERT_HASH_PROTOS(dccp_ops, eth_lay3);
for_each_hash_int(&eth_lay3, dissector_set_print_type, type);
}
diff --git a/netsniff-ng/Makefile b/netsniff-ng/Makefile
index d1d8a85..eeb8d0d 100644
--- a/netsniff-ng/Makefile
+++ b/netsniff-ng/Makefile
@@ -39,6 +39,7 @@ netsniff-ng-objs = dissector.o \
proto_none.o \
proto_tcp.o \
proto_udp.o \
+ proto_dccp.o \
proto_vlan.o \
proto_vlan_q_in_q.o \
proto_mpls_unicast.o \
diff --git a/proto_dccp.c b/proto_dccp.c
new file mode 100644
index 0000000..256ad16
--- /dev/null
+++ b/proto_dccp.c
@@ -0,0 +1,154 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2009, 2010 Daniel Borkmann.
+ * Copyright 2018 Markus Amend
+ * Subject to the GPL, version 2.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <netinet/in.h> /* for ntohs() */
+
+#include "proto.h"
+#include "protos.h"
+#include "pkt_buff.h"
+
+struct dccphdr {
+ uint16_t source;
+ uint16_t dest;
+ uint8_t data_offs;
+ uint8_t cc_cscov;
+ uint16_t checks;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __extension__ uint32_t x:1,
+ type:4,
+ res:3,
+ sqnr:24;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ __extension__ uint32_t res:3,
+ type:4,
+ x:1,
+ sqnr:24;
+#else
+# error "Please fix <asm/byteorder.h>"
+#endif
+
+} __packed;
+
+struct dccpexthdr {
+ uint32_t seqnr_low;
+} __packed;
+
+struct ack_subhdr {
+ uint32_t res:8,
+ acknr_low: 24;
+} __packed;
+
+struct ack_extsubhdr {
+ uint16_t res;
+ uint16_t acknr_high;
+ uint32_t acknr_low;
+} __packed;
+
+static char* dccp_pkt_type(uint8_t type) {
+ switch(type) {
+ case 0: return "Request";
+ case 1: return "Response";
+ case 2: return "Data";
+ case 3: return "Ack";
+ case 4: return "DataAck";
+ case 5: return "CloseReq";
+ case 6: return "Close";
+ case 7: return "Reset";
+ case 8: return "Sync";
+ case 9: return "SyncAck";
+ case 10 ... 15: return "Reserved";
+ }
+ return "Undef";
+}
+
+static void dccp(struct pkt_buff *pkt)
+{
+ struct dccphdr *dccp = (struct dccphdr *) pkt_pull(pkt, sizeof(*dccp));
+ struct dccpexthdr *dccpext = NULL;
+ struct ack_subhdr *ack = NULL;
+ struct ack_extsubhdr *ackext = NULL;
+ uint16_t src, dest;
+ uint64_t seqnr;
+ int64_t acknr = -1;
+ size_t used_hdr = 0;
+
+ if (dccp == NULL)
+ return;
+
+ used_hdr += sizeof(*dccp);
+
+ seqnr = (uint64_t) ntohl(dccp->sqnr);
+
+ /* check for extended sequence number */
+ if (dccp->x) {
+ dccpext = (struct dccpexthdr *) pkt_pull(pkt, sizeof(*dccpext));
+ if (dccpext == NULL)
+ return;
+
+ used_hdr += sizeof(*dccpext);
+ seqnr = (((uint64_t) seqnr)<<24) | ntohl(dccpext->seqnr_low);
+ }
+
+ /* check for ack header */
+ if (dccp->type == 1 || (dccp->type >= 2 && dccp->type <= 9)) {
+ if (dccp->x) {
+ /* Extended ack header */
+ ackext = (struct ack_extsubhdr *) pkt_pull(pkt, sizeof(*ackext));
+ if (ackext == NULL)
+ return;
+
+ used_hdr += sizeof(*ackext);
+ acknr = (((uint64_t) ntohs(ackext->acknr_high))<<32) |
+ ntohl(ackext->acknr_low);
+ } else {
+ /* standard ack header */
+ ack = (struct ack_subhdr *) pkt_pull(pkt, sizeof(*ack));
+ if (ack == NULL)
+ return;
+
+ used_hdr += sizeof(*ack);
+ acknr = ntohl((uint32_t) ack->acknr_low);
+ }
+ }
+
+ src = ntohs(dccp->source);
+ dest = ntohs(dccp->dest);
+
+ tprintf(" [ DCCP ");
+ tprintf("Port (%u", src);
+ tprintf(" => %u", dest);
+ tprintf("), ");
+ tprintf("Header Len (%u Bytes), ", dccp->data_offs * 4);
+ tprintf("Type: %s, ", dccp_pkt_type((uint8_t) dccp->type));
+ tprintf("Seqnr:%lu", seqnr);
+ if (acknr > 0)
+ tprintf(", AckNr:%lu", acknr);
+ tprintf(" ]\n");
+}
+
+static void dccp_less(struct pkt_buff *pkt)
+{
+ struct dccphdr *dccp = (struct dccphdr *) pkt_pull(pkt, sizeof(*dccp));
+ uint16_t src, dest;
+
+ if (dccp == NULL)
+ return;
+
+ src = ntohs(dccp->source);
+ dest = ntohs(dccp->dest);
+
+ tprintf(" DCCP %u", src);
+ tprintf("/%u", dest);
+}
+
+struct protocol dccp_ops = {
+ .key = 0x21,
+ .print_full = dccp,
+ .print_less = dccp_less,
+};
diff --git a/protos.h b/protos.h
index 201439a..39a8c4f 100644
--- a/protos.h
+++ b/protos.h
@@ -23,6 +23,7 @@ extern struct protocol lldp_ops;
extern struct protocol none_ops;
extern struct protocol tcp_ops;
extern struct protocol udp_ops;
+extern struct protocol dccp_ops;
extern struct protocol vlan_ops;
extern struct protocol ieee80211_ops;
extern struct protocol QinQ_ops;