void gre_print_0(const u_char *bp, u_int length) { u_int len = length; u_int16_t flags, prot; flags = EXTRACT_16BITS(bp); if (vflag) printf(", Flags [%s]", bittok2str(gre_flag_values,"none",flags)); len -= 2; bp += 2; if (len < 2) goto trunc; prot = EXTRACT_16BITS(bp); len -= 2; bp += 2; if ((flags & GRE_CP) | (flags & GRE_RP)) { if (len < 2) goto trunc; if (vflag) printf(", sum 0x%x", EXTRACT_16BITS(bp)); bp += 2; len -= 2; if (len < 2) goto trunc; printf(", off 0x%x", EXTRACT_16BITS(bp)); bp += 2; len -= 2; } if (flags & GRE_KP) { if (len < 4) goto trunc; printf(", key=0x%x", EXTRACT_32BITS(bp)); bp += 4; len -= 4; } if (flags & GRE_SP) { if (len < 4) goto trunc; printf(", seq %u", EXTRACT_32BITS(bp)); bp += 4; len -= 4; } if (flags & GRE_RP) { for (;;) { u_int16_t af; u_int8_t sreoff; u_int8_t srelen; if (len < 4) goto trunc; af = EXTRACT_16BITS(bp); sreoff = *(bp + 2); srelen = *(bp + 3); bp += 4; len -= 4; if (af == 0 && srelen == 0) break; gre_sre_print(af, sreoff, srelen, bp, len); if (len < srelen) goto trunc; bp += srelen; len -= srelen; } } if (eflag) printf(", proto %s (0x%04x)", tok2str(ethertype_values,"unknown",prot), prot); printf(", length %u",length); if (vflag < 1) printf(": "); /* put in a colon as protocol demarc */ else printf("\n\t"); /* if verbose go multiline */ switch (prot) { case ETHERTYPE_IP: ip_print(gndo, bp, len); break; #ifdef INET6 case ETHERTYPE_IPV6: ip6_print(gndo, bp, len); break; #endif case ETHERTYPE_MPLS: mpls_print(bp, len); break; case ETHERTYPE_IPX: ipx_print(bp, len); break; case ETHERTYPE_ATALK: atalk_print(bp, len); break; case ETHERTYPE_GRE_ISO: isoclns_print(bp, len, len); break; case ETHERTYPE_TEB: ether_print(gndo, bp, len, len, NULL, NULL); break; default: printf("gre-proto-0x%x", prot); } return; trunc: printf("[|gre]"); }
static void gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length) { u_int len = length; uint16_t flags, prot; /* 16 bits ND_TCHECKed in gre_print() */ flags = EXTRACT_BE_U_2(bp); if (ndo->ndo_vflag) ND_PRINT(", Flags [%s]", bittok2str(gre_flag_values,"none",flags)); len -= 2; bp += 2; ND_TCHECK_2(bp); if (len < 2) goto trunc; prot = EXTRACT_BE_U_2(bp); len -= 2; bp += 2; if ((flags & GRE_CP) | (flags & GRE_RP)) { ND_TCHECK_2(bp); if (len < 2) goto trunc; if (ndo->ndo_vflag) ND_PRINT(", sum 0x%x", EXTRACT_BE_U_2(bp)); bp += 2; len -= 2; ND_TCHECK_2(bp); if (len < 2) goto trunc; ND_PRINT(", off 0x%x", EXTRACT_BE_U_2(bp)); bp += 2; len -= 2; } if (flags & GRE_KP) { ND_TCHECK_4(bp); if (len < 4) goto trunc; ND_PRINT(", key=0x%x", EXTRACT_BE_U_4(bp)); bp += 4; len -= 4; } if (flags & GRE_SP) { ND_TCHECK_4(bp); if (len < 4) goto trunc; ND_PRINT(", seq %u", EXTRACT_BE_U_4(bp)); bp += 4; len -= 4; } if (flags & GRE_RP) { for (;;) { uint16_t af; uint8_t sreoff; uint8_t srelen; ND_TCHECK_4(bp); if (len < 4) goto trunc; af = EXTRACT_BE_U_2(bp); sreoff = EXTRACT_U_1(bp + 2); srelen = EXTRACT_U_1(bp + 3); bp += 4; len -= 4; if (af == 0 && srelen == 0) break; if (!gre_sre_print(ndo, af, sreoff, srelen, bp, len)) goto trunc; if (len < srelen) goto trunc; bp += srelen; len -= srelen; } } if (ndo->ndo_eflag) ND_PRINT(", proto %s (0x%04x)", tok2str(ethertype_values,"unknown",prot), prot); ND_PRINT(", length %u",length); if (ndo->ndo_vflag < 1) ND_PRINT(": "); /* put in a colon as protocol demarc */ else ND_PRINT("\n\t"); /* if verbose go multiline */ switch (prot) { case ETHERTYPE_IP: ip_print(ndo, bp, len); break; case ETHERTYPE_IPV6: ip6_print(ndo, bp, len); break; case ETHERTYPE_MPLS: mpls_print(ndo, bp, len); break; case ETHERTYPE_IPX: ipx_print(ndo, bp, len); break; case ETHERTYPE_ATALK: atalk_print(ndo, bp, len); break; case ETHERTYPE_GRE_ISO: isoclns_print(ndo, bp, len); break; case ETHERTYPE_TEB: ether_print(ndo, bp, len, ndo->ndo_snapend - bp, NULL, NULL); break; default: ND_PRINT("gre-proto-0x%x", prot); } return; trunc: ND_PRINT("%s", tstr); }