/* * Print RRCP requests */ void rrcp_print(netdissect_options *ndo, const u_char *cp, u_int length _U_, const struct lladdr_info *src, const struct lladdr_info *dst) { uint8_t rrcp_proto; uint8_t rrcp_opcode; ndo->ndo_protocol = "rrcp"; ND_TCHECK_1(cp + RRCP_PROTO_OFFSET); rrcp_proto = EXTRACT_U_1(cp + RRCP_PROTO_OFFSET); ND_TCHECK_1(cp + RRCP_OPCODE_ISREPLY_OFFSET); rrcp_opcode = EXTRACT_U_1((cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; if (src != NULL && dst != NULL) { ND_PRINT("%s > %s, ", (src->addr_string)(ndo, src->addr), (dst->addr_string)(ndo, dst->addr)); } ND_PRINT("%s %s", tok2str(proto_values,"RRCP-0x%02x",rrcp_proto), ((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"); if (rrcp_proto==1){ ND_PRINT(": %s", tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode)); } if (rrcp_opcode==1 || rrcp_opcode==2){ ND_TCHECK_6(cp + RRCP_REG_ADDR_OFFSET); ND_PRINT(" addr=0x%04x, data=0x%08x", EXTRACT_LE_U_2(cp + RRCP_REG_ADDR_OFFSET), EXTRACT_LE_U_4(cp + RRCP_REG_DATA_OFFSET)); } if (rrcp_proto==1){ ND_TCHECK_2(cp + RRCP_AUTHKEY_OFFSET); ND_PRINT(", auth=0x%04x", EXTRACT_BE_U_2(cp + RRCP_AUTHKEY_OFFSET)); } if (rrcp_proto==1 && rrcp_opcode==0 && ((EXTRACT_U_1(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ ND_TCHECK_4(cp + RRCP_VENDOR_ID_OFFSET); ND_PRINT(" downlink_port=%u, uplink_port=%u, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", EXTRACT_U_1(cp + RRCP_DOWNLINK_PORT_OFFSET), EXTRACT_U_1(cp + RRCP_UPLINK_PORT_OFFSET), etheraddr_string(ndo, cp + RRCP_UPLINK_MAC_OFFSET), EXTRACT_BE_U_4(cp + RRCP_VENDOR_ID_OFFSET), EXTRACT_BE_U_2(cp + RRCP_CHIP_ID_OFFSET)); }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ ND_TCHECK_4(cp + RRCP_COOKIE2_OFFSET); ND_PRINT(", cookie=0x%08x%08x ", EXTRACT_BE_U_4(cp + RRCP_COOKIE2_OFFSET), EXTRACT_BE_U_4(cp + RRCP_COOKIE1_OFFSET)); } return; trunc: nd_print_trunc(ndo); }
void lwapp_data_print(netdissect_options *ndo, const u_char *pptr, u_int len) { const struct lwapp_transport_header *lwapp_trans_header; const u_char *tptr; u_int tlen; u_int version; tptr=pptr; /* check if enough bytes for AP identity */ ND_TCHECK_6(tptr); lwapp_trans_header = (const struct lwapp_transport_header *)pptr; ND_TCHECK_SIZE(lwapp_trans_header); version = EXTRACT_U_1(lwapp_trans_header->version); /* * Sanity checking of the header. */ if (LWAPP_EXTRACT_VERSION(version) != LWAPP_VERSION) { ND_PRINT("LWAPP version %u packet not supported", LWAPP_EXTRACT_VERSION(version)); return; } /* non-verbose */ if (ndo->ndo_vflag < 1) { ND_PRINT("LWAPPv%u, %s frame, Flags [%s], length %u", LWAPP_EXTRACT_VERSION(version), LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", bittok2str(lwapp_header_bits_values,"none",version&0x07), len); return; } /* ok they seem to want to know everything - lets fully decode it */ tlen=EXTRACT_BE_U_2(lwapp_trans_header->length); if (tlen < sizeof(struct lwapp_transport_header)) { ND_PRINT("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], length %u < transport header length", LWAPP_EXTRACT_VERSION(version), LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", LWAPP_EXTRACT_RID(version), bittok2str(lwapp_header_bits_values,"none",version&0x07), tlen); return; } ND_PRINT("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", LWAPP_EXTRACT_VERSION(version), LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", LWAPP_EXTRACT_RID(version), bittok2str(lwapp_header_bits_values,"none",version&0x07), EXTRACT_U_1(lwapp_trans_header->frag_id), tlen); tptr+=sizeof(struct lwapp_transport_header); tlen-=sizeof(struct lwapp_transport_header); /* FIX - An IEEE 802.11 frame follows - hexdump for now */ print_unknown_data(ndo, tptr, "\n\t", tlen); return; trunc: ND_PRINT("%s", data_tstr); }
void lwapp_control_print(netdissect_options *ndo, const u_char *pptr, u_int len, int has_ap_ident) { const struct lwapp_transport_header *lwapp_trans_header; const struct lwapp_control_header *lwapp_control_header; const u_char *tptr; uint8_t version; u_int tlen; u_int msg_type, msg_tlen; tptr=pptr; if (has_ap_ident) { /* check if enough bytes for AP identity */ ND_TCHECK_6(tptr); lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6); } else { lwapp_trans_header = (const struct lwapp_transport_header *)pptr; } ND_TCHECK_SIZE(lwapp_trans_header); version = EXTRACT_U_1(lwapp_trans_header->version); /* * Sanity checking of the header. */ if (LWAPP_EXTRACT_VERSION(version) != LWAPP_VERSION) { ND_PRINT("LWAPP version %u packet not supported", LWAPP_EXTRACT_VERSION(version)); return; } /* non-verbose */ if (ndo->ndo_vflag < 1) { ND_PRINT("LWAPPv%u, %s frame, Flags [%s], length %u", LWAPP_EXTRACT_VERSION(version), LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", bittok2str(lwapp_header_bits_values,"none",version&0x07), len); return; } /* ok they seem to want to know everything - lets fully decode it */ tlen=EXTRACT_BE_U_2(lwapp_trans_header->length); ND_PRINT("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", LWAPP_EXTRACT_VERSION(version), LWAPP_EXTRACT_CONTROL_BIT(version) ? "Control" : "Data", LWAPP_EXTRACT_RID(version), bittok2str(lwapp_header_bits_values,"none",version&0x07), EXTRACT_U_1(lwapp_trans_header->frag_id), tlen); if (has_ap_ident) { ND_PRINT("\n\tAP identity: %s", etheraddr_string(ndo, tptr)); tptr+=sizeof(struct lwapp_transport_header)+6; } else { tptr+=sizeof(struct lwapp_transport_header); } while(tlen!=0) { /* did we capture enough for fully decoding the object header ? */ ND_TCHECK_LEN(tptr, sizeof(struct lwapp_control_header)); if (tlen < sizeof(struct lwapp_control_header)) { ND_PRINT("\n\t Msg goes past end of PDU"); break; } lwapp_control_header = (const struct lwapp_control_header *)tptr; msg_tlen = EXTRACT_BE_U_2(lwapp_control_header->len); if (tlen < sizeof(struct lwapp_control_header) + msg_tlen) { ND_PRINT("\n\t Msg goes past end of PDU"); break; } /* print message header */ msg_type = EXTRACT_U_1(lwapp_control_header->msg_type); ND_PRINT("\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %u, Session: 0x%08x", tok2str(lwapp_msg_type_values,"Unknown",msg_type), msg_type, EXTRACT_U_1(lwapp_control_header->seq_num), msg_tlen, EXTRACT_BE_U_4(lwapp_control_header->session_id)); /* did we capture enough for fully decoding the message */ ND_TCHECK_LEN(tptr, msg_tlen); /* XXX - Decode sub messages for each message */ switch(msg_type) { case LWAPP_MSGTYPE_DISCOVERY_REQUEST: case LWAPP_MSGTYPE_DISCOVERY_RESPONSE: case LWAPP_MSGTYPE_JOIN_REQUEST: case LWAPP_MSGTYPE_JOIN_RESPONSE: case LWAPP_MSGTYPE_JOIN_ACK: case LWAPP_MSGTYPE_JOIN_CONFIRM: case LWAPP_MSGTYPE_CONFIGURE_REQUEST: case LWAPP_MSGTYPE_CONFIGURE_RESPONSE: case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST: case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE: case LWAPP_MSGTYPE_WTP_EVENT_REQUEST: case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE: case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST: case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE: case LWAPP_MSGTYPE_ECHO_REQUEST: case LWAPP_MSGTYPE_ECHO_RESPONSE: case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST: case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE: case LWAPP_MSGTYPE_RESET_REQUEST: case LWAPP_MSGTYPE_RESET_RESPONSE: case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST: case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE: case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST: case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE: case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST: case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE: case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION: case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST: case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE: case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST: case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE: default: break; } tptr += sizeof(struct lwapp_control_header) + msg_tlen; tlen -= sizeof(struct lwapp_control_header) + msg_tlen; } return; trunc: ND_PRINT("%s", control_tstr); }
/* * Print bootp requests */ void bootp_print(netdissect_options *ndo, const u_char *cp, u_int length) { const struct bootp *bp; static const u_char vm_cmu[4] = VM_CMU; static const u_char vm_rfc1048[4] = VM_RFC1048; uint8_t bp_op, bp_htype, bp_hlen; ndo->ndo_protocol = "bootp"; bp = (const struct bootp *)cp; ND_TCHECK_1(bp->bp_op); bp_op = EXTRACT_U_1(bp->bp_op); ND_PRINT("BOOTP/DHCP, %s", tok2str(bootp_op_values, "unknown (0x%02x)", bp_op)); ND_TCHECK_1(bp->bp_hlen); bp_htype = EXTRACT_U_1(bp->bp_htype); bp_hlen = EXTRACT_U_1(bp->bp_hlen); if (bp_htype == 1 && bp_hlen == 6 && bp_op == BOOTPREQUEST) { ND_TCHECK_6(bp->bp_chaddr); ND_PRINT(" from %s", etheraddr_string(ndo, bp->bp_chaddr)); } ND_PRINT(", length %u", length); if (!ndo->ndo_vflag) return; ND_TCHECK_2(bp->bp_secs); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp_htype != 1) ND_PRINT(", htype %u", bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp_htype != 1 || bp_hlen != 6) ND_PRINT(", hlen %u", bp_hlen); /* Only print interesting fields */ if (EXTRACT_U_1(bp->bp_hops)) ND_PRINT(", hops %u", EXTRACT_U_1(bp->bp_hops)); if (EXTRACT_BE_U_4(bp->bp_xid)) ND_PRINT(", xid 0x%x", EXTRACT_BE_U_4(bp->bp_xid)); if (EXTRACT_BE_U_2(bp->bp_secs)) ND_PRINT(", secs %u", EXTRACT_BE_U_2(bp->bp_secs)); ND_TCHECK_2(bp->bp_flags); ND_PRINT(", Flags [%s]", bittok2str(bootp_flag_values, "none", EXTRACT_BE_U_2(bp->bp_flags))); if (ndo->ndo_vflag > 1) ND_PRINT(" (0x%04x)", EXTRACT_BE_U_2(bp->bp_flags)); /* Client's ip address */ ND_TCHECK_4(bp->bp_ciaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_ciaddr)) ND_PRINT("\n\t Client-IP %s", ipaddr_string(ndo, bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ ND_TCHECK_4(bp->bp_yiaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_yiaddr)) ND_PRINT("\n\t Your-IP %s", ipaddr_string(ndo, bp->bp_yiaddr)); /* Server's ip address */ ND_TCHECK_4(bp->bp_siaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_siaddr)) ND_PRINT("\n\t Server-IP %s", ipaddr_string(ndo, bp->bp_siaddr)); /* Gateway's ip address */ ND_TCHECK_4(bp->bp_giaddr); if (EXTRACT_IPV4_TO_NETWORK_ORDER(bp->bp_giaddr)) ND_PRINT("\n\t Gateway-IP %s", ipaddr_string(ndo, bp->bp_giaddr)); /* Client's Ethernet address */ if (bp_htype == 1 && bp_hlen == 6) { ND_TCHECK_6(bp->bp_chaddr); ND_PRINT("\n\t Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr)); } ND_TCHECK_1(bp->bp_sname); /* check first char only */ if (EXTRACT_U_1(bp->bp_sname)) { ND_PRINT("\n\t sname \""); if (nd_printztn(ndo, bp->bp_sname, (u_int)sizeof(bp->bp_sname), ndo->ndo_snapend) == 0) { ND_PRINT("\""); nd_print_trunc(ndo); return; } ND_PRINT("\""); } ND_TCHECK_1(bp->bp_file); /* check first char only */ if (EXTRACT_U_1(bp->bp_file)) { ND_PRINT("\n\t file \""); if (nd_printztn(ndo, bp->bp_file, (u_int)sizeof(bp->bp_file), ndo->ndo_snapend) == 0) { ND_PRINT("\""); nd_print_trunc(ndo); return; } ND_PRINT("\""); } /* Decode the vendor buffer */ ND_TCHECK_4(bp->bp_vend); if (memcmp((const char *)bp->bp_vend, vm_rfc1048, sizeof(uint32_t)) == 0) rfc1048_print(ndo, bp->bp_vend); else if (memcmp((const char *)bp->bp_vend, vm_cmu, sizeof(uint32_t)) == 0) cmu_print(ndo, bp->bp_vend); else { uint32_t ul; ul = EXTRACT_BE_U_4(bp->bp_vend); if (ul != 0) ND_PRINT("\n\t Vendor-#0x%x", ul); } return; trunc: nd_print_trunc(ndo); }
/* LCP config options */ static u_int print_lcp_config_options(netdissect_options *ndo, const u_char *p, u_int length) { u_int opt, len; if (length < 2) return 0; ND_TCHECK_2(p); opt = EXTRACT_U_1(p); len = EXTRACT_U_1(p + 1); if (length < len) return 0; if (len < 2) { if (opt < NUM_LCPOPTS) ND_PRINT("\n\t %s Option (0x%02x), length %u (length bogus, should be >= 2)", lcpconfopts[opt], opt, len); else ND_PRINT("\n\tunknown LCP option 0x%02x", opt); return 0; } if (opt < NUM_LCPOPTS) ND_PRINT("\n\t %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len); else { ND_PRINT("\n\tunknown LCP option 0x%02x", opt); return len; } switch (opt) { case LCPOPT_VEXT: if (len < 6) { ND_PRINT(" (length bogus, should be >= 6)"); return len; } ND_TCHECK_3(p + 2); ND_PRINT(": Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_BE_U_3(p + 2)), EXTRACT_BE_U_3(p + 2)); #if 0 ND_TCHECK_1(p + 5); ND_PRINT(", kind: 0x%02x", EXTRACT_U_1(p + 5)); ND_PRINT(", Value: 0x"); for (i = 0; i < len - 6; i++) { ND_TCHECK_1(p + 6 + i); ND_PRINT("%02x", EXTRACT_U_1(p + 6 + i)); } #endif break; case LCPOPT_MRU: if (len != 4) { ND_PRINT(" (length bogus, should be = 4)"); return len; } ND_TCHECK_2(p + 2); ND_PRINT(": %u", EXTRACT_BE_U_2(p + 2)); break; case LCPOPT_ACCM: if (len != 6) { ND_PRINT(" (length bogus, should be = 6)"); return len; } ND_TCHECK_4(p + 2); ND_PRINT(": 0x%08x", EXTRACT_BE_U_4(p + 2)); break; case LCPOPT_AP: if (len < 4) { ND_PRINT(" (length bogus, should be >= 4)"); return len; } ND_TCHECK_2(p + 2); ND_PRINT(": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_BE_U_2(p + 2))); switch (EXTRACT_BE_U_2(p + 2)) { case PPP_CHAP: ND_TCHECK_1(p + 4); ND_PRINT(", %s", tok2str(authalg_values, "Unknown Auth Alg %u", EXTRACT_U_1(p + 4))); break; case PPP_PAP: /* fall through */ case PPP_EAP: case PPP_SPAP: case PPP_SPAP_OLD: break; default: print_unknown_data(ndo, p, "\n\t", len); } break; case LCPOPT_QP: if (len < 4) { ND_PRINT(" (length bogus, should be >= 4)"); return 0; } ND_TCHECK_2(p + 2); if (EXTRACT_BE_U_2(p + 2) == PPP_LQM) ND_PRINT(": LQR"); else ND_PRINT(": unknown"); break; case LCPOPT_MN: if (len != 6) { ND_PRINT(" (length bogus, should be = 6)"); return 0; } ND_TCHECK_4(p + 2); ND_PRINT(": 0x%08x", EXTRACT_BE_U_4(p + 2)); break; case LCPOPT_PFC: break; case LCPOPT_ACFC: break; case LCPOPT_LD: if (len != 4) { ND_PRINT(" (length bogus, should be = 4)"); return 0; } ND_TCHECK_2(p + 2); ND_PRINT(": 0x%04x", EXTRACT_BE_U_2(p + 2)); break; case LCPOPT_CBACK: if (len < 3) { ND_PRINT(" (length bogus, should be >= 3)"); return 0; } ND_PRINT(": "); ND_TCHECK_1(p + 2); ND_PRINT(": Callback Operation %s (%u)", tok2str(ppp_callback_values, "Unknown", EXTRACT_U_1(p + 2)), EXTRACT_U_1(p + 2)); break; case LCPOPT_MLMRRU: if (len != 4) { ND_PRINT(" (length bogus, should be = 4)"); return 0; } ND_TCHECK_2(p + 2); ND_PRINT(": %u", EXTRACT_BE_U_2(p + 2)); break; case LCPOPT_MLED: if (len < 3) { ND_PRINT(" (length bogus, should be >= 3)"); return 0; } ND_TCHECK_1(p + 2); switch (EXTRACT_U_1(p + 2)) { /* class */ case MEDCLASS_NULL: ND_PRINT(": Null"); break; case MEDCLASS_LOCAL: ND_PRINT(": Local"); /* XXX */ break; case MEDCLASS_IPV4: if (len != 7) { ND_PRINT(" (length bogus, should be = 7)"); return 0; } ND_TCHECK_4(p + 3); ND_PRINT(": IPv4 %s", ipaddr_string(ndo, p + 3)); break; case MEDCLASS_MAC: if (len != 9) { ND_PRINT(" (length bogus, should be = 9)"); return 0; } ND_TCHECK_6(p + 3); ND_PRINT(": MAC %s", etheraddr_string(ndo, p + 3)); break; case MEDCLASS_MNB: ND_PRINT(": Magic-Num-Block"); /* XXX */ break; case MEDCLASS_PSNDN: ND_PRINT(": PSNDN"); /* XXX */ break; default: ND_PRINT(": Unknown class %u", EXTRACT_U_1(p + 2)); 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: /* * Unknown option; dump it as raw bytes now if we're * not going to do so below. */ if (ndo->ndo_vflag < 2) print_unknown_data(ndo, p + 2, "\n\t ", len - 2); break; } if (ndo->ndo_vflag > 1) print_unknown_data(ndo, p + 2, "\n\t ", len - 2); /* exclude TLV header */ return len; trunc: ND_PRINT("[|lcp]"); return 0; }