u_int _token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct token_header *trp; u_short extracted_ethertype; struct ether_header ehdr; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; trp = (const struct token_header *)p; if (caplen < TOKEN_HDRLEN) { ND_PRINT((ndo, "%s", tstr)); return hdr_len; } /* * Get the TR addresses into a canonical form */ extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); /* Adjust for source routing information in the MAC header */ if (IS_SOURCE_ROUTED(trp)) { /* Clear source-routed bit */ *ESRC(&ehdr) &= 0x7f; if (ndo->ndo_eflag) token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr)); if (caplen < TOKEN_HDRLEN + 2) { ND_PRINT((ndo, "%s", tstr)); return hdr_len; } route_len = RIF_LENGTH(trp); hdr_len += route_len; if (caplen < hdr_len) { ND_PRINT((ndo, "%s", tstr)); return hdr_len; } if (ndo->ndo_vflag) { ND_PRINT((ndo, "%s ", broadcast_indicator[BROADCAST(trp)])); ND_PRINT((ndo, "%s", direction[DIRECTION(trp)])); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) ND_PRINT((ndo, " [%d:%d]", RING_NUMBER(trp, seg), BRIDGE_NUMBER(trp, seg))); } else { ND_PRINT((ndo, "rt = %x", EXTRACT_16BITS(&trp->token_rcf))); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) ND_PRINT((ndo, ":%x", EXTRACT_16BITS(&trp->token_rseg[seg]))); } ND_PRINT((ndo, " (%s) ", largest_frame[LARGEST_FRAME(trp)])); } else { if (ndo->ndo_eflag) token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr)); } /* Skip over token ring MAC header and routing information */ length -= hdr_len; p += hdr_len; caplen -= hdr_len; /* Frame Control field determines interpretation of packet */ if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr), &extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len, ESRC(&ehdr), EDST(&ehdr)); if (extracted_ethertype) { ND_PRINT((ndo, "(LLC %s) ", etherproto_string(htons(extracted_ethertype)))); } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } } else { /* Some kinds of TR packet we cannot handle intelligently */ /* XXX - dissect MAC packets if frame type is 0 */ if (!ndo->ndo_eflag) token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len, ESRC(&ehdr), EDST(&ehdr)); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } return (hdr_len); }
u_int token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) { const struct token_header *trp; int llc_hdrlen; nd_mac_addr srcmac, dstmac; struct lladdr_info src, dst; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; ndo->ndo_protocol = "token"; trp = (const struct token_header *)p; if (caplen < TOKEN_HDRLEN) { nd_print_trunc(ndo); return hdr_len; } /* * Get the TR addresses into a canonical form */ extract_token_addrs(trp, (char*)srcmac, (char*)dstmac); /* Adjust for source routing information in the MAC header */ if (IS_SOURCE_ROUTED(trp)) { /* Clear source-routed bit */ srcmac[0] &= 0x7f; if (ndo->ndo_eflag) token_hdr_print(ndo, trp, length, srcmac, dstmac); if (caplen < TOKEN_HDRLEN + 2) { nd_print_trunc(ndo); return hdr_len; } route_len = RIF_LENGTH(trp); hdr_len += route_len; if (caplen < hdr_len) { nd_print_trunc(ndo); return hdr_len; } if (ndo->ndo_vflag) { ND_PRINT("%s ", broadcast_indicator[BROADCAST(trp)]); ND_PRINT("%s", direction[DIRECTION(trp)]); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) ND_PRINT(" [%u:%u]", RING_NUMBER(trp, seg), BRIDGE_NUMBER(trp, seg)); } else { ND_PRINT("rt = %x", EXTRACT_BE_U_2(trp->token_rcf)); for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) ND_PRINT(":%x", EXTRACT_BE_U_2(trp->token_rseg[seg])); } ND_PRINT(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); } else { if (ndo->ndo_eflag) token_hdr_print(ndo, trp, length, srcmac, dstmac); } src.addr = srcmac; src.addr_string = etheraddr_string; dst.addr = dstmac; dst.addr_string = etheraddr_string; /* Skip over token ring MAC header and routing information */ length -= hdr_len; p += hdr_len; caplen -= hdr_len; /* Frame Control field determines interpretation of packet */ if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { /* Try to print the LLC-layer header & higher layers */ llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); if (llc_hdrlen < 0) { /* packet type not known, print raw packet */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); llc_hdrlen = -llc_hdrlen; } hdr_len += llc_hdrlen; } else { /* Some kinds of TR packet we cannot handle intelligently */ /* XXX - dissect MAC packets if frame type is 0 */ if (!ndo->ndo_eflag) token_hdr_print(ndo, trp, length + TOKEN_HDRLEN + route_len, srcmac, dstmac); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } return (hdr_len); }