static inline void ether_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) { register const struct ether_header *ep; u_int16_t ether_type; ep = (const struct ether_header *)bp; (void)ND_PRINT((ndo, "%s > %s", etheraddr_string(ESRC(ep)), etheraddr_string(EDST(ep)))); ether_type = EXTRACT_16BITS(&ep->ether_type); if (!ndo->ndo_qflag) { if (ether_type <= ETHERMTU) (void)ND_PRINT((ndo, ", 802.3")); else (void)ND_PRINT((ndo, ", ethertype %s (0x%04x)", tok2str(ethertype_values,"Unknown", ether_type), ether_type)); } else { if (ether_type <= ETHERMTU) (void)ND_PRINT((ndo, ", 802.3")); else (void)ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type))); } (void)ND_PRINT((ndo, ", length %u: ", length)); }
/* * Print RRCP requests */ void rrcp_print(netdissect_options *ndo, register const u_char *cp, u_int length _U_) { const u_char *rrcp; uint8_t rrcp_proto; uint8_t rrcp_opcode; register const struct ether_header *ep; char proto_str[16]; char opcode_str[32]; ep = (const struct ether_header *)cp; rrcp = cp + ETHER_HDRLEN; ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; ND_PRINT((ndo, "%s > %s, %s %s", etheraddr_string(ndo, ESRC(ep)), etheraddr_string(ndo, EDST(ep)), tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)), ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); if (rrcp_proto==1){ ND_PRINT((ndo, ": %s", tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); } if (rrcp_opcode==1 || rrcp_opcode==2){ ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); } if (rrcp_proto==1){ ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); ND_PRINT((ndo, ", auth=0x%04x", EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); } if (rrcp_proto==1 && rrcp_opcode==0 && ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), *(rrcp + RRCP_UPLINK_PORT_OFFSET), etheraddr_string(ndo, rrcp + RRCP_UPLINK_MAC_OFFSET), EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); ND_PRINT((ndo, ", cookie=0x%08x%08x ", EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); } return; trunc: ND_PRINT((ndo, "[|rrcp]")); }
static inline void ether_print(register const u_char *bp, u_int length) { register const struct ether_header *ep; ep = (const struct ether_header *)bp; if (qflag) (void)printf("%s %s %d: ", etheraddr_string(ESRC(ep)), etheraddr_string(EDST(ep)), length); else (void)printf("%s %s %s %d: ", etheraddr_string(ESRC(ep)), etheraddr_string(EDST(ep)), etherproto_string(ep->ether_type), length); }
void medsa_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { register const struct ether_header *ep; const struct medsa_pkthdr *medsa; u_short ether_type; medsa = (const struct medsa_pkthdr *)bp; ep = (const struct ether_header *)(bp - sizeof(*ep)); ND_TCHECK(*medsa); if (!ndo->ndo_eflag) ND_PRINT((ndo, "MEDSA %d.%d:%d: ", SRC_DEV(medsa), SRC_PORT(medsa), VID(medsa))); else medsa_print_full(ndo, medsa, caplen); bp += 8; length -= 8; caplen -= 8; ether_type = EXTRACT_16BITS(&medsa->ether_type); if (ether_type <= ETHERMTU) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(ndo, bp, length, caplen, ESRC(ep), EDST(ep)) < 0) { /* packet type not known, print raw packet */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(bp, caplen); } } else { if (ndo->ndo_eflag) ND_PRINT((ndo, "ethertype %s (0x%04x) ", tok2str(ethertype_values, "Unknown", ether_type), ether_type)); if (ethertype_print(ndo, ether_type, bp, length, caplen) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) ND_PRINT((ndo, "ethertype %s (0x%04x) ", tok2str(ethertype_values, "Unknown", ether_type), ether_type)); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(bp, caplen); } } return; trunc: ND_PRINT((ndo, "%s", tstr)); }
/* Process an ethernet arp/rarp packet */ void process_ether(register u_char *u, register const struct pcap_pkthdr *h, register const u_char *p) { register struct ether_header *eh; register struct ether_arp *ea; register u_char *sea, *sha; register time_t t; u_int32_t sia; eh = (struct ether_header *)p; ea = (struct ether_arp *)(eh + 1); if (!sanity_ether(eh, ea, h->caplen)) return; /* Source hardware ethernet address */ sea = (u_char *)ESRC(eh); /* Source ethernet address */ sha = (u_char *)SHA(ea); /* Source ip address */ BCOPY(SPA(ea), &sia, 4); /* Watch for bogons */ if (isbogon(sia)) { dosyslog(LOG_INFO, "bogon", sia, sea, sha); return; } /* Watch for ethernet broadcast */ if (MEMCMP(sea, zero, 6) == 0 || MEMCMP(sea, allones, 6) == 0 || MEMCMP(sha, zero, 6) == 0 || MEMCMP(sha, allones, 6) == 0) { dosyslog(LOG_INFO, "ethernet broadcast", sia, sea, sha); return; } /* Double check ethernet addresses */ if (MEMCMP(sea, sha, 6) != 0) { dosyslog(LOG_INFO, "ethernet mismatch", sia, sea, sha); return; } /* Got a live one */ t = h->ts.tv_sec; can_checkpoint = 0; if (!ent_add(sia, sea, t, NULL)) syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed", intoa(sia), e2str(sea), t); can_checkpoint = 1; }
/* * Print an Ethernet frame. * This might be encapsulated within another frame; we might be passed * a pointer to a function that can print header information for that * frame's protocol, and an argument to pass to that function. */ void ether_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg) { struct ether_header *ep; u_int orig_length; u_short ether_type; u_short extracted_ether_type; if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { ND_PRINT((ndo, "[|ether]")); return; } if (ndo->ndo_eflag) { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, p, length); } orig_length = length; length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; ep = (struct ether_header *)p; p += ETHER_HDRLEN; ether_type = EXTRACT_16BITS(&ep->ether_type); recurse: /* * Is it (gag) an 802.3 encapsulation? */ if (ether_type <= ETHERMTU) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, (u_char *)ep, orig_length); } if (!ndo->ndo_suppress_default_print) ndo->ndo_default_print(ndo, p, caplen); } } else if (ether_type == ETHERTYPE_8021Q || ether_type == ETHERTYPE_8021Q9100 || ether_type == ETHERTYPE_8021Q9200 || ether_type == ETHERTYPE_8021QinQ) { /* * Print VLAN information, and then go back and process * the enclosed type field. */ if (caplen < 4 || length < 4) { ND_PRINT((ndo, "[|vlan]")); return; } if (ndo->ndo_eflag) { u_int16_t tag = EXTRACT_16BITS(p); ND_PRINT((ndo, "vlan %u, p %u%s, ", tag & 0xfff, tag >> 13, (tag & 0x1000) ? ", CFI" : "")); } ether_type = EXTRACT_16BITS(p + 2); if (ndo->ndo_eflag && ether_type > ETHERMTU) ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type))); p += 4; length -= 4; caplen -= 4; goto recurse; } else if (ether_type == ETHERTYPE_JUMBO) {
/* * Print bootp requests */ void bootp_print(struct bootp *bp, int length, u_short sport, u_short dport) { static char tstr[] = " [|bootp]"; static unsigned char vm_cmu[4] = VM_CMU; static unsigned char vm_rfc1048[4] = VM_RFC1048; u_char *ep; int vdlen; #define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc /* Note funny sized packets */ if (length != sizeof(struct bootp)) (void) printf(" [len=%d]", length); /* 'ep' points to the end of avaible data. */ ep = (u_char *) snapend; switch (bp->bp_op) { case BOOTREQUEST: /* Usually, a request goes from a client to a server */ if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) printf(" (request)"); break; case BOOTREPLY: /* Usually, a reply goes from a server to a client */ if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) printf(" (reply)"); break; default: printf(" bootp-#%d", bp->bp_op); } /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) printf(" htype:%d", bp->bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp->bp_hlen != 6) printf(" hlen:%d", bp->bp_hlen); /* Client's Hardware address */ if (bp->bp_hlen) { struct ether_header *eh; char *e; TCHECK(bp->bp_chaddr[0], 6); eh = (struct ether_header *) packetp; if (bp->bp_op == BOOTREQUEST) e = (char *) ESRC(eh); else if (bp->bp_op == BOOTREPLY) e = (char *) EDST(eh); else e = NULL; if (e == NULL || bcmp((char *) bp->bp_chaddr, e, 6)) dump_hex(bp->bp_chaddr, bp->bp_hlen); } /* Only print interesting fields */ if (bp->bp_hops) printf(" hops:%d", bp->bp_hops); if (bp->bp_xid) printf(" xid:%ld", (long)ntohl(bp->bp_xid)); if (bp->bp_secs) printf(" secs:%d", ntohs(bp->bp_secs)); /* Client's ip address */ TCHECK(bp->bp_ciaddr, sizeof(bp->bp_ciaddr)); if (bp->bp_ciaddr.s_addr) printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ TCHECK(bp->bp_yiaddr, sizeof(bp->bp_yiaddr)); if (bp->bp_yiaddr.s_addr) printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); /* Server's ip address */ TCHECK(bp->bp_siaddr, sizeof(bp->bp_siaddr)); if (bp->bp_siaddr.s_addr) printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); /* Gateway's ip address */ TCHECK(bp->bp_giaddr, sizeof(bp->bp_giaddr)); if (bp->bp_giaddr.s_addr) printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); TCHECK(bp->bp_sname[0], sizeof(bp->bp_sname)); if (*bp->bp_sname) { printf(" sname:"); if (printfn(bp->bp_sname, ep)) { fputs(tstr + 1, stdout); return; } } TCHECK(bp->bp_file[0], sizeof(bp->bp_file)); if (*bp->bp_file) { printf(" file:"); if (printfn(bp->bp_file, ep)) { fputs(tstr + 1, stdout); return; } } /* Don't try to decode the vendor buffer unless we're verbose */ if (vflag <= 0) return; vdlen = sizeof(bp->bp_vend); /* Vendor data can extend to the end of the packet. */ if (vdlen < (ep - bp->bp_vend)) vdlen = (ep - bp->bp_vend); TCHECK(bp->bp_vend[0], vdlen); printf(" vend"); if (!bcmp(bp->bp_vend, vm_rfc1048, sizeof(u_int32))) rfc1048_print(bp->bp_vend, vdlen); else if (!bcmp(bp->bp_vend, vm_cmu, sizeof(u_int32))) cmu_print(bp->bp_vend, vdlen); else other_print(bp->bp_vend, vdlen); return; trunc: fputs(tstr, stdout); #undef TCHECK }
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); }
p += 4; length -= 4; caplen -= 4; goto recurse; } else if (ether_type == ETHERTYPE_JUMBO) { /* * Alteon jumbo frames. * See * * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 * * which indicates that, following the type field, * there's an LLC header and payload. */ /* Try to print the LLC-layer header & higher layers */ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ if (!eflag) { if (print_encap_header != NULL) (*print_encap_header)(encap_header_arg); ether_hdr_print((u_char *)ep, orig_length); } if (!suppress_default_print) default_print(p, caplen); } } else { if (ethertype_print(ether_type, p, length, caplen) == 0) { /* ether_type not known, print raw packet */ if (!eflag) {
static inline void ether_hdr_print(register const u_char *bp, u_int length) { register const struct ether_header *ep; ep = (const struct ether_header *)bp; (void)sprintf(&ArgusBuf[strlen(ArgusBuf)],"%s > %s", etheraddr_string(ArgusParser, (u_char *)&ESRC(ep)), etheraddr_string(ArgusParser, (u_char *)&EDST(ep))); if (!ArgusParser->qflag) { if (ntohs(ep->ether_type) <= ETHERMTU) (void)sprintf(&ArgusBuf[strlen(ArgusBuf)],", 802.3"); else (void)sprintf(&ArgusBuf[strlen(ArgusBuf)],", ethertype %s (0x%04x)", tok2str(ethertype_values,"Unknown", ntohs(ep->ether_type)), ntohs(ep->ether_type)); } else { if (ntohs(ep->ether_type) <= ETHERMTU) (void)sprintf(&ArgusBuf[strlen(ArgusBuf)],", 802.3"); else (void)sprintf(&ArgusBuf[strlen(ArgusBuf)],", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(ep->ether_type))); } (void)sprintf(&ArgusBuf[strlen(ArgusBuf)],", length %u: ", length); }
/* * Print an Ethernet frame. * This might be encapsulated within another frame; we might be passed * a pointer to a function that can print header information for that * frame's protocol, and an argument to pass to that function. */ void ether_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen, void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg) { struct ether_header *ep; u_int orig_length; u_short ether_type; u_short extracted_ether_type; if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { ND_PRINT((ndo, "[|ether]")); return; } if (ndo->ndo_eflag) { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, p, length); } orig_length = length; length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; ep = (struct ether_header *)p; p += ETHER_HDRLEN; ether_type = EXTRACT_16BITS(&ep->ether_type); recurse: /* * Is it (gag) an 802.3 encapsulation? */ if (ether_type <= ETHERMTU) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep), &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, (u_char *)ep, orig_length); } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } } else if (ether_type == ETHERTYPE_8021Q || ether_type == ETHERTYPE_8021Q9100 || ether_type == ETHERTYPE_8021Q9200 || ether_type == ETHERTYPE_8021QinQ) { /* * Print VLAN information, and then go back and process * the enclosed type field. */ if (caplen < 4 || length < 4) { ND_PRINT((ndo, "[|vlan]")); return; } if (ndo->ndo_eflag) { uint16_t tag = EXTRACT_16BITS(p); ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag))); } ether_type = EXTRACT_16BITS(p + 2); if (ndo->ndo_eflag && ether_type > ETHERMTU) ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type))); p += 4; length -= 4; caplen -= 4; goto recurse; } else if (ether_type == ETHERTYPE_JUMBO) { /* * Alteon jumbo frames. * See * * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 * * which indicates that, following the type field, * there's an LLC header and payload. */ /* Try to print the LLC-layer header & higher layers */ if (llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep), &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, (u_char *)ep, orig_length); } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } } else { if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { /* ether_type not known, print raw packet */ if (!ndo->ndo_eflag) { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, (u_char *)ep, orig_length); } if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } } }
/* * This is the top level routine of the printer. 'p' is the points * to the ether header of the packet, 'tvp' is the timestamp, * 'length' is the length of the packet off the wire, and 'caplen' * is the number of bytes actually captured. */ void ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; struct ether_header *ep; u_short ether_type; extern u_short extracted_ethertype; ts_print(&h->ts); if (caplen < sizeof(struct ether_header)) { printf("[|ether]"); goto out; } if (eflag) ether_print(p, length); /* * Some printers want to get back at the ethernet addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ packetp = p; snapend = p + caplen; length -= sizeof(struct ether_header); caplen -= sizeof(struct ether_header); ep = (struct ether_header *)p; p += sizeof(struct ether_header); ether_type = ntohs(ep->ether_type); /* * Is it (gag) an 802.3 encapsulation? */ extracted_ethertype = 0; if (ether_type <= ETHERMTU) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) { /* ether_type not known, print raw packet */ if (!eflag) ether_print((u_char *)ep, length); if (extracted_ethertype) { printf("(LLC %s) ", etherproto_string(htons(extracted_ethertype))); } if (!xflag && !qflag) default_print(p, caplen); } } else if (ether_encap_print(ether_type, p, length, caplen) == 0) { /* ether_type not known, print raw packet */ if (!eflag) ether_print((u_char *)ep, length + sizeof(*ep)); if (!xflag && !qflag) default_print(p, caplen); } if (xflag) default_print(p, caplen); out: putchar('\n'); }
/* * This is the top level routine of the printer. 'sp' is the points * to the FDDI header of the packet, 'tvp' is the timestamp, * 'length' is the length of the packet off the wire, and 'caplen' * is the number of bytes actually captured. */ void fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, register const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; const struct fddi_header *fddip = (struct fddi_header *)p; extern u_short extracted_ethertype; struct ether_header ehdr; ts_print(&h->ts); if (caplen < FDDI_HDRLEN) { printf("[|fddi]"); goto out; } /* * Get the FDDI addresses into a canonical form */ extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); /* * Some printers want to get back at the link level addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ snapend = p + caplen; /* * Actually, the only printer that uses packetp is print-bootp.c, * and it assumes that packetp points to an Ethernet header. The * right thing to do is to fix print-bootp.c to know which link * type is in use when it excavates. XXX */ packetp = (u_char *)&ehdr; if (eflag) fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); /* Skip over FDDI MAC header */ length -= FDDI_HDRLEN; p += FDDI_HDRLEN; caplen -= FDDI_HDRLEN; /* Frame Control field determines interpretation of packet */ extracted_ethertype = 0; if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr)) == 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ if (!eflag) fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); if (extracted_ethertype) { printf("(LLC %s) ", etherproto_string(htons(extracted_ethertype))); } if (!xflag && !qflag) default_print(p, caplen); } } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) fddi_smt_print(p, caplen); else { /* Some kinds of FDDI packet we cannot handle intelligently */ if (!eflag) fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); if (!xflag && !qflag) default_print(p, caplen); } if (xflag) default_print(p, caplen); out: putchar('\n'); }
void arp_print(register const u_char *bp, u_int length, u_int caplen) { register const struct ether_arp *ap; register const struct ether_header *eh; register u_short pro, hrd, op; ap = (struct ether_arp *)bp; if ((u_char *)(ap + 1) > snapend) { printf("[|arp]"); return; } if (length < sizeof(struct ether_arp)) { (void)printf("truncated-arp"); default_print((u_char *)ap, length); return; } pro = EXTRACT_16BITS(&ap->arp_pro); hrd = EXTRACT_16BITS(&ap->arp_hrd); op = EXTRACT_16BITS(&ap->arp_op); if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || ap->arp_hln != sizeof(SHA(ap)) || ap->arp_pln != sizeof(SPA(ap))) { (void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)", op, pro, ap->arp_pln, hrd, ap->arp_hln); return; } if (pro == ETHERTYPE_TRAIL) (void)printf("trailer-"); eh = (struct ether_header *)packetp; switch (op) { case ARPOP_REQUEST: (void)printf("arp who-has %s", ipaddr_string(TPA(ap))); if (memcmp((char *)ezero, (char *)THA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(THA(ap))); (void)printf(" tell %s", ipaddr_string(SPA(ap))); if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(SHA(ap))); break; case ARPOP_REPLY: (void)printf("arp reply %s", ipaddr_string(SPA(ap))); if (memcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(SHA(ap))); (void)printf(" is-at %s", etheraddr_string(SHA(ap))); if (memcmp((char *)EDST(eh), (char *)THA(ap), 6) != 0) (void)printf(" (%s)", etheraddr_string(THA(ap))); break; case REVARP_REQUEST: (void)printf("rarp who-is %s tell %s", etheraddr_string(THA(ap)), etheraddr_string(SHA(ap))); break; case REVARP_REPLY: (void)printf("rarp reply %s at %s", etheraddr_string(THA(ap)), ipaddr_string(TPA(ap))); break; default: (void)printf("arp-#%d", op); default_print((u_char *)ap, caplen); return; } if (hrd != ARPHRD_ETHER) printf(" hardware #%d", hrd); }
/* * Print bootp requests */ void bootp_print(const u_char *cp, u_int length, u_short sport, u_short dport) { const struct bootp *bp; static u_char vm_cmu[4] = VM_CMU; static u_char vm_rfc1048[4] = VM_RFC1048; bp = (struct bootp *)cp; TCHECK(bp->bp_op); switch (bp->bp_op) { case BOOTREQUEST: /* Usually, a request goes from a client to a server */ if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) printf(" (request)"); break; case BOOTREPLY: /* Usually, a reply goes from a server to a client */ if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) printf(" (reply)"); break; default: printf(" bootp-#%d", bp->bp_op); } TCHECK(bp->bp_flags); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) printf(" htype-#%d", bp->bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp->bp_htype != 1 || bp->bp_hlen != 6) printf(" hlen:%d", bp->bp_hlen); /* Only print interesting fields */ if (bp->bp_hops) printf(" hops:%d", bp->bp_hops); if (bp->bp_xid) printf(" xid:0x%x", (u_int32_t)ntohl(bp->bp_xid)); if (bp->bp_secs) printf(" secs:%d", ntohs(bp->bp_secs)); if (bp->bp_flags) printf(" flags:0x%x", ntohs(bp->bp_flags)); /* Client's ip address */ TCHECK(bp->bp_ciaddr); if (bp->bp_ciaddr.s_addr) printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ TCHECK(bp->bp_yiaddr); if (bp->bp_yiaddr.s_addr) printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); /* Server's ip address */ TCHECK(bp->bp_siaddr); if (bp->bp_siaddr.s_addr) printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); /* Gateway's ip address */ TCHECK(bp->bp_giaddr); if (bp->bp_giaddr.s_addr) printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); /* Client's Ethernet address */ if (bp->bp_htype == 1 && bp->bp_hlen == 6) { const struct ether_header *eh; const char *e; TCHECK2(bp->bp_chaddr[0], 6); eh = (struct ether_header *)packetp; if (bp->bp_op == BOOTREQUEST) e = (const char *)ESRC(eh); else if (bp->bp_op == BOOTREPLY) e = (const char *)EDST(eh); else e = NULL; if (e == 0 || memcmp((char *)bp->bp_chaddr, e, 6) != 0) printf(" ether %s", etheraddr_string(bp->bp_chaddr)); } TCHECK2(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_sname) { printf(" sname \""); if (fn_print(bp->bp_sname, snapend)) { putchar('"'); fputs(tstr + 1, stdout); return; } putchar('"'); } TCHECK2(bp->bp_file[0], 1); /* check first char only */ if (*bp->bp_file) { printf(" file \""); if (fn_print(bp->bp_file, snapend)) { putchar('"'); fputs(tstr + 1, stdout); return; } putchar('"'); } /* Decode the vendor buffer */ TCHECK2(bp->bp_vend[0], sizeof(u_int32_t)); length -= sizeof(*bp) - sizeof(bp->bp_vend); if (memcmp((char *)bp->bp_vend, (char *)vm_rfc1048, sizeof(u_int32_t)) == 0) rfc1048_print(bp->bp_vend, length); else if (memcmp((char *)bp->bp_vend, (char *)vm_cmu, sizeof(u_int32_t)) == 0) cmu_print(bp->bp_vend, length); else { u_int32_t ul; memcpy((char *)&ul, (char *)bp->bp_vend, sizeof(ul)); if (ul != 0) printf("vend-#0x%x", ul); } return; trunc: fputs(tstr, stdout); }