summaryrefslogtreecommitdiff
path: root/proto_dccp.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto_dccp.c')
-rw-r--r--proto_dccp.c154
1 files changed, 154 insertions, 0 deletions
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,
+};