/* * This is the top level routine of the printer. 'p' points * to the ARCNET header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. It is quite similar * to the non-Linux style printer except that Linux doesn't ever * supply packets that look like exception frames, it always supplies * reassembled packets rather than raw frames, and headers have an * extra "offset" field between the src/dest and packet type. */ u_int arcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; const struct arc_linux_header *ap; int archdrlen = 0; u_char arc_type; if (caplen < ARC_LINUX_HDRLEN) { printf("[|arcnet]"); return (caplen); } ap = (const struct arc_linux_header *)p; arc_type = ap->arc_type; switch (arc_type) { default: archdrlen = ARC_LINUX_HDRNEWLEN; if (caplen < ARC_LINUX_HDRNEWLEN) { printf("[|arcnet]"); return (caplen); } break; case ARCTYPE_IP_OLD: case ARCTYPE_ARP_OLD: case ARCTYPE_DIAGNOSE: archdrlen = ARC_LINUX_HDRLEN; break; } if (eflag) arcnet_print(p, length, 0, 0, 0); /* * Go past the ARCNET header. */ length -= archdrlen; caplen -= archdrlen; p += archdrlen; if (!arcnet_encap_print(arc_type, p, length, caplen)) default_print(p, caplen); return (archdrlen); }
/* * This is the top level routine of the printer. 'p' points * to the ARCNET header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. It is quite similar * to the non-Linux style printer except that Linux doesn't ever * supply packets that look like exception frames, it always supplies * reassembled packets rather than raw frames, and headers have an * extra "offset" field between the src/dest and packet type. */ u_int arcnet_linux_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; const struct arc_linux_header *ap; int archdrlen = 0; u_char arc_type; if (caplen < ARC_LINUX_HDRLEN || length < ARC_LINUX_HDRLEN) { ND_PRINT("[|arcnet]"); return (caplen); } ap = (const struct arc_linux_header *)p; arc_type = EXTRACT_U_1(ap->arc_type); switch (arc_type) { default: archdrlen = ARC_LINUX_HDRNEWLEN; if (caplen < ARC_LINUX_HDRNEWLEN || length < ARC_LINUX_HDRNEWLEN) { ND_PRINT("[|arcnet]"); return (caplen); } break; case ARCTYPE_IP_OLD: case ARCTYPE_ARP_OLD: case ARCTYPE_DIAGNOSE: archdrlen = ARC_LINUX_HDRLEN; break; } if (ndo->ndo_eflag) arcnet_print(ndo, p, length, 0, 0, 0); /* * Go past the ARCNET header. */ length -= archdrlen; caplen -= archdrlen; p += archdrlen; if (!arcnet_encap_print(ndo, arc_type, p, length, caplen)) ND_DEFAULTPRINT(p, caplen); return (archdrlen); }
/* * This is the top level routine of the printer. 'p' points * to the ARCNET header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; const struct arc_header *ap; int phds, flag = 0, archdrlen = 0; u_int seqid = 0; u_char arc_type; if (caplen < ARC_HDRLEN) { printf("[|arcnet]"); return (caplen); } ap = (const struct arc_header *)p; arc_type = ap->arc_type; switch (arc_type) { default: phds = 1; break; case ARCTYPE_IP_OLD: case ARCTYPE_ARP_OLD: case ARCTYPE_DIAGNOSE: phds = 0; archdrlen = ARC_HDRLEN; break; } if (phds) { if (caplen < ARC_HDRNEWLEN) { arcnet_print(p, length, 0, 0, 0); printf("[|phds]"); return (caplen); } if (ap->arc_flag == 0xff) { if (caplen < ARC_HDRNEWLEN_EXC) { arcnet_print(p, length, 0, 0, 0); printf("[|phds extended]"); return (caplen); } flag = ap->arc_flag2; seqid = EXTRACT_16BITS(&ap->arc_seqid2); archdrlen = ARC_HDRNEWLEN_EXC; } else { flag = ap->arc_flag; seqid = EXTRACT_16BITS(&ap->arc_seqid); archdrlen = ARC_HDRNEWLEN; } } if (eflag) arcnet_print(p, length, phds, flag, seqid); /* * Go past the ARCNET header. */ length -= archdrlen; caplen -= archdrlen; p += archdrlen; if (phds && flag && (flag & 1) == 0) { /* * This is a middle fragment. */ return (archdrlen); } if (!arcnet_encap_print(arc_type, p, length, caplen)) default_print(p, caplen); return (archdrlen); }
/* * This is the top level routine of the printer. 'p' points * to the ARCNET header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int arcnet_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; const struct arc_header *ap; int phds; u_int flag = 0, archdrlen = 0; u_int seqid = 0; u_char arc_type; if (caplen < ARC_HDRLEN || length < ARC_HDRLEN) { ND_PRINT("[|arcnet]"); return (caplen); } ap = (const struct arc_header *)p; arc_type = EXTRACT_U_1(ap->arc_type); switch (arc_type) { default: phds = 1; break; case ARCTYPE_IP_OLD: case ARCTYPE_ARP_OLD: case ARCTYPE_DIAGNOSE: phds = 0; archdrlen = ARC_HDRLEN; break; } if (phds) { if (caplen < ARC_HDRNEWLEN || length < ARC_HDRNEWLEN) { arcnet_print(ndo, p, length, 0, 0, 0); ND_PRINT("[|phds]"); return (caplen); } flag = EXTRACT_U_1(ap->arc_flag); if (flag == 0xff) { if (caplen < ARC_HDRNEWLEN_EXC || length < ARC_HDRNEWLEN_EXC) { arcnet_print(ndo, p, length, 0, 0, 0); ND_PRINT("[|phds extended]"); return (caplen); } flag = EXTRACT_U_1(ap->arc_flag2); seqid = EXTRACT_BE_U_2(ap->arc_seqid2); archdrlen = ARC_HDRNEWLEN_EXC; } else { seqid = EXTRACT_BE_U_2(ap->arc_seqid); archdrlen = ARC_HDRNEWLEN; } } if (ndo->ndo_eflag) arcnet_print(ndo, p, length, phds, flag, seqid); /* * Go past the ARCNET header. */ length -= archdrlen; caplen -= archdrlen; p += archdrlen; if (phds && flag && (flag & 1) == 0) { /* * This is a middle fragment. */ return (archdrlen); } if (!arcnet_encap_print(ndo, arc_type, p, length, caplen)) ND_DEFAULTPRINT(p, caplen); return (archdrlen); }