From e52b10213e78c59a40b16e751353652e4cb437f6 Mon Sep 17 00:00:00 2001 From: Markus Amend Date: Wed, 25 Apr 2012 17:32:38 +0200 Subject: [PATCH] proto_icmpv6.h: intermediate state --- src/proto_icmpv6.h | 534 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 333 insertions(+), 201 deletions(-) diff --git a/src/proto_icmpv6.h b/src/proto_icmpv6.h index 04341664..aec05fce 100644 --- a/src/proto_icmpv6.h +++ b/src/proto_icmpv6.h @@ -6,6 +6,8 @@ * ICMPv6 described in RFC4443, RFC2710, RFC4861, RFC2894, * RFC4620, RFC3122, RFC3810, RFC3775, RFC3971, RFC4065 * RFC4286 + * Look also for an good overview: + * http://www.iana.org/assignments/icmpv6-parameters */ #ifndef PROTO_ICMPV6_H @@ -171,6 +173,25 @@ struct icmpv6_mldv2_addr_rec { } __packed; /* end MLDv2 report */ +/* ICMP Mobility Support */ +struct icmpv6_type_144_146 { + uint16_t id; + uint16_t res; +} __packed; + +struct icmpv6_type_145 { + uint16_t id; + uint16_t res; + struct in6_addr home_agent_addr[0]; +} __packed; + +struct icmpv6_type_147 { + uint16_t id; + uint16_t m_o_res; + uint8_t ops[0]; +} __packed; +/* end ICMP Mobility Support */ + static inline void print_ipv6_addr_list(struct pkt_buff *pkt, uint8_t nr_addr) { char address[INET6_ADDRSTRLEN]; @@ -187,177 +208,52 @@ static inline void print_ipv6_addr_list(struct pkt_buff *pkt, uint8_t nr_addr) } } -static char *icmpv6_type_1_codes[] = { - "No route to destination", - "Communication with destination administratively prohibited", - "Beyond scope of source address", - "Address unreachable", - "Port unreachable", - "Source address failed ingress/egress policy", - "Reject route to destination", - "Error in Source Routing Header", -}; - -static inline void dissect_icmpv6_type1(struct pkt_buff *pkt) -{ - struct icmpv6_type_1_3 *icmp_1; - - icmp_1 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_1)); - if (icmp_1 == NULL) - return; - - tprintf(", Unused (0x%x)",ntohl(icmp_1->unused)); - tprintf(" Payload include as much of invoking packet"); -} - -static inline void dissect_icmpv6_type2(struct pkt_buff *pkt) -{ - struct icmpv6_type_2 *icmp_2; - - icmp_2 = (struct icmpv6_type_2 *) pkt_pull(pkt,sizeof(*icmp_2)); - if (icmp_2 == NULL) - return; - - tprintf(", MTU (0x%x)",ntohl(icmp_2->MTU)); - tprintf(" Payload include as much of invoking packet"); -} - -static char *icmpv6_type_3_codes[] = { - "Hop limit exceeded in transit", - "Fragment reassembly time exceeded", -}; - -static inline void dissect_icmpv6_type3(struct pkt_buff *pkt) -{ - struct icmpv6_type_1_3 *icmp_3; - - icmp_3 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_3)); - if (icmp_3 == NULL) - return; - - tprintf(", Unused (0x%x)",ntohl(icmp_3->unused)); - tprintf(" Payload include as much of invoking packet"); -} - -static char *icmpv6_type_4_codes[] = { - "Erroneous header field encountered", - "Unrecognized Next Header type encountered", - "Unrecognized IPv6 option encountered", +static char *icmpv6_mcast_rec_types[] = { + "MODE_IS_INCLUDE", + "MODE_IS_EXCLUDE", + "CHANGE_TO_INCLUDE_MODE", + "CHANGE_TO_EXCLUDE_MODE", + "ALLOW_NEW_SOURCES", + "BLOCK_OLD_SOURCES", }; -static inline void dissect_icmpv6_type4(struct pkt_buff *pkt) -{ - struct icmpv6_type_4 *icmp_4; - - icmp_4 = (struct icmpv6_type_4 *) pkt_pull(pkt,sizeof(*icmp_4)); - if (icmp_4 == NULL) - return; - - tprintf(", Pointer (0x%x)",ntohl(icmp_4->pointer)); - tprintf(" Payload include as much of invoking packet"); -} - -static inline void dissect_icmpv6_type128(struct pkt_buff *pkt) -{ - struct icmpv6_type_128_129 *icmp_128; - - icmp_128 = (struct icmpv6_type_128_129 *) - pkt_pull(pkt,sizeof(*icmp_128)); - if (icmp_128 == NULL) - return; - - tprintf(", ID (0x%x)",ntohs(icmp_128->id)); - tprintf(", Seq. Nr. (%u)",ntohs(icmp_128->sn)); - tprintf(" Payload include Data"); -} - -static inline void dissect_icmpv6_type129(struct pkt_buff *pkt) -{ - struct icmpv6_type_128_129 *icmp_129; - - icmp_129 = (struct icmpv6_type_128_129 *) - pkt_pull(pkt,sizeof(*icmp_129)); - if (icmp_129 == NULL) - return; - - tprintf(", ID (0x%x)",ntohs(icmp_129->id)); - tprintf(", Seq. Nr. (%u)",ntohs(icmp_129->sn)); - tprintf(" Payload include Data"); -} - -static inline void dissect_icmpv6_type130(struct pkt_buff *pkt) +static inline void dissect_icmpv6_mcast_rec(struct pkt_buff *pkt, + uint16_t nr_rec) { - char address[INET6_ADDRSTRLEN]; - uint16_t nr_src, maxrespdel; - uint8_t switch_mldv2 = 0; - struct icmpv6_type_130_131_132 *icmp_130; - - icmp_130 = (struct icmpv6_type_130_131_132 *) - pkt_pull(pkt,sizeof(*icmp_130)); - if (icmp_130 == NULL) - return; - maxrespdel = ntohs(icmp_130->maxrespdel); - - if(pkt_len(pkt) >= sizeof(struct icmpv6_type_130_mldv2)) - switch_mldv2 = 1; - - if(switch_mldv2) - tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel >> 15 ? - (((maxrespdel & 0xFFF) | 0x1000) << - (((maxrespdel >> 12) & 0x3) + 3)) : maxrespdel); - else - tprintf(", Max Resp Delay (%ums)",maxrespdel); - tprintf(", Res (0x%x)",ntohs(icmp_130->res)); - tprintf(", Address: %s", - inet_ntop(AF_INET6, &icmp_130->ipv6_addr, - address, sizeof(address))); + size_t aux_data_len_bytes; + uint16_t nr_src; + struct icmpv6_mldv2_addr_rec *addr_rec; - if(switch_mldv2) { - struct icmpv6_type_130_mldv2 *icmp_130_mldv2; - - icmp_130_mldv2 = (struct icmpv6_type_130_mldv2 *) - pkt_pull(pkt,sizeof(*icmp_130_mldv2)); - if (icmp_130_mldv2 == NULL) + while (nr_rec--) { + addr_rec = (struct icmpv6_mldv2_addr_rec *) + pkt_pull(pkt,sizeof(*addr_rec)); + if (addr_rec == NULL) return; - - nr_src = ntohs(icmp_130_mldv2->nr_src); + aux_data_len_bytes = addr_rec->aux_data_len * 4; + nr_src = ntohs(addr_rec->nr_src); - tprintf(", Resv (0x%x)",icmp_130_mldv2->resv_S_QRV >> 4); - tprintf(", S (%u)",(icmp_130_mldv2->resv_S_QRV >> 3) & 0x1); - tprintf(", QRV (0x%x)",icmp_130_mldv2->resv_S_QRV & 0x3); - tprintf(", QQIC (%u)",icmp_130_mldv2->QQIC); - tprintf(", Nr Src (0x%x)",nr_src); + tprintf(", Rec Type %s (%u)", + icmpv6_code_range_valid(addr_rec->rec_type - 1, + icmpv6_mcast_rec_types) ? + icmpv6_mcast_rec_types[addr_rec->rec_type - 1] + : "Unknown", addr_rec->rec_type); + tprintf(", Aux Data Len (%u, %u bytes)",addr_rec->aux_data_len, + aux_data_len_bytes); + tprintf(", Nr. of Sources (%u)",nr_src); print_ipv6_addr_list(pkt, nr_src); - } -} - -static inline void dissect_icmpv6_type131(struct pkt_buff *pkt) -{ - char address[INET6_ADDRSTRLEN]; - struct icmpv6_type_130_131_132 *icmp_131; - - icmp_131 = (struct icmpv6_type_130_131_132 *) - pkt_pull(pkt,sizeof(*icmp_131)); - if (icmp_131 == NULL) - return; - - tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131->maxrespdel)); - tprintf(", Res (0x%x)",ntohs(icmp_131->res)); - tprintf(", Address: %s", - inet_ntop(AF_INET6, &icmp_131->ipv6_addr, - address, sizeof(address))); -} -static inline void dissect_icmpv6_type132(struct pkt_buff *pkt) -{ - dissect_icmpv6_type131(pkt); + tprintf(", Aux Data: "); + while (aux_data_len_bytes--) { + tprintf("%x", *pkt_pull(pkt,1)); + } + } } static inline void dissect_neighb_disc_ops_1(struct pkt_buff *pkt, size_t len) { struct icmpv6_neighb_disc_ops_type_1_2 *icmp_neighb_disc_1; - + icmp_neighb_disc_1 = (struct icmpv6_neighb_disc_ops_type_1_2 *) pkt_pull(pkt,sizeof(*icmp_neighb_disc_1)); if (icmp_neighb_disc_1 == NULL) @@ -463,10 +359,67 @@ static inline char *icmpv6_neighb_disc_ops(uint8_t code) { return "Redirected Header"; case 5: return "MTU"; + case 6: + return "NBMA Shortcut Limit Option"; + case 7: + return "Advertisement Interval Option"; + case 8: + return "Home Agent Information Option"; case 9: return "Source Address List"; case 10: return "Target Address List"; + case 11: + return "CGA option"; + case 12: + return "RSA Signature option"; + case 13: + return "Timestamp option"; + case 14: + return "Nonce option"; + case 15: + return "Trust Anchor option"; + case 16: + return "Certificate option"; + case 17: + return "IP Address/Prefix Option"; + case 18: + return "New Router Prefix Information Option"; + case 19: + return "Link-layer Address Option"; + case 20: + return "Neighbor Advertisement Acknowledgment Option"; + + case 23: + return "Prefix Information"; + case 24: + return "Redirected Header"; + case 25: + return "MTU"; + case 26: + return "NBMA Shortcut Limit Option"; + case 27: + return "Advertisement Interval Option"; + case 28: + return "Home Agent Information Option"; + case 29: + return "Source Address List"; + case 30: + return "Target Address List"; + case 31: + return "DNS Search List Option"; + case 32: + return "Proxy Signature (PS)"; + + case 138: + return "CARD Request option"; + case 139: + return "CARD Reply option"; + + case 253: + return "RFC3692-style Experiment 1"; + case 254: + return "RFC3692-style Experiment 2"; } return NULL; @@ -476,7 +429,7 @@ static inline void dissect_neighb_disc_ops(struct pkt_buff *pkt) { size_t ops_total_len, ops_payl_len; struct icmpv6_neighb_disc_ops_general *icmp_neighb_disc; - + while(pkt_len(pkt)) { icmp_neighb_disc = (struct icmpv6_neighb_disc_ops_general *) pkt_pull(pkt,sizeof(*icmp_neighb_disc)); @@ -492,7 +445,7 @@ static inline void dissect_neighb_disc_ops(struct pkt_buff *pkt) : "Type Unknown", icmp_neighb_disc->type); tprintf("Length (%u, %u bytes) ", icmp_neighb_disc->len, ops_total_len); - + switch (icmp_neighb_disc->type) { case 1: dissect_neighb_disc_ops_1(pkt, ops_payl_len); @@ -524,6 +477,173 @@ static inline void dissect_neighb_disc_ops(struct pkt_buff *pkt) } } +static char *icmpv6_type_1_codes[] = { + "No route to destination", + "Communication with destination administratively prohibited", + "Beyond scope of source address", + "Address unreachable", + "Port unreachable", + "Source address failed ingress/egress policy", + "Reject route to destination", + "Error in Source Routing Header", +}; + +static inline void dissect_icmpv6_type1(struct pkt_buff *pkt) +{ + struct icmpv6_type_1_3 *icmp_1; + + icmp_1 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_1)); + if (icmp_1 == NULL) + return; + + tprintf(", Unused (0x%x)",ntohl(icmp_1->unused)); + tprintf(" Payload include as much of invoking packet"); +} + +static inline void dissect_icmpv6_type2(struct pkt_buff *pkt) +{ + struct icmpv6_type_2 *icmp_2; + + icmp_2 = (struct icmpv6_type_2 *) pkt_pull(pkt,sizeof(*icmp_2)); + if (icmp_2 == NULL) + return; + + tprintf(", MTU (0x%x)",ntohl(icmp_2->MTU)); + tprintf(" Payload include as much of invoking packet"); +} + +static char *icmpv6_type_3_codes[] = { + "Hop limit exceeded in transit", + "Fragment reassembly time exceeded", +}; + +static inline void dissect_icmpv6_type3(struct pkt_buff *pkt) +{ + struct icmpv6_type_1_3 *icmp_3; + + icmp_3 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_3)); + if (icmp_3 == NULL) + return; + + tprintf(", Unused (0x%x)",ntohl(icmp_3->unused)); + tprintf(" Payload include as much of invoking packet"); +} + +static char *icmpv6_type_4_codes[] = { + "Erroneous header field encountered", + "Unrecognized Next Header type encountered", + "Unrecognized IPv6 option encountered", +}; + +static inline void dissect_icmpv6_type4(struct pkt_buff *pkt) +{ + struct icmpv6_type_4 *icmp_4; + + icmp_4 = (struct icmpv6_type_4 *) pkt_pull(pkt,sizeof(*icmp_4)); + if (icmp_4 == NULL) + return; + + tprintf(", Pointer (0x%x)",ntohl(icmp_4->pointer)); + tprintf(" Payload include as much of invoking packet"); +} + +static inline void dissect_icmpv6_type128(struct pkt_buff *pkt) +{ + struct icmpv6_type_128_129 *icmp_128; + + icmp_128 = (struct icmpv6_type_128_129 *) + pkt_pull(pkt,sizeof(*icmp_128)); + if (icmp_128 == NULL) + return; + + tprintf(", ID (0x%x)",ntohs(icmp_128->id)); + tprintf(", Seq. Nr. (%u)",ntohs(icmp_128->sn)); + tprintf(" Payload include Data"); +} + +static inline void dissect_icmpv6_type129(struct pkt_buff *pkt) +{ + struct icmpv6_type_128_129 *icmp_129; + + icmp_129 = (struct icmpv6_type_128_129 *) + pkt_pull(pkt,sizeof(*icmp_129)); + if (icmp_129 == NULL) + return; + + tprintf(", ID (0x%x)",ntohs(icmp_129->id)); + tprintf(", Seq. Nr. (%u)",ntohs(icmp_129->sn)); + tprintf(" Payload include Data"); +} + +static inline void dissect_icmpv6_type130(struct pkt_buff *pkt) +{ + char address[INET6_ADDRSTRLEN]; + uint16_t nr_src, maxrespdel; + uint8_t switch_mldv2 = 0; + struct icmpv6_type_130_131_132 *icmp_130; + + icmp_130 = (struct icmpv6_type_130_131_132 *) + pkt_pull(pkt,sizeof(*icmp_130)); + if (icmp_130 == NULL) + return; + maxrespdel = ntohs(icmp_130->maxrespdel); + + if(pkt_len(pkt) >= sizeof(struct icmpv6_type_130_mldv2)) + switch_mldv2 = 1; + + if(switch_mldv2) + tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel >> 15 ? + (((maxrespdel & 0xFFF) | 0x1000) << + (((maxrespdel >> 12) & 0x3) + 3)) : maxrespdel); + else + tprintf(", Max Resp Delay (%ums)",maxrespdel); + tprintf(", Res (0x%x)",ntohs(icmp_130->res)); + tprintf(", Address: %s", + inet_ntop(AF_INET6, &icmp_130->ipv6_addr, + address, sizeof(address))); + + if(switch_mldv2) { + struct icmpv6_type_130_mldv2 *icmp_130_mldv2; + + icmp_130_mldv2 = (struct icmpv6_type_130_mldv2 *) + pkt_pull(pkt,sizeof(*icmp_130_mldv2)); + if (icmp_130_mldv2 == NULL) + return; + + nr_src = ntohs(icmp_130_mldv2->nr_src); + + tprintf(", Resv (0x%x)",icmp_130_mldv2->resv_S_QRV >> 4); + tprintf(", S (%u)",(icmp_130_mldv2->resv_S_QRV >> 3) & 0x1); + tprintf(", QRV (0x%x)",icmp_130_mldv2->resv_S_QRV & 0x3); + tprintf(", QQIC (%u)",icmp_130_mldv2->QQIC); + tprintf(", Nr Src (0x%x)",nr_src); + + print_ipv6_addr_list(pkt, nr_src); + } +} + +static inline void dissect_icmpv6_type131(struct pkt_buff *pkt) +{ + char address[INET6_ADDRSTRLEN]; + struct icmpv6_type_130_131_132 *icmp_131; + + icmp_131 = (struct icmpv6_type_130_131_132 *) + pkt_pull(pkt,sizeof(*icmp_131)); + if (icmp_131 == NULL) + return; + + tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131->maxrespdel)); + tprintf(", Res (0x%x)",ntohs(icmp_131->res)); + tprintf(", Address: %s", + inet_ntop(AF_INET6, &icmp_131->ipv6_addr, + address, sizeof(address))); +} + +static inline void dissect_icmpv6_type132(struct pkt_buff *pkt) +{ + dissect_icmpv6_type131(pkt); +} + static inline void dissect_icmpv6_type133(struct pkt_buff *pkt) { struct icmpv6_type_133_141_142 *icmp_133; @@ -729,48 +849,6 @@ static inline void dissect_icmpv6_type142(struct pkt_buff *pkt) dissect_icmpv6_type133(pkt); } -static char *icmpv6_type_143_rec_types[] = { - "MODE_IS_INCLUDE", - "MODE_IS_EXCLUDE", - "CHANGE_TO_INCLUDE_MODE", - "CHANGE_TO_EXCLUDE_MODE", - "ALLOW_NEW_SOURCES", - "BLOCK_OLD_SOURCES", -}; - -static inline void dissect_icmpv6_mcast_rec(struct pkt_buff *pkt, - uint16_t nr_rec) -{ - size_t aux_data_len_bytes; - uint16_t nr_src; - struct icmpv6_mldv2_addr_rec *addr_rec; - - while (nr_rec--) { - addr_rec = (struct icmpv6_mldv2_addr_rec *) - pkt_pull(pkt,sizeof(*addr_rec)); - if (addr_rec == NULL) - return; - aux_data_len_bytes = addr_rec->aux_data_len * 4; - nr_src = ntohs(addr_rec->nr_src); - - tprintf(", Rec Type %s (%u)", - icmpv6_code_range_valid(addr_rec->rec_type - 1, - icmpv6_type_143_rec_types) ? - icmpv6_type_143_rec_types[addr_rec->rec_type - 1] - : "Unknown", addr_rec->rec_type); - tprintf(", Aux Data Len (%u, %u bytes)",addr_rec->aux_data_len, - aux_data_len_bytes); - tprintf(", Nr. of Sources (%u)",nr_src); - - print_ipv6_addr_list(pkt, nr_src); - - tprintf(", Aux Data: "); - while (aux_data_len_bytes--) { - tprintf("%x", *pkt_pull(pkt,1)); - } - } -} - static inline void dissect_icmpv6_type143(struct pkt_buff *pkt) { uint16_t nr_rec; @@ -788,6 +866,57 @@ static inline void dissect_icmpv6_type143(struct pkt_buff *pkt) dissect_icmpv6_mcast_rec(pkt, nr_rec); } +static inline void dissect_icmpv6_type144(struct pkt_buff *pkt) +{ + struct icmpv6_type_144_146 *icmp_144; + + icmp_144 = (struct icmpv6_type_144_146 *) + pkt_pull(pkt,sizeof(*icmp_144)); + if (icmp_144 == NULL) + return; + + tprintf(", ID (%u)",ntohs(icmp_144->id)); + tprintf(", Res (0x%x)",ntohs(icmp_144->res)); +} + +static inline void dissect_icmpv6_type145(struct pkt_buff *pkt) +{ + struct icmpv6_type_145 *icmp_145; + + icmp_145 = (struct icmpv6_type_145 *) + pkt_pull(pkt,sizeof(*icmp_145)); + if (icmp_145 == NULL) + return; + + tprintf(", ID (%u)",ntohs(icmp_145->id)); + tprintf(", Res (0x%x)",ntohs(icmp_145->res)); + + print_ipv6_addr_list(pkt, pkt_len(pkt) / sizeof(struct in6_addr)); +} + +static inline void dissect_icmpv6_type146(struct pkt_buff *pkt) +{ + dissect_icmpv6_type144(pkt); +} + +static inline void dissect_icmpv6_type147(struct pkt_buff *pkt) +{ + uint16_t m_o_res; + struct icmpv6_type_147 *icmp_147; + + icmp_147 = (struct icmpv6_type_147 *) + pkt_pull(pkt,sizeof(*icmp_147)); + if (icmp_147 == NULL) + return; + m_o_res = ntohs(icmp_147->m_o_res); + + tprintf(", ID (%u)",ntohs(icmp_147->id)); + tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res >> 15, + (m_o_res >> 14) & 1, m_o_res & 0x3FFF); + + dissect_neighb_disc_ops(pkt); +} + static inline void icmpv6_process(struct icmpv6_general_hdr *icmp, char **type, char **code, void (**optional)(struct pkt_buff *pkt)) @@ -930,6 +1059,9 @@ static inline void icmpv6_process(struct icmpv6_general_hdr *icmp, char **type, case 153: *type = "Multicast Router Termination"; return; + case 154: + *type = "FMIPv6 Messages"; + return; case 155: *type = "RPL Control Message"; return; -- 2.11.4.GIT