From: Michael Richardson Date: Fri, 3 Jan 2014 02:33:26 +0000 (-0500) Subject: updated RPL printer from draft-07 to rfc6550 for DIO message. X-Git-Tag: tcpdump-4.6.0~311 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/82ede46025bf29a26eda1848c7d588ccff423046 updated RPL printer from draft-07 to rfc6550 for DIO message. Decode the DIO suboptions as well, added new test case --- diff --git a/print-icmp6.c b/print-icmp6.c index 9369297e..bfde664a 100644 --- a/print-icmp6.c +++ b/print-icmp6.c @@ -655,25 +655,89 @@ enum ND_RPL_DIO_FLAGS { ND_RPL_DIO_PRF_MASK = 0x07, /* 3-bit preference */ }; +enum ND_RPL_SUBOPT { + RPL_OPT_PAD0 = 0, + RPL_OPT_PADN = 1, + RPL_DIO_METRICS = 2, + RPL_DIO_ROUTINGINFO = 3, + RPL_DIO_CONFIG = 4, + RPL_DAO_RPLTARGET = 5, + RPL_DAO_TRANSITINFO = 6, + RPL_DIO_DESTPREFIX = 8, + RPL_DAO_RPLTARGET_DESC=9, +}; + +#define RPL_DIO_GROUND_FLAG 0x80 +#define RPL_DIO_MOP_SHIFT 3 +#define RPL_DIO_MOP_MASK (7 << RPL_DIO_MOP_SHIFT) +#define RPL_DIO_PRF_SHIFT 0 +#define RPL_DIO_PRF_MASK (7 << RPL_DIO_MOP_SHIFT) +#define RPL_DIO_GROUNDED(X) ((X)&RPL_DIO_GROUND_FLAG) +#define RPL_DIO_MOP(X) (((X)&RPL_DIO_MOP_MASK) >> RPL_DIO_MOP_SHIFT) +#define RPL_DIO_PRF(X) (((X)&RPL_DIO_PRF_MASK) >> RPL_DIO_PRF_SHIFT) + + struct nd_rpl_dio { - u_int8_t rpl_flags; - u_int8_t rpl_seq; - u_int8_t rpl_instanceid; - u_int8_t rpl_dagrank; - u_int8_t rpl_dagid[16]; + u_int8_t rpl_instanceid; + u_int8_t rpl_version; + u_int16_t rpl_dagrank; + u_int8_t rpl_mopprf; /* bit 7=G, 5-3=MOP, 2-0=PRF */ + u_int8_t rpl_dtsn; + u_int8_t rpl_flags; /* Dest. Advertisement Trigger Seq Number */ + u_int8_t rpl_resv1; + u_int8_t rpl_dagid[16]; +}; +struct nd_rpl_option { + u_int8_t rpl_dio_type; + u_int8_t rpl_dio_len; /* suboption length, not including type/len */ + u_int8_t rpl_dio_data[0]; +}; + +static char *rpl_mop_name[]={ + "nonstoring", + "storing", + "nonstoring-multicast", + "storing-multicast", + "mop-reserved-4", + "mop-reserved-5", + "mop-reserved-6", + "mop-reserved-7" }; +static char *rpl_subopt_name(int opt, char *buf, int len) { + switch(opt) { + case RPL_OPT_PAD0: + return "pad0"; + case RPL_OPT_PADN: + return "padN"; + case RPL_DIO_METRICS: + return "metrics"; + case RPL_DIO_ROUTINGINFO: + return "routinginfo"; + case RPL_DIO_CONFIG: + return "routinginfo"; + case RPL_DAO_RPLTARGET: + return "rpltarget"; + case RPL_DAO_TRANSITINFO: + return "transitinfo"; + case RPL_DIO_DESTPREFIX: + return "destprefix"; + case RPL_DAO_RPLTARGET_DESC: + return "rpltargetdesc"; + default: + snprintf(buf, len, "unknown:%u", opt); + return buf; + } +} + static void rpl_print(netdissect_options *ndo, const struct icmp6_hdr *hdr, const u_char *bp, u_int length _U_) { - struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp; int secured = hdr->icmp6_code & 0x80; int basecode= hdr->icmp6_code & 0x7f; - ND_TCHECK(dio->rpl_dagid); - if(secured) { ND_PRINT((ndo, ", (SEC)")); } else { @@ -689,9 +753,12 @@ rpl_print(netdissect_options *ndo, case ND_RPL_DIO: ND_PRINT((ndo, "DODAG Information Object")); if(ndo->ndo_vflag) { + struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp; char dagid[65]; char *d = dagid; int i; + ND_TCHECK(dio->rpl_dagid); + for(i=0;i<16;i++) { if(isprint(dio->rpl_dagid[i])) { *d++ = dio->rpl_dagid[i]; @@ -702,11 +769,30 @@ rpl_print(netdissect_options *ndo, } } *d++ = '\0'; - ND_PRINT((ndo, " [seq:%u,instance:%u,rank:%u,dagid:%s]", - dio->rpl_seq, + ND_PRINT((ndo, " [dagid:%s,seq:%u,instance:%u,rank:%u,%smop:%s,prf:%u]", + dagid, + dio->rpl_dtsn, dio->rpl_instanceid, dio->rpl_dagrank, - dagid)); + RPL_DIO_GROUNDED(dio->rpl_mopprf) ? "grounded,":"", + rpl_mop_name[RPL_DIO_MOP(dio->rpl_mopprf)], + RPL_DIO_PRF(dio->rpl_mopprf))); + + if(ndo->ndo_vflag > 1) { + struct nd_rpl_option *opt = (struct nd_rpl_option *)&dio[1]; + char optname_buf[64]; + ND_TCHECK(opt->rpl_dio_len); + while(opt->rpl_dio_type == RPL_OPT_PAD0 || ND_TTEST2(opt,(opt->rpl_dio_len+2))) { + unsigned int len = opt->rpl_dio_len+2; + if(opt->rpl_dio_type == RPL_OPT_PAD0) { + len = 1; + } + ND_PRINT((ndo, " opt:%s len:%u ", + rpl_subopt_name(opt->rpl_dio_type, optname_buf, sizeof(optname_buf)), + len)); + opt = (struct nd_rpl_option *)((char *)opt) + len; + } + } } break; case ND_RPL_DAO: diff --git a/tests/19-pickdag.out b/tests/19-pickdag.out new file mode 100644 index 00000000..d93d44c8 --- /dev/null +++ b/tests/19-pickdag.out @@ -0,0 +1,2 @@ +IP6 (hlim 64, next-header ICMPv6 (58) payload length: 48) fe80::216:3eff:fe11:3424 > ff02::1: [icmp6 sum ok] ICMP6, RPL, (CLR)DODAG Information Object [dagid:T10x0,seq:10,instance:42,rank:768,grounded,mop:nonstoring,prf:0] +IP6 (hlim 64, next-header ICMPv6 (58) payload length: 56) fe80::216:3eff:fe11:3424 > fe80::216:3eff:fe11:3424: [icmp6 sum ok] ICMP6, RPL, (CLR)Destination Advertisement Object diff --git a/tests/19-pickdag.pcap b/tests/19-pickdag.pcap new file mode 100644 index 00000000..db33d492 Binary files /dev/null and b/tests/19-pickdag.pcap differ diff --git a/tests/TESTLIST b/tests/TESTLIST index 47f4b14d..bd16d5a1 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -17,15 +17,15 @@ print-A print-flags.pcap print-A.out -t -A print-AA print-flags.pcap print-AA.out -t -AA # BGP tests -bgp_vpn_attrset bgp_vpn_attrset.pcap bgp_vpn_attrset.out -t -v +bgp_vpn_attrset bgp_vpn_attrset.pcap bgp_vpn_attrset.out -t -v mpbgp-linklocal-nexthop mpbgp-linklocal-nexthop.pcap mpbgp-linklocal-nexthop.out -t -v # EAP tests -eapon1 eapon1.pcap eapon1.out -t +eapon1 eapon1.pcap eapon1.out -t # ESP tests esp0 02-sunrise-sunset-esp.pcap esp0.out -t -n -esp1 02-sunrise-sunset-esp.pcap esp1.out -t -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x4043434545464649494a4a4c4c4f4f515152525454575758" +esp1 02-sunrise-sunset-esp.pcap esp1.out -t -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x4043434545464649494a4a4c4c4f4f515152525454575758" esp2 08-sunrise-sunset-esp2.pcap esp2.out -t -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x43434545464649494a4a4c4c4f4f51515252545457575840,0xabcdabcd@192.0.1.1 3des-cbc-hmac96:0x434545464649494a4a4c4c4f4f5151525254545757584043" esp3 02-sunrise-sunset-esp.pcap esp1.out -t -E "3des-cbc-hmac96:0x4043434545464649494a4a4c4c4f4f515152525454575758" esp4 08-sunrise-sunset-esp2.pcap esp2.out -t -E "file esp-secrets.txt" @@ -33,7 +33,7 @@ esp5 08-sunrise-sunset-aes.pcap esp5.out -t -E "file esp-secrets.txt" espudp1 espudp1.pcap espudp1.out -nnnn -t -E "file esp-secrets.txt" # ISAKMP tests -isakmp1 isakmp-delete-segfault.pcap isakmp1.out -t +isakmp1 isakmp-delete-segfault.pcap isakmp1.out -t isakmp2 isakmp-pointer-loop.pcap isakmp2.out -t isakmp3 isakmp-identification-segfault.pcap isakmp3.out -t -v isakmp4 isakmp4500.pcap isakmp4.out -t -E "file esp-secrets.txt" @@ -50,26 +50,27 @@ ospf-gmpls ospf-gmpls.pcap ospf-gmpls.out -t -v # IKEv2 tests ikev2four ikev2four.pcap ikev2four.out -t -v -ikev2fourv ikev2four.pcap ikev2fourv.out -t -v -v -v +ikev2fourv ikev2four.pcap ikev2fourv.out -t -v -v -v ikev2fourv4 ikev2four.pcap ikev2fourv4.out -t -v -v -v -v ikev2pI2 ikev2pI2.pcap ikev2pI2.out -t -E "file ikev2pI2-secrets.txt" -v -v -v -v # IETF ROLL RPL packets dio01 dio.pcap dio.out -t -v +dio02 19-pickdag.pcap 19-pickdag.out -t -v -v # IPNET encapsulated site e1000g e1000g.pcap e1000g.out -t # IETF FORCES WG packets and printer forces01 forces1.pcap forces1.out -t -forces01vvv forces1.pcap forces1vvv.out -t -v -v -v +forces01vvv forces1.pcap forces1vvv.out -t -v -v -v forces01vvvv forces1.pcap forces1vvvv.out -t -v -v -v -v # need new pcap file, not sure what the differences were? #forces02 forces2.pcap forces2.out -t #forces02v forces2.pcap forces2v.out -t -v #forces02vv forces2.pcap forces2vv.out -t -v -v -# 802.1ad, QinQ tests +# 802.1ad, QinQ tests qinq QinQpacket.pcap QinQpacket.out -t -e qinqv QinQpacket.pcap QinQpacketv.out -t -e -v @@ -79,7 +80,7 @@ sflow2 sflow_multiple_counter_30_pdus.pcap sflow_multiple_counter_3 # AHCP and Babel tests ahcp-vv ahcp.pcap ahcp-vv.out -t -vv -babel1 babel.pcap babel1.out -t +babel1 babel.pcap babel1.out -t babel1v babel.pcap babel1v.out -t -v babel_auth babel_auth.pcap babel_auth.out -t -v babel_pad1 babel_pad1.pcap babel_pad1.out -t