ring_tx: handle EINTR from sendto
[netsniff-ng-new.git] / proto_dccp.c
blob256ad16e824e0ff92776c23ce578077a8dc7fbb0
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2018 Markus Amend
5 * Subject to the GPL, version 2.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <netinet/in.h> /* for ntohs() */
12 #include "proto.h"
13 #include "protos.h"
14 #include "pkt_buff.h"
16 struct dccphdr {
17 uint16_t source;
18 uint16_t dest;
19 uint8_t data_offs;
20 uint8_t cc_cscov;
21 uint16_t checks;
22 #if defined(__LITTLE_ENDIAN_BITFIELD)
23 __extension__ uint32_t x:1,
24 type:4,
25 res:3,
26 sqnr:24;
27 #elif defined (__BIG_ENDIAN_BITFIELD)
28 __extension__ uint32_t res:3,
29 type:4,
30 x:1,
31 sqnr:24;
32 #else
33 # error "Please fix <asm/byteorder.h>"
34 #endif
36 } __packed;
38 struct dccpexthdr {
39 uint32_t seqnr_low;
40 } __packed;
42 struct ack_subhdr {
43 uint32_t res:8,
44 acknr_low: 24;
45 } __packed;
47 struct ack_extsubhdr {
48 uint16_t res;
49 uint16_t acknr_high;
50 uint32_t acknr_low;
51 } __packed;
53 static char* dccp_pkt_type(uint8_t type) {
54 switch(type) {
55 case 0: return "Request";
56 case 1: return "Response";
57 case 2: return "Data";
58 case 3: return "Ack";
59 case 4: return "DataAck";
60 case 5: return "CloseReq";
61 case 6: return "Close";
62 case 7: return "Reset";
63 case 8: return "Sync";
64 case 9: return "SyncAck";
65 case 10 ... 15: return "Reserved";
67 return "Undef";
70 static void dccp(struct pkt_buff *pkt)
72 struct dccphdr *dccp = (struct dccphdr *) pkt_pull(pkt, sizeof(*dccp));
73 struct dccpexthdr *dccpext = NULL;
74 struct ack_subhdr *ack = NULL;
75 struct ack_extsubhdr *ackext = NULL;
76 uint16_t src, dest;
77 uint64_t seqnr;
78 int64_t acknr = -1;
79 size_t used_hdr = 0;
81 if (dccp == NULL)
82 return;
84 used_hdr += sizeof(*dccp);
86 seqnr = (uint64_t) ntohl(dccp->sqnr);
88 /* check for extended sequence number */
89 if (dccp->x) {
90 dccpext = (struct dccpexthdr *) pkt_pull(pkt, sizeof(*dccpext));
91 if (dccpext == NULL)
92 return;
94 used_hdr += sizeof(*dccpext);
95 seqnr = (((uint64_t) seqnr)<<24) | ntohl(dccpext->seqnr_low);
98 /* check for ack header */
99 if (dccp->type == 1 || (dccp->type >= 2 && dccp->type <= 9)) {
100 if (dccp->x) {
101 /* Extended ack header */
102 ackext = (struct ack_extsubhdr *) pkt_pull(pkt, sizeof(*ackext));
103 if (ackext == NULL)
104 return;
106 used_hdr += sizeof(*ackext);
107 acknr = (((uint64_t) ntohs(ackext->acknr_high))<<32) |
108 ntohl(ackext->acknr_low);
109 } else {
110 /* standard ack header */
111 ack = (struct ack_subhdr *) pkt_pull(pkt, sizeof(*ack));
112 if (ack == NULL)
113 return;
115 used_hdr += sizeof(*ack);
116 acknr = ntohl((uint32_t) ack->acknr_low);
120 src = ntohs(dccp->source);
121 dest = ntohs(dccp->dest);
123 tprintf(" [ DCCP ");
124 tprintf("Port (%u", src);
125 tprintf(" => %u", dest);
126 tprintf("), ");
127 tprintf("Header Len (%u Bytes), ", dccp->data_offs * 4);
128 tprintf("Type: %s, ", dccp_pkt_type((uint8_t) dccp->type));
129 tprintf("Seqnr:%lu", seqnr);
130 if (acknr > 0)
131 tprintf(", AckNr:%lu", acknr);
132 tprintf(" ]\n");
135 static void dccp_less(struct pkt_buff *pkt)
137 struct dccphdr *dccp = (struct dccphdr *) pkt_pull(pkt, sizeof(*dccp));
138 uint16_t src, dest;
140 if (dccp == NULL)
141 return;
143 src = ntohs(dccp->source);
144 dest = ntohs(dccp->dest);
146 tprintf(" DCCP %u", src);
147 tprintf("/%u", dest);
150 struct protocol dccp_ops = {
151 .key = 0x21,
152 .print_full = dccp,
153 .print_less = dccp_less,