1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 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,
};
|