From 92609553c7c6da3214482b1f39bef7cce41a6fdf Mon Sep 17 00:00:00 2001 From: Markus Amend Date: Fri, 12 Jan 2018 08:27:12 +0100 Subject: netsniff-ng: add DCCP support Adds a first rudimentary support for the DCCP protocol. Signed-off-by: Markus Amend [tk: minor formatting tweaks] Signed-off-by: Tobias Klauser --- dissector_eth.c | 1 + netsniff-ng/Makefile | 1 + proto_dccp.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ protos.h | 1 + 4 files changed, 157 insertions(+) create mode 100644 proto_dccp.c 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(ð_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 +#include +#include /* 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 " +#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; -- cgit v1.2.3-54-g00ecf