]>
The Tcpdump Group git mirrors - tcpdump/blob - print-dccp.c
2 * Copyright (C) Arnaldo Carvalho de Melo 2004
3 * Copyright (C) Ian McDonald 2005
4 * Copyright (C) Yoshifumi Nishida 2005
6 * This software may be distributed either under the terms of the
7 * BSD-style license that accompanies tcpdump or the GNU GPL version 2
11 static const char rcsid
[] _U_
=
12 "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.1.2.2 2005-09-20 06:25:45 guy Exp $ (LBL)";
19 #include <tcpdump-stdinc.h>
26 #include "interface.h"
27 #include "addrtoname.h"
28 #include "extract.h" /* must come after interface.h */
35 static const char *dccp_reset_codes
[] = {
50 static const char *dccp_feature_nums
[] = {
59 "minimum checksum coverage",
60 "check data checksum",
63 static int dccp_cksum(const struct ip
*ip
,
64 const struct dccp_hdr
*dh
, u_int len
)
80 phu
.ph
.len
= htons(len
);
81 phu
.ph
.proto
= IPPROTO_DCCP
;
82 memcpy(&phu
.ph
.src
, &ip
->ip_src
.s_addr
, sizeof(u_int32_t
));
84 memcpy(&phu
.ph
.dst
, &ip
->ip_dst
.s_addr
, sizeof(u_int32_t
));
86 phu
.ph
.dst
= ip_finddst(ip
);
89 return in_cksum((u_short
*)dh
, len
, sp
[0]+sp
[1]+sp
[2]+sp
[3]+sp
[4]+sp
[5]);
93 static int dccp6_cksum(const struct ip6_hdr
*ip6
, const struct dccp_hdr
*dh
, u_int len
)
100 struct in6_addr ph_src
;
101 struct in6_addr ph_dst
;
110 memset(&phu
, 0, sizeof(phu
));
111 phu
.ph
.ph_src
= ip6
->ip6_src
;
112 phu
.ph
.ph_dst
= ip6
->ip6_dst
;
113 phu
.ph
.ph_len
= htonl(len
);
114 phu
.ph
.ph_nxt
= IPPROTO_DCCP
;
117 for (i
= 0; i
< sizeof(phu
.pa
) / sizeof(phu
.pa
[0]); i
++)
120 sp
= (const u_int16_t
*)dh
;
122 for (i
= 0; i
< (len
& ~1); i
+= 2)
126 sum
+= htons((*(const u_int8_t
*)sp
) << 8);
129 sum
= (sum
& 0xffff) + (sum
>> 16);
136 static const char *dccp_reset_code(u_int8_t code
)
138 if (code
>= __DCCP_RESET_CODE_LAST
)
140 return dccp_reset_codes
[code
];
143 static u_int64_t
dccp_seqno(const struct dccp_hdr
*dh
)
145 u_int32_t seq_high
= DCCPH_SEQ(dh
);
146 u_int64_t seqno
= EXTRACT_24BITS(&seq_high
) & 0xFFFFFF;
148 if (DCCPH_X(dh
) != 0) {
149 const struct dccp_hdr_ext
*dhx
= (void *)dh
+ sizeof(*dh
);
150 u_int32_t seq_low
= dhx
->dccph_seq_low
;
151 seqno
&= 0x00FFFF; /* clear reserved field */
152 seqno
= (seqno
<< 32) + EXTRACT_32BITS(&seq_low
);
158 static u_int64_t
dccp_ack_no(const struct dccp_hdr
*dh
,
159 const struct dccp_hdr_ack_bits
*dh_ack
)
161 u_int32_t ack_high
= DCCPH_ACK(dh_ack
);
162 u_int64_t ackno
= EXTRACT_24BITS(&ack_high
) & 0xFFFFFF;
164 if (DCCPH_X(dh
) != 0) {
165 u_int32_t ack_low
= dh_ack
->dccph_ack_nr_low
;
167 ackno
&= 0x00FFFF; /* clear reserved field */
168 ackno
= (ackno
<< 32) + EXTRACT_32BITS(&ack_low
);
174 static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr
*dh
)
176 return sizeof(*dh
) + (DCCPH_X(dh
) ? sizeof(struct dccp_hdr_ext
) : 0);
179 static inline unsigned int dccp_packet_hdr_len(const u_int8_t type
)
181 if (type
== DCCP_PKT_DATA
)
183 if (type
== DCCP_PKT_DATAACK
||
184 type
== DCCP_PKT_ACK
||
185 type
== DCCP_PKT_SYNC
||
186 type
== DCCP_PKT_SYNCACK
||
187 type
== DCCP_PKT_CLOSE
||
188 type
== DCCP_PKT_CLOSEREQ
)
189 return sizeof(struct dccp_hdr_ack_bits
);
190 if (type
== DCCP_PKT_REQUEST
)
191 return sizeof(struct dccp_hdr_request
);
192 if (type
== DCCP_PKT_RESPONSE
)
193 return sizeof(struct dccp_hdr_response
);
194 return sizeof(struct dccp_hdr_reset
);
197 static int dccp_print_option(const u_char
*option
);
200 * dccp_print - show dccp packet
201 * @bp - beginning of dccp packet
202 * @data2 - beginning of enclosing
203 * @len - lenght of ip packet
205 void dccp_print(const u_char
*bp
, const u_char
*data2
, u_int len
)
207 const struct dccp_hdr
*dh
;
210 const struct ip6_hdr
*ip6
;
213 u_short sport
, dport
;
217 dh
= (const struct dccp_hdr
*)bp
;
219 ip
= (struct ip
*)data2
;
222 ip6
= (const struct ip6_hdr
*)data2
;
226 cp
= (const u_char
*)(dh
+ 1);
228 printf("[Invalid packet|dccp]");
232 if (len
< sizeof(struct dccp_hdr
)) {
233 printf("truncated-dccp - %ld bytes missing!",
234 (long)len
- sizeof(struct dccp_hdr
));
238 sport
= EXTRACT_16BITS(&dh
->dccph_sport
);
239 dport
= EXTRACT_16BITS(&dh
->dccph_dport
);
240 hlen
= dh
->dccph_doff
* 4;
244 (void)printf("%s.%d > %s.%d: ",
245 ip6addr_string(&ip6
->ip6_src
), sport
,
246 ip6addr_string(&ip6
->ip6_dst
), dport
);
250 (void)printf("%s.%d > %s.%d: ",
251 ipaddr_string(&ip
->ip_src
), sport
,
252 ipaddr_string(&ip
->ip_dst
), dport
);
257 (void)printf(" %d", len
- hlen
);
259 (void)printf("dccp [bad hdr length %u - too long, > %u]",
265 /* other variables in generic header */
267 (void)printf("CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh
), DCCPH_CSCOV(dh
));
270 /* checksum calculation */
273 if (ip6
->ip6_plen
&& vflag
) {
274 u_int16_t sum
, dccp_sum
;
276 sum
= dccp6_cksum(ip6
, dh
, len
);
277 dccp_sum
= EXTRACT_16BITS(&dh
->dccph_checksum
);
278 printf("cksum 0x%04x", dccp_sum
);
280 (void)printf(" (incorrect (-> 0x%04x), ",in_cksum_shouldbe(dccp_sum
, sum
));
282 (void)printf(" (correct), ");
288 u_int16_t sum
, dccp_sum
;
290 sum
= dccp_cksum(ip
, dh
, len
);
291 dccp_sum
= EXTRACT_16BITS(&dh
->dccph_checksum
);
292 printf("cksum 0x%04x", dccp_sum
);
294 (void)printf(" (incorrect (-> 0x%04x), ",in_cksum_shouldbe(dccp_sum
, sum
));
296 (void)printf(" (correct), ");
299 switch (DCCPH_TYPE(dh
)) {
300 case DCCP_PKT_REQUEST
: {
301 struct dccp_hdr_request
*dhr
=
302 (struct dccp_hdr_request
*)(bp
+ dccp_basic_hdr_len(dh
));
304 (void)printf("request (service=%d) ", dhr
->dccph_req_service
);
308 case DCCP_PKT_RESPONSE
: {
309 struct dccp_hdr_response
*dhr
=
310 (struct dccp_hdr_response
*)(bp
+ dccp_basic_hdr_len(dh
));
312 (void)printf("response (service=%d, ack=%" PRIu64
") ",
313 dhr
->dccph_resp_service
,
314 dccp_ack_no(dh
,&(dhr
->dccph_resp_ack
)));
319 (void)printf("data ");
322 struct dccp_hdr_ack_bits
*dha
=
323 (struct dccp_hdr_ack_bits
*)(bp
+ dccp_basic_hdr_len(dh
));
325 (void)printf("ack (ack=%" PRIu64
") ",
326 dccp_ack_no(dh
,dha
));
330 case DCCP_PKT_DATAACK
: {
331 struct dccp_hdr_ack_bits
*dha
=
332 (struct dccp_hdr_ack_bits
*)(bp
+ dccp_basic_hdr_len(dh
));
334 (void)printf("dataack (ack=%" PRIu64
") ",
335 dccp_ack_no(dh
,dha
));
339 case DCCP_PKT_CLOSEREQ
:
340 (void)printf("closereq ");
344 (void)printf("close ");
347 case DCCP_PKT_RESET
: {
348 struct dccp_hdr_reset
*dhr
=
349 (struct dccp_hdr_reset
*)(bp
+ dccp_basic_hdr_len(dh
));
351 (void)printf("reset (code=%s) ",
352 dccp_reset_code(dhr
->dccph_reset_code
));
357 (void)printf("sync ");
360 case DCCP_PKT_SYNCACK
:
361 (void)printf("syncack ");
365 (void)printf("invalid ");
372 (void)printf("seq %" PRIu64
, dccp_seqno(dh
));
374 /* process options */
375 if (hlen
> dccp_basic_hdr_len(dh
) + extlen
){
378 cp
= bp
+ dccp_basic_hdr_len(dh
) + extlen
;
381 hlen
-= dccp_basic_hdr_len(dh
) + extlen
;
384 optlen
= dccp_print_option(cp
);
385 if (!optlen
) goto trunc2
;
386 if (hlen
<= optlen
) break;
400 static int dccp_print_option(const u_char
*option
)
411 optlen
= *(option
+1);
413 printf("Option %d optlen too short",*option
);
418 TCHECK2(*option
,optlen
);
428 printf("slowreceiver");
432 if (*(option
+2) < 10){
433 printf(" %s", dccp_feature_nums
[*(option
+2)]);
434 for (i
= 0; i
< optlen
-3; i
++) printf(" %d", *(option
+3 + i
));
439 if (*(option
+2) < 10){
440 printf(" %s", dccp_feature_nums
[*(option
+2)]);
441 for (i
= 0; i
< optlen
-3; i
++) printf(" %d", *(option
+3 + i
));
446 if (*(option
+2) < 10){
447 printf(" %s", dccp_feature_nums
[*(option
+2)]);
448 for (i
= 0; i
< optlen
-3; i
++) printf(" %d", *(option
+3 + i
));
453 if (*(option
+2) < 10){
454 printf(" %s", dccp_feature_nums
[*(option
+2)]);
455 for (i
= 0; i
< optlen
-3; i
++) printf(" %d", *(option
+3 + i
));
459 printf("initcookie 0x");
460 for (i
= 0; i
< optlen
-2; i
++) printf("%02x", *(option
+2 + i
));
464 for (i
= 0; i
< optlen
-2; i
++) printf(" %d", *(option
+2 + i
));
467 printf("ack_vector0 0x");
468 for (i
= 0; i
< optlen
-2; i
++) printf("%02x", *(option
+2 + i
));
471 printf("ack_vector1 0x");
472 for (i
= 0; i
< optlen
-2; i
++) printf("%02x", *(option
+2 + i
));
475 printf("data_dropped 0x");
476 for (i
= 0; i
< optlen
-2; i
++) printf("%02x", *(option
+2 + i
));
479 ts
= (u_int32_t
*)(option
+ 2);
480 printf("timestamp %u", (u_int32_t
)ntohl(*ts
));
483 ts
= (u_int32_t
*)(option
+ 2);
484 printf("timestamp_echo %u", (u_int32_t
)ntohl(*ts
));
487 printf("elapsed_time ");
489 ts
= (u_int32_t
*)(option
+ 2);
490 printf("%u", (u_int32_t
)ntohl(*ts
));
492 var16
= (u_int16_t
*)(option
+ 2);
493 printf("%u", ntohs(*var16
));
497 printf("data_checksum ");
498 for (i
= 0; i
< optlen
-2; i
++) printf("%02x", *(option
+2 + i
));
501 if (*option
>= 128) {
502 printf("CCID option %d",*option
);
505 var16
= (u_int16_t
*)(option
+ 2);
506 printf(" %u",ntohs(*var16
));
509 var32
= (u_int32_t
*)(option
+ 2);
510 printf(" %u",(u_int32_t
)ntohl(*var32
));
518 printf("unknown_opt %d", *option
);