static void print_vendor_attr(packetbody_t data, u_int length, u_short attr_code _U_) { u_int idx; u_int vendor_id; u_int vendor_type; u_int vendor_length; if (length < 4) goto trunc; PACKET_HAS_SPACE_OR_TRUNC(data, 4); vendor_id = EXTRACT_32BITS(data); data+=4; length-=4; printf("Vendor: %s (%u)", tok2str(smi_values,"Unknown",vendor_id), vendor_id); while (length >= 2) { PACKET_HAS_SPACE_OR_TRUNC(data, 2); vendor_type = *(data); vendor_length = *(data+1); if (vendor_length < 2) { printf("\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", vendor_type, vendor_length); return; } if (vendor_length > length) { printf("\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", vendor_type, vendor_length); return; } data+=2; vendor_length-=2; length-=2; PACKET_HAS_SPACE_OR_TRUNC(data, vendor_length); printf("\n\t Vendor Attribute: %u, Length: %u, Value: ", vendor_type, vendor_length); for (idx = 0; idx < vendor_length ; idx++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); length-=vendor_length; } return; trunc: printf(" [|radius]"); }
static void print_attr_address(packetbody_t data, u_int length, u_short attr_code ) { if (length != 4) { printf("ERROR: length %u != 4", length); return; } PACKET_HAS_SPACE_OR_TRUNC(data,4); switch(attr_code) { case FRM_IPADDR: case LOG_IPHOST: if (EXTRACT_32BITS(data) == 0xFFFFFFFF ) printf("User Selected"); else if (EXTRACT_32BITS(data) == 0xFFFFFFFE ) printf("NAS Select"); else printf("%s",ipaddr_string(data)); break; default: printf("%s",ipaddr_string(data) ); break; } return; trunc: printf(" [|radius]"); }
void carp_print(packetbody_t bp, register u_int len, int ttl) { int version, type; const char *type_s; PACKET_HAS_ONE_OR_TRUNC(bp); version = (bp[0] & 0xf0) >> 4; type = bp[0] & 0x0f; if (type == 1) type_s = "advertise"; else type_s = "unknown"; printf("CARPv%d-%s %d: ", version, type_s, len); if (ttl != 255) printf("[ttl=%d!] ", ttl); if (version != 2 || type != 1) return; PACKET_HAS_SPACE_OR_TRUNC(bp, 6); printf("vhid=%d advbase=%d advskew=%d authlen=%d ", bp[1], bp[5], bp[2], bp[3]); if (vflag) { struct cksum_vec vec[1]; vec[0].ptr = (packetbody_t)bp; vec[0].len = len; if (PACKET_HAS_SPACE(bp, len) && in_cksum(vec, 1)) printf(" (bad carp cksum %x!)", EXTRACT_16BITS(&bp[6])); } printf("counter=%" PRIu64, EXTRACT_64BITS(&bp[8])); return; trunc: printf("[|carp]"); }
void rpki_rtr_print(packetbody_t pptr, register u_int len) { u_int tlen, pdu_type, pdu_len; packetbody_t tptr; __capability const rpki_rtr_pdu *pdu_header; tptr = pptr; tlen = len; if (!vflag) { printf(", RPKI-RTR"); return; } while (tlen >= sizeof(rpki_rtr_pdu)) { PACKET_HAS_SPACE_OR_TRUNC(tptr, sizeof(rpki_rtr_pdu)); pdu_header = (__capability const rpki_rtr_pdu *)tptr; pdu_type = pdu_header->pdu_type; pdu_len = EXTRACT_32BITS(pdu_header->length); /* infinite loop check */ if (!pdu_type || !pdu_len) { break; } PACKET_HAS_SPACE_OR_TRUNC(tptr, pdu_len); if (tlen < pdu_len) { goto trunc; } /* * Print the PDU. */ rpki_rtr_pdu_print(tptr, 8); tlen -= pdu_len; tptr += pdu_len; } return; trunc: printf("\n\t[|RPKI-RTR]"); }
void ipx_sap_print(__capability const u_short *ipx, u_int length) { int command, i; PACKET_HAS_ONE_OR_TRUNC(ipx); command = EXTRACT_16BITS(ipx); ipx++; length -= 2; switch (command) { case 1: case 3: if (command == 1) (void)printf("ipx-sap-req"); else (void)printf("ipx-sap-nearest-req"); PACKET_HAS_ONE_OR_TRUNC(ipx); (void)printf(" %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); break; case 2: case 4: if (command == 2) (void)printf("ipx-sap-resp"); else (void)printf("ipx-sap-nearest-resp"); for (i = 0; i < 8 && length > 0; i++) { PACKET_HAS_ONE_OR_TRUNC(ipx); (void)printf(" %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); if (fn_printzp((packetbody_t)&ipx[1], 48, snapend)) { printf("'"); goto trunc; } PACKET_HAS_SPACE_OR_TRUNC(ipx, (2 * 25) + 10); printf("' addr %s", ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (packetbody_t)&ipx[27])); ipx += 32; length -= 64; } break; default: (void)printf("ipx-sap-?%x", command); break; } return; trunc: printf("[|ipx %d]", length); }
static void print_attr_string(packetbody_t data, u_int length, u_short attr_code ) { register u_int i; PACKET_HAS_SPACE_OR_TRUNC(data,length); switch(attr_code) { case TUNNEL_PASS: if (length < 3) { printf(" [|radius]"); return; } if (*data && (*data <=0x1F) ) printf("Tag %u, ",*data); data++; length--; printf("Salt %u ",EXTRACT_16BITS(data) ); data+=2; length-=2; break; case TUNNEL_CLIENT_END: case TUNNEL_SERVER_END: case TUNNEL_PRIV_GROUP: case TUNNEL_ASSIGN_ID: case TUNNEL_CLIENT_AUTH: case TUNNEL_SERVER_AUTH: if (*data <= 0x1F) { if (length < 1) { printf(" [|radius]"); return; } printf("Tag %u",*data); data++; length--; } break; } for (i=0; *data && i < length ; i++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); return; trunc: printf(" [|radius]"); }
void ipx_rip_print(__capability const u_short *ipx, u_int length) { int command, i; PACKET_HAS_ONE_OR_TRUNC(ipx); command = EXTRACT_16BITS(ipx); ipx++; length -= 2; switch (command) { case 1: (void)printf("ipx-rip-req"); if (length > 0) { PACKET_HAS_SPACE_OR_TRUNC(ipx, 8); (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); } break; case 2: (void)printf("ipx-rip-resp"); for (i = 0; i < 50 && length > 0; i++) { PACKET_HAS_SPACE_OR_TRUNC(ipx, 8); (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); ipx += 4; length -= 8; } break; default: (void)printf("ipx-rip-?%x", command); break; } return; trunc: printf("[|ipx %d]", length); }
void radius_print(packetbody_t dat, u_int length) { __capability const struct radius_hdr *rad; u_int len, auth_idx; PACKET_HAS_SPACE_OR_TRUNC(dat, MIN_RADIUS_LEN); rad = (__capability struct radius_hdr *)dat; len = EXTRACT_16BITS(&rad->len); if (len < MIN_RADIUS_LEN) { printf(" [|radius]"); return; } if (len > length) len = length; if (vflag < 1) { printf("RADIUS, %s (%u), id: 0x%02x length: %u", tok2str(radius_command_values,"Unknown Command",rad->code), rad->code, rad->id, len); return; } else { printf("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", len, tok2str(radius_command_values,"Unknown Command",rad->code), rad->code, rad->id); for(auth_idx=0; auth_idx < 16; auth_idx++) printf("%02x", rad->auth[auth_idx] ); } if (len > MIN_RADIUS_LEN) radius_attrs_print( dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN); return; trunc: printf(" [|radius]"); }
static void print_attr_time(packetbody_t data, u_int length, u_short attr_code _U_) { time_t attr_time; char string[26]; if (length != 4) { printf("ERROR: length %u != 4", length); return; } PACKET_HAS_SPACE_OR_TRUNC(data,4); attr_time = EXTRACT_32BITS(data); strlcpy(string, ctime(&attr_time), sizeof(string)); /* Get rid of the newline */ string[24] = '\0'; printf("%.24s", string); return; trunc: printf(" [|radius]"); }
/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ static void handle_ctrl_proto(u_int proto, packetbody_t pptr, int length) { const char *typestr; u_int code, len; int (*pfunc)(packetbody_t, int); int x, j; packetbody_t tptr; tptr=pptr; typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto); printf("%s, ",typestr); if (length < 4) /* FIXME weak boundary checking */ goto trunc; PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); code = *tptr++; printf("%s (0x%02x), id %u, length %u", tok2str(cpcodes, "Unknown Opcode",code), code, *tptr++, /* ID */ length+2); if (!vflag) return; if (length <= 4) return; /* there may be a NULL confreq etc. */ PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); len = EXTRACT_16BITS(tptr); tptr += 2; printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4); if (vflag>1) print_unknown_data(PACKET_SUBTRACT(pptr,2), "\n\t", 6); switch (code) { case CPCODES_VEXT: if (length < 11) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); tptr += 4; PACKET_HAS_SPACE_OR_TRUNC(tptr, 3); printf(" Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), EXTRACT_24BITS(tptr)); /* XXX: need to decode Kind and Value(s)? */ break; case CPCODES_CONF_REQ: case CPCODES_CONF_ACK: case CPCODES_CONF_NAK: case CPCODES_CONF_REJ: x = len - 4; /* Code(1), Identifier(1) and Length(2) */ do { switch (proto) { case PPP_LCP: pfunc = print_lcp_config_options; break; case PPP_IPCP: pfunc = print_ipcp_config_options; break; case PPP_IPV6CP: pfunc = print_ip6cp_config_options; break; case PPP_CCP: pfunc = print_ccp_config_options; break; case PPP_BACP: pfunc = print_bacp_config_options; break; default: /* * No print routine for the options for * this protocol. */ pfunc = NULL; break; } if (pfunc == NULL) /* catch the above null pointer if unknown CP */ break; if ((j = (*pfunc)(tptr, len)) == 0) break; x -= j; tptr += j; } while (x > 0); break; case CPCODES_TERM_REQ: case CPCODES_TERM_ACK: /* XXX: need to decode Data? */ break; case CPCODES_CODE_REJ: /* XXX: need to decode Rejected-Packet? */ break; case CPCODES_PROT_REJ: if (length < 6) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); printf("\n\t Rejected %s Protocol (0x%04x)", tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), EXTRACT_16BITS(tptr)); /* XXX: need to decode Rejected-Information? - hexdump for now */ if (len > 6) { printf("\n\t Rejected Packet"); print_unknown_data(tptr+2,"\n\t ",len-2); } break; case CPCODES_ECHO_REQ: case CPCODES_ECHO_RPL: case CPCODES_DISC_REQ: if (length < 8) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); /* XXX: need to decode Data? - hexdump for now */ if (len > 8) { printf("\n\t -----trailing data-----"); PACKET_HAS_SPACE_OR_TRUNC(tptr, 4 + len-8); print_unknown_data(tptr+4,"\n\t ",len-8); } break; case CPCODES_ID: if (length < 8) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); /* RFC 1661 says this is intended to be human readable */ if (len > 8) { printf("\n\t Message\n\t "); fn_printn(tptr+4,len-4,snapend); } break; case CPCODES_TIME_REM: if (length < 12) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); PACKET_HAS_SPACE_OR_TRUNC(tptr, 8); printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)); /* XXX: need to decode Message? */ break; default: /* XXX this is dirty but we do not get the * original pointer passed to the begin * the PPP packet */ if (vflag <= 1) print_unknown_data(PACKET_SUBTRACT(pptr, 2), "\n\t ", length+2); break; } return; trunc: printf("[|%s]", typestr); }
static void print_attr_num(packetbody_t data, u_int length, u_short attr_code ) { u_int8_t tag; u_int32_t timeout; if (length != 4) { printf("ERROR: length %u != 4", length); return; } PACKET_HAS_SPACE_OR_TRUNC(data,4); /* This attribute has standard values */ if (attr_type[attr_code].siz_subtypes) { static const char **table; u_int32_t data_value; table = attr_type[attr_code].subtypes; if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) { if (!*data) printf("Tag[Unused]"); else printf("Tag[%d]", *data); data++; data_value = EXTRACT_24BITS(data); } else { data_value = EXTRACT_32BITS(data); } if ( data_value <= (u_int32_t)(attr_type[attr_code].siz_subtypes - 1 + attr_type[attr_code].first_subtype) && data_value >= attr_type[attr_code].first_subtype ) printf("%s",table[data_value]); else printf("#%u",data_value); } else { switch(attr_code) /* Be aware of special cases... */ { case FRM_IPX: if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) printf("NAS Select"); else printf("%d",EXTRACT_32BITS( data) ); break; case SESSION_TIMEOUT: case IDLE_TIMEOUT: case ACCT_DELAY: case ACCT_SESSION_TIME: case ACCT_INT_INTERVAL: timeout = EXTRACT_32BITS( data); if ( timeout < 60 ) printf( "%02d secs", timeout); else { if ( timeout < 3600 ) printf( "%02d:%02d min", timeout / 60, timeout % 60); else printf( "%02d:%02d:%02d hours", timeout / 3600, (timeout % 3600) / 60, timeout % 60); } break; case FRM_ATALK_LINK: if (EXTRACT_32BITS(data) ) printf("%d",EXTRACT_32BITS(data) ); else printf("Unnumbered" ); break; case FRM_ATALK_NETWORK: if (EXTRACT_32BITS(data) ) printf("%d",EXTRACT_32BITS(data) ); else printf("NAS assigned" ); break; case TUNNEL_PREFERENCE: tag = *data; data++; if (tag == 0) printf("Tag (Unused) %d",EXTRACT_24BITS(data) ); else printf("Tag (%d) %d", tag, EXTRACT_24BITS(data) ); break; default: printf("%d",EXTRACT_32BITS( data) ); break; } /* switch */ } /* if-else */ return; trunc: printf(" [|radius]"); }
static void krb4_print(packetbody_t cp) { __capability const struct krb *kp; u_char type; u_short len; #define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc /* True if struct krb is little endian */ #define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) #define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) kp = (__capability const struct krb *)cp; if (!PACKET_HAS_ELEMENT(kp, type)) { fputs(tstr, stdout); return; } type = kp->type & (0xFF << 1); printf(" %s %s: ", IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type)); switch (type) { case AUTH_MSG_KDC_REQUEST: if ((cp = krb4_print_hdr(cp)) == NULL) return; cp += 4; /* ctime */ PACKET_HAS_ONE_OR_TRUNC(cp); printf(" %dmin ", *cp++ * 5); PRINT; putchar('.'); PRINT; break; case AUTH_MSG_APPL_REQUEST: cp += 2; PACKET_HAS_ONE_OR_TRUNC(cp); printf("v%d ", *cp++); PRINT; PACKET_HAS_ONE_OR_TRUNC(cp); printf(" (%d)", *cp++); PACKET_HAS_ONE_OR_TRUNC(cp); printf(" (%d)", *cp); break; case AUTH_MSG_KDC_REPLY: if ((cp = krb4_print_hdr(cp)) == NULL) return; cp += 10; /* timestamp + n + exp + kvno */ PACKET_HAS_SPACE_OR_TRUNC(cp, sizeof(short)); len = KTOHSP(kp, cp); printf(" (%d)", len); break; case AUTH_MSG_ERR_REPLY: if ((cp = krb4_print_hdr(cp)) == NULL) return; cp += 4; /* timestamp */ PACKET_HAS_SPACE_OR_TRUNC(cp, sizeof(short)); printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp))); cp += 4; PRINT; break; default: fputs("(unknown)", stdout); break; } return; trunc: fputs(tstr, stdout); }
static int juniper_parse_header (packetbody_t p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) { struct juniper_cookie_table_t *lp = juniper_cookie_table; u_int idx, jnx_ext_len, jnx_header_len = 0; u_int8_t tlv_type,tlv_len; u_int32_t control_word; int tlv_value; packetbody_t tptr; l2info->header_len = 0; l2info->cookie_len = 0; l2info->proto = 0; l2info->length = h->len; l2info->caplen = h->caplen; PACKET_HAS_SPACE_OR_TRUNC(p,4); l2info->flags = p[3]; l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ printf("no magic-number found!"); return 0; } if (eflag) /* print direction */ printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); /* magic number + flags */ jnx_header_len = 4; if (vflag>1) printf("\n\tJuniper PCAP Flags [%s]", bittok2str(jnx_flag_values, "none", l2info->flags)); /* extensions present ? - calculate how much bytes to skip */ if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { tptr = p+jnx_header_len; /* ok to read extension length ? */ PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); jnx_ext_len = EXTRACT_16BITS(tptr); jnx_header_len += 2; tptr +=2; /* nail up the total length - * just in case something goes wrong * with TLV parsing */ jnx_header_len += jnx_ext_len; if (vflag>1) printf(", PCAP Extension(s) total length %u", jnx_ext_len); PACKET_HAS_SPACE_OR_TRUNC(tptr, jnx_ext_len); while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) { tlv_type = *(tptr++); tlv_len = *(tptr++); tlv_value = 0; /* sanity check */ if (tlv_type == 0 || tlv_len == 0) break; if (vflag>1) printf("\n\t %s Extension TLV #%u, length %u, value ", tok2str(jnx_ext_tlv_values,"Unknown",tlv_type), tlv_type, tlv_len); tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len); switch (tlv_type) { case JUNIPER_EXT_TLV_IFD_NAME: /* FIXME */ break; case JUNIPER_EXT_TLV_IFD_MEDIATYPE: case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE: if (tlv_value != -1) { if (vflag>1) printf("%s (%u)", tok2str(juniper_ifmt_values, "Unknown", tlv_value), tlv_value); } break; case JUNIPER_EXT_TLV_IFL_ENCAPS: case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS: if (tlv_value != -1) { if (vflag>1) printf("%s (%u)", tok2str(juniper_ifle_values, "Unknown", tlv_value), tlv_value); } break; case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */ case JUNIPER_EXT_TLV_IFL_UNIT: case JUNIPER_EXT_TLV_IFD_IDX: default: if (tlv_value != -1) { if (vflag>1) printf("%u",tlv_value); } break; } tptr+=tlv_len; jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD; } if (vflag>1) printf("\n\t-----original packet-----\n\t"); } if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { if (eflag) printf("no-L2-hdr, "); /* there is no link-layer present - * perform the v4/v6 heuristics * to figure out what it is */ PACKET_HAS_SPACE_OR_TRUNC(p, (jnx_header_len+4) + 1); if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0) printf("no IP-hdr found!"); l2info->header_len=jnx_header_len+4; return 0; /* stop parsing the output further */ } l2info->header_len = jnx_header_len; p+=l2info->header_len; l2info->length -= l2info->header_len; l2info->caplen -= l2info->header_len; /* search through the cookie table and copy values matching for our PIC type */ while (lp->s != NULL) { if (lp->pictype == l2info->pictype) { l2info->cookie_len += lp->cookie_len; switch (p[0]) { case LS_COOKIE_ID: l2info->cookie_type = LS_COOKIE_ID; l2info->cookie_len += 2; break; case AS_COOKIE_ID: l2info->cookie_type = AS_COOKIE_ID; l2info->cookie_len = 8; break; default: l2info->bundle = l2info->cookie[0]; break; } #ifdef DLT_JUNIPER_MFR /* MFR child links don't carry cookies */ if (l2info->pictype == DLT_JUNIPER_MFR && (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { l2info->cookie_len = 0; } #endif l2info->header_len += l2info->cookie_len; l2info->length -= l2info->cookie_len; l2info->caplen -= l2info->cookie_len; if (eflag) printf("%s-PIC, cookie-len %u", lp->s, l2info->cookie_len); if (l2info->cookie_len > 0) { PACKET_HAS_SPACE_OR_TRUNC(p,l2info->cookie_len); if (eflag) printf(", cookie 0x"); for (idx = 0; idx < l2info->cookie_len; idx++) { l2info->cookie[idx] = p[idx]; /* copy cookie data */ if (eflag) printf("%02x",p[idx]); } } if (eflag) printf(": "); /* print demarc b/w L2/L3*/ l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); break; } ++lp; } p+=l2info->cookie_len; /* DLT_ specific parsing */ switch(l2info->pictype) { #ifdef DLT_JUNIPER_MLPPP case DLT_JUNIPER_MLPPP: switch (l2info->cookie_type) { case LS_COOKIE_ID: l2info->bundle = l2info->cookie[1]; break; case AS_COOKIE_ID: l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff; l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: l2info->bundle = l2info->cookie[0]; break; } break; #endif #ifdef DLT_JUNIPER_MLFR case DLT_JUNIPER_MLFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: l2info->bundle = l2info->cookie[1]; l2info->proto = EXTRACT_16BITS(p); l2info->header_len += 2; l2info->length -= 2; l2info->caplen -= 2; break; case AS_COOKIE_ID: l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff; l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: l2info->bundle = l2info->cookie[0]; l2info->header_len += 2; l2info->length -= 2; l2info->caplen -= 2; break; } break; #endif #ifdef DLT_JUNIPER_MFR case DLT_JUNIPER_MFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: l2info->bundle = l2info->cookie[1]; l2info->proto = EXTRACT_16BITS(p); l2info->header_len += 2; l2info->length -= 2; l2info->caplen -= 2; break; case AS_COOKIE_ID: l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff; l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: l2info->bundle = l2info->cookie[0]; break; } break; #endif #ifdef DLT_JUNIPER_ATM2 case DLT_JUNIPER_ATM2: PACKET_HAS_SPACE_OR_TRUNC(p,4); /* ATM cell relay control word present ? */ if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { control_word = EXTRACT_32BITS(p); /* some control word heuristics */ switch(control_word) { case 0: /* zero control word */ case 0x08000000: /* < JUNOS 7.4 control-word */ case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/ l2info->header_len += 4; break; default: break; } if (eflag) printf("control-word 0x%08x ", control_word); } break; #endif #ifdef DLT_JUNIPER_GGSN case DLT_JUNIPER_GGSN: break; #endif #ifdef DLT_JUNIPER_ATM1 case DLT_JUNIPER_ATM1: break; #endif #ifdef DLT_JUNIPER_PPP case DLT_JUNIPER_PPP: break; #endif #ifdef DLT_JUNIPER_CHDLC case DLT_JUNIPER_CHDLC: break; #endif #ifdef DLT_JUNIPER_ETHER case DLT_JUNIPER_ETHER: break; #endif #ifdef DLT_JUNIPER_FRELAY case DLT_JUNIPER_FRELAY: break; #endif default: printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); break; } if (eflag > 1) printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); return 1; /* everything went ok so far. continue parsing */ trunc: printf("[|juniper_hdr], length %u",h->len); return 0; }
void syslog_print(packetbody_t pptr, register u_int len) { u_int16_t msg_off = 0; u_int16_t pri = 0; u_int16_t facility,severity; /* extract decimal figures that are * encapsulated within < > tags * based on this decimal figure extract the * severity and facility values */ if (!PACKET_HAS_SPACE(pptr, 1)) goto trunc; if (*(pptr+msg_off) == '<') { msg_off++; PACKET_HAS_SPACE_OR_TRUNC(pptr, msg_off + 1); while ( *(pptr+msg_off) >= '0' && *(pptr+msg_off) <= '9' && msg_off <= SYSLOG_MAX_DIGITS) { PACKET_HAS_SPACE_OR_TRUNC(pptr, msg_off + 1); pri = pri * 10 + (*(pptr+msg_off) - '0'); msg_off++; PACKET_HAS_SPACE_OR_TRUNC(pptr, msg_off + 1); if (*(pptr+msg_off) == '>') msg_off++; } } else { printf("[|syslog]"); return; } facility = (pri & SYSLOG_FACILITY_MASK) >> 3; severity = pri & SYSLOG_SEVERITY_MASK; if (vflag < 1 ) { printf("SYSLOG %s.%s, length: %u", tok2str(syslog_facility_values, "unknown (%u)", facility), tok2str(syslog_severity_values, "unknown (%u)", severity), len); return; } printf("SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ", len, tok2str(syslog_facility_values, "unknown (%u)", facility), facility, tok2str(syslog_severity_values, "unknown (%u)", severity), severity); /* print the syslog text in verbose mode */ for (; msg_off < len; msg_off++) { PACKET_HAS_SPACE_OR_TRUNC(pptr, msg_off + 1); safeputchar(*(pptr+msg_off)); } if (vflag > 1) { if(!print_unknown_data(pptr,"\n\t",len)) return; } return; trunc: printf("[|syslog]"); }
int snap_print(packetbody_t p, u_int length, u_int caplen, u_int bridge_pad) { u_int32_t orgcode; register u_short et; register int ret; PACKET_HAS_SPACE_OR_TRUNC(p, 5); orgcode = EXTRACT_24BITS(p); et = EXTRACT_16BITS(p + 3); if (eflag) { const struct tok *tok = null_values; const struct oui_tok *otp; for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { if (otp->oui == orgcode) { tok = otp->tok; break; } } (void)printf("oui %s (0x%06x), %s %s (0x%04x): ", tok2str(oui_values, "Unknown", orgcode), orgcode, (orgcode == 0x000000 ? "ethertype" : "pid"), tok2str(tok, "Unknown", et), et); } p += 5; length -= 5; caplen -= 5; switch (orgcode) { case OUI_ENCAP_ETHER: case OUI_CISCO_90: /* * This is an encapsulated Ethernet packet, * or a packet bridged by some piece of * Cisco hardware; the protocol ID is * an Ethernet protocol type. */ ret = ethertype_print(gndo, et, p, length, caplen); if (ret) return (ret); break; case OUI_APPLETALK: if (et == ETHERTYPE_ATALK) { /* * No, I have no idea why Apple used one * of their own OUIs, rather than * 0x000000, and an Ethernet packet * type, for Appletalk data packets, * but used 0x000000 and an Ethernet * packet type for AARP packets. */ ret = ethertype_print(gndo, et, p, length, caplen); if (ret) return (ret); } break; case OUI_CISCO: switch (et) { case PID_CISCO_CDP: cdp_print(p, length, caplen); return (1); case PID_CISCO_DTP: dtp_print(p, length); return (1); case PID_CISCO_UDLD: udld_print(p, length); return (1); case PID_CISCO_VTP: vtp_print(p, length); return (1); case PID_CISCO_PVST: stp_print(p, length); return (1); default: break; } case OUI_RFC2684: switch (et) { case PID_RFC2684_ETH_FCS: case PID_RFC2684_ETH_NOFCS: /* * XXX - remove the last two bytes for * PID_RFC2684_ETH_FCS? */ /* * Skip the padding. */ PACKET_HAS_SPACE_OR_TRUNC(p, bridge_pad); caplen -= bridge_pad; length -= bridge_pad; p += bridge_pad; /* * What remains is an Ethernet packet. */ ether_print(gndo, p, length, caplen, NULL, NULL); return (1); case PID_RFC2684_802_5_FCS: case PID_RFC2684_802_5_NOFCS: /* * XXX - remove the last two bytes for * PID_RFC2684_ETH_FCS? */ /* * Skip the padding, but not the Access * Control field. */ PACKET_HAS_SPACE_OR_TRUNC(p, bridge_pad); caplen -= bridge_pad; length -= bridge_pad; p += bridge_pad; /* * What remains is an 802.5 Token Ring * packet. */ token_print(p, length, caplen); return (1); case PID_RFC2684_FDDI_FCS: case PID_RFC2684_FDDI_NOFCS: /* * XXX - remove the last two bytes for * PID_RFC2684_ETH_FCS? */ /* * Skip the padding. */ PACKET_HAS_SPACE_OR_TRUNC(p, bridge_pad + 1); caplen -= bridge_pad + 1; length -= bridge_pad + 1; p += bridge_pad + 1; /* * What remains is an FDDI packet. */ fddi_print(p, length, caplen); return (1); case PID_RFC2684_BPDU: stp_print(p, length); return (1); } } return (0); trunc: (void)printf("[|snap]"); return (1); }
/* * Mobility Header */ int mobility_print(packetbody_t bp, packetbody_t bp2 _U_) { __capability const struct ip6_mobility *mh; int mhlen, hlen, type; mh = (__capability const struct ip6_mobility *)bp; if (!PACKET_HAS_ELEMENT(mh, ip6m_len)) { /* * There's not enough captured data to include the * mobility header length. * * Our caller expects us to return the length, however, * so return a value that will run to the end of the * captured data. * * XXX - "ip6_print()" doesn't do anything with the * returned length, however, as it breaks out of the * header-processing loop. */ mhlen = PACKET_REMAINING(bp); goto trunc; } mhlen = (int)((mh->ip6m_len + 1) << 3); /* XXX ip6m_cksum */ PACKET_HAS_ELEMENT_OR_TRUNC(mh, ip6m_type); type = mh->ip6m_type; switch (type) { case IP6M_BINDING_REQUEST: printf("mobility: BRR"); hlen = IP6M_MINLEN; break; case IP6M_HOME_TEST_INIT: case IP6M_CAREOF_TEST_INIT: printf("mobility: %soTI", type == IP6M_HOME_TEST_INIT ? "H" : "C"); hlen = IP6M_MINLEN; if (vflag) { PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 8); printf(" %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of", EXTRACT_32BITS(&bp[hlen]), EXTRACT_32BITS(&bp[hlen + 4])); } hlen += 8; break; case IP6M_HOME_TEST: case IP6M_CAREOF_TEST: printf("mobility: %soT", type == IP6M_HOME_TEST ? "H" : "C"); PACKET_HAS_ELEMENT_OR_TRUNC(mh, ip6m_data16[0]); printf(" nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0])); hlen = IP6M_MINLEN; if (vflag) { PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 8); printf(" %s Init Cookie=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", EXTRACT_32BITS(&bp[hlen]), EXTRACT_32BITS(&bp[hlen + 4])); } hlen += 8; if (vflag) { PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 8); printf(" %s Keygen Token=%08x:%08x", type == IP6M_HOME_TEST ? "Home" : "Care-of", EXTRACT_32BITS(&bp[hlen]), EXTRACT_32BITS(&bp[hlen + 4])); } hlen += 8; break; case IP6M_BINDING_UPDATE: printf("mobility: BU"); PACKET_HAS_ELEMENT_OR_TRUNC(mh, ip6m_data16[0]); printf(" seq#=%d", EXTRACT_16BITS(&mh->ip6m_data16[0])); hlen = IP6M_MINLEN; PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 1); if (bp[hlen] & 0xf0) printf(" "); if (bp[hlen] & 0x80) printf("A"); if (bp[hlen] & 0x40) printf("H"); if (bp[hlen] & 0x20) printf("L"); if (bp[hlen] & 0x10) printf("K"); /* Reserved (4bits) */ hlen += 1; /* Reserved (8bits) */ hlen += 1; PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 2); /* units of 4 secs */ printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2); hlen += 2; break; case IP6M_BINDING_ACK: printf("mobility: BA"); PACKET_HAS_ELEMENT_OR_TRUNC(mh, ip6m_data8[0]); printf(" status=%d", mh->ip6m_data8[0]); if (mh->ip6m_data8[1] & 0x80) printf(" K"); /* Reserved (7bits) */ hlen = IP6M_MINLEN; PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 2); printf(" seq#=%d", EXTRACT_16BITS(&bp[hlen])); hlen += 2; PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 2); /* units of 4 secs */ printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2); hlen += 2; break; case IP6M_BINDING_ERROR: printf("mobility: BE"); PACKET_HAS_ELEMENT_OR_TRUNC(mh, ip6m_data8[0]); printf(" status=%d", mh->ip6m_data8[0]); /* Reserved */ hlen = IP6M_MINLEN; PACKET_HAS_SPACE_OR_TRUNC(mh, hlen + 16); printf(" homeaddr %s", ip6addr_string(&bp[hlen])); hlen += 16; break; default: printf("mobility: type-#%d len=%d", type, mh->ip6m_len); return(mhlen); break; } if (vflag) mobility_opt_print(&bp[hlen], mhlen - hlen); return(mhlen); trunc: fputs("[|MOBILITY]", stdout); return(mhlen); }
static void print_attr_strange(packetbody_t data, u_int length, u_short attr_code) { u_short len_data; switch(attr_code) { case ARAP_PASS: if (length != 16) { printf("ERROR: length %u != 16", length); return; } printf("User_challenge ("); PACKET_HAS_SPACE_OR_TRUNC(data,8); len_data = 8; PRINT_HEX(len_data, data); printf(") User_resp("); PACKET_HAS_SPACE_OR_TRUNC(data,8); len_data = 8; PRINT_HEX(len_data, data); printf(")"); break; case ARAP_FEATURES: if (length != 14) { printf("ERROR: length %u != 14", length); return; } PACKET_HAS_SPACE_OR_TRUNC(data,1); if (*data) printf("User can change password"); else printf("User cannot change password"); data++; PACKET_HAS_SPACE_OR_TRUNC(data,1); printf(", Min password length: %d",*data); data++; printf(", created at: "); PACKET_HAS_SPACE_OR_TRUNC(data,4); len_data = 4; PRINT_HEX(len_data, data); printf(", expires in: "); PACKET_HAS_SPACE_OR_TRUNC(data,4); len_data = 4; PRINT_HEX(len_data, data); printf(", Current Time: "); PACKET_HAS_SPACE_OR_TRUNC(data,4); len_data = 4; PRINT_HEX(len_data, data); break; case ARAP_CHALLENGE_RESP: if (length < 8) { printf("ERROR: length %u != 8", length); return; } PACKET_HAS_SPACE_OR_TRUNC(data,8); len_data = 8; PRINT_HEX(len_data, data); break; } return; trunc: printf(" [|radius]"); }
/* LCP config options */ static int print_lcp_config_options(packetbody_t p, int length) { int len, opt; if (length < 2) return 0; PACKET_HAS_SPACE_OR_TRUNC(p, 2); len = p[1]; opt = p[0]; if (length < len) return 0; if (len < 2) { if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len); else printf("\n\tunknown LCP option 0x%02x", opt); return 0; } if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len); else { printf("\n\tunknown LCP option 0x%02x", opt); return len; } switch (opt) { case LCPOPT_VEXT: if (len >= 6) { PACKET_HAS_SPACE_OR_TRUNC(p, 5); printf("Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), EXTRACT_24BITS(p+2)); #if 0 PACKET_HAS_SPACE_OR_TRUNC(p, 6); printf(", kind: 0x%02x", p[5]); printf(", Value: 0x") for (i = 0; i < len - 6; i++) { PACKET_HAS_SPACE_OR_TRUNC(p, 1 + 6 + i); printf("%02x", p[6 + i]); } #endif } break; case LCPOPT_MRU: if (len == 4) { PACKET_HAS_SPACE_OR_TRUNC(p, 4); printf("%u", EXTRACT_16BITS(p + 2)); } break; case LCPOPT_ACCM: if (len == 6) { PACKET_HAS_SPACE_OR_TRUNC(p, 6); printf("0x%08x", EXTRACT_32BITS(p + 2)); } break; case LCPOPT_AP: if (len >= 4) { PACKET_HAS_SPACE_OR_TRUNC(p, 4); printf("%s", tok2str(ppptype2str,"Unknown Auth Proto (0x04x)",EXTRACT_16BITS(p+2))); switch (EXTRACT_16BITS(p+2)) { case PPP_CHAP: PACKET_HAS_SPACE_OR_TRUNC(p, 5); printf(", %s",tok2str(authalg_values,"Unknown Auth Alg %u",p[4])); break; case PPP_PAP: /* fall through */ case PPP_EAP: case PPP_SPAP: case PPP_SPAP_OLD: break; default: print_unknown_data(p,"\n\t",len); } } break; case LCPOPT_QP: if (len >= 4) { PACKET_HAS_SPACE_OR_TRUNC(p, 4); if (EXTRACT_16BITS(p+2) == PPP_LQM) printf(" LQR"); else printf(" unknown"); } break; case LCPOPT_MN: if (len == 6) { PACKET_HAS_SPACE_OR_TRUNC(p, 6); printf("0x%08x", EXTRACT_32BITS(p + 2)); } break; case LCPOPT_PFC: break; case LCPOPT_ACFC: break; case LCPOPT_LD: if (len == 4) { PACKET_HAS_SPACE_OR_TRUNC(p, 4); printf("0x%04x", EXTRACT_16BITS(p + 2)); } break; case LCPOPT_CBACK: if (len < 3) break; PACKET_HAS_SPACE_OR_TRUNC(p, 3); printf("Callback Operation %s (%u)", tok2str(ppp_callback_values,"Unknown",p[2]), p[2]); break; case LCPOPT_MLMRRU: if (len == 4) { PACKET_HAS_SPACE_OR_TRUNC(p, 4); printf("%u", EXTRACT_16BITS(p + 2)); } break; case LCPOPT_MLED: if (len < 3) break; PACKET_HAS_SPACE_OR_TRUNC(p, 3); switch (p[2]) { /* class */ case MEDCLASS_NULL: printf("Null"); break; case MEDCLASS_LOCAL: printf("Local"); /* XXX */ break; case MEDCLASS_IPV4: if (len != 7) break; PACKET_HAS_SPACE_OR_TRUNC(p, 7); printf("IPv4 %s", ipaddr_string(p + 3)); break; case MEDCLASS_MAC: if (len != 9) break; PACKET_HAS_SPACE_OR_TRUNC(p, 9); printf("MAC %02x:%02x:%02x:%02x:%02x:%02x", p[3], p[4], p[5], p[6], p[7], p[8]); break; case MEDCLASS_MNB: printf("Magic-Num-Block"); /* XXX */ break; case MEDCLASS_PSNDN: printf("PSNDN"); /* XXX */ break; } break; /* XXX: to be supported */ #if 0 case LCPOPT_DEP6: case LCPOPT_FCSALT: case LCPOPT_SDP: case LCPOPT_NUMMODE: case LCPOPT_DEP12: case LCPOPT_DEP14: case LCPOPT_DEP15: case LCPOPT_DEP16: case LCPOPT_MLSSNHF: case LCPOPT_PROP: case LCPOPT_DCEID: case LCPOPT_MPP: case LCPOPT_LCPAOPT: case LCPOPT_COBS: case LCPOPT_PE: case LCPOPT_MLHF: case LCPOPT_I18N: case LCPOPT_SDLOS: case LCPOPT_PPPMUX: break; #endif default: if(vflag<2) print_unknown_data(&p[2],"\n\t ",len-2); break; }
/* * RFC3032: MPLS label stack encoding */ void mpls_print(packetbody_t bp, u_int length) { packetbody_t p; u_int32_t label_entry; u_int16_t label_stack_depth = 0; enum mpls_packet_type pt = PT_UNKNOWN; p = bp; printf("MPLS"); do { PACKET_HAS_SPACE_OR_TRUNC(p, sizeof(label_entry)); label_entry = EXTRACT_32BITS(p); printf("%s(label %u", (label_stack_depth && vflag) ? "\n\t" : " ", MPLS_LABEL(label_entry)); label_stack_depth++; if (vflag && MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) printf(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]); printf(", exp %u", MPLS_EXP(label_entry)); if (MPLS_STACK(label_entry)) printf(", [S]"); printf(", ttl %u)", MPLS_TTL(label_entry)); p += sizeof(label_entry); } while (!MPLS_STACK(label_entry)); /* * Try to figure out the packet type. */ switch (MPLS_LABEL(label_entry)) { case 0: /* IPv4 explicit NULL label */ case 3: /* IPv4 implicit NULL label */ pt = PT_IPV4; break; case 2: /* IPv6 explicit NULL label */ pt = PT_IPV6; break; default: /* * Generally there's no indication of protocol in MPLS label * encoding. * * However, draft-hsmit-isis-aal5mux-00.txt describes a * technique for encapsulating IS-IS and IP traffic on the * same ATM virtual circuit; you look at the first payload * byte to determine the network layer protocol, based on * the fact that * * 1) the first byte of an IP header is 0x45-0x4f * for IPv4 and 0x60-0x6f for IPv6; * * 2) the first byte of an OSI CLNP packet is 0x81, * the first byte of an OSI ES-IS packet is 0x82, * and the first byte of an OSI IS-IS packet is * 0x83; * * so the network layer protocol can be inferred from the * first byte of the packet, if the protocol is one of the * ones listed above. * * Cisco sends control-plane traffic MPLS-encapsulated in * this fashion. */ switch(*p) { case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: pt = PT_IPV4; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: pt = PT_IPV6; break; case 0x81: case 0x82: case 0x83: pt = PT_OSI; break; default: /* ok bail out - we did not figure out what it is*/ break; } } /* * Print the payload. */ if (pt == PT_UNKNOWN) { if (!suppress_default_print) default_print(p, length - (p - bp)); return; } if (vflag) printf("\n\t"); else printf(" "); switch (pt) { case PT_IPV4: ip_print(gndo, p, length - (p - bp)); break; case PT_IPV6: #ifdef INET6 ip6_print(gndo, p, length - (p - bp)); #else printf("IPv6, length: %u", length); #endif break; case PT_OSI: isoclns_print(p, length - (p - bp), length - (p - bp)); break; default: break; } return; trunc: printf("[|MPLS]"); }