/* * Function: dhcpol_get * * Purpose: * Accumulate all occurences of the given option into a * malloc'd buffer, and return its length. Used to get * all occurrences of a particular option in a single * data area. * Note: * Use _FREE(val, M_TEMP) to free the returned data area. */ void * dhcpol_get(dhcpol_t * list, int tag, int * len_p) { int i; char * data = NULL; int data_len = 0; if (tag == dhcptag_end_e || tag == dhcptag_pad_e) return (NULL); for (i = 0; i < dhcpol_count(list); i++) { unsigned char * option = dhcpol_element(list, i); if (option[DHCP_TAG_OFFSET] == tag) { int len = option[DHCP_LEN_OFFSET]; if (data_len == 0) { data = my_malloc(len); } else { data = my_realloc(data, data_len, data_len + len); } bcopy(option + DHCP_OPTION_OFFSET, data + data_len, len); data_len += len; } } *len_p = data_len; return (data); }
PRIVATE_EXTERN void bsdp_print_packet(struct dhcp * pkt, int length, int options_only) { dhcpo_err_str_t err; int i; dhcpol_t options; dhcpol_t vendor_options; dhcpol_init(&options); dhcpol_init(&vendor_options); if (options_only == 0) { dhcp_packet_print(pkt, length); } if (dhcpol_parse_packet(&options, pkt, length, &err) == FALSE) { fprintf(stderr, "packet did not parse, %s\n", err.str); return; } if (dhcpol_parse_vendor(&vendor_options, &options, &err) == FALSE) { fprintf(stderr, "vendor options did not parse, %s\n", err.str); goto done; } printf("BSDP Options count is %d\n", dhcpol_count(&vendor_options)); for (i = 0; i < dhcpol_count(&vendor_options); i++) { u_int8_t code; u_int8_t * opt = dhcpol_element(&vendor_options, i); u_int8_t len; code = opt[TAG_OFFSET]; len = opt[LEN_OFFSET]; printf("%s: ", bsdptag_name(code)); if (code == bsdptag_message_type_e) { printf("%s (", bsdp_msgtype_names(opt[OPTION_OFFSET])); dhcptype_print(bsdptag_type(code), opt + OPTION_OFFSET, len); printf(")\n"); } else { dhcptype_print(bsdptag_type(code), opt + OPTION_OFFSET, len); printf("\n"); } } done: dhcpol_free(&options); dhcpol_free(&vendor_options); return; }
/* * Function: dhcpol_find * * Purpose: * Finds the first occurence of the given option, and returns its * length and the option data pointer. * * The optional start parameter allows this function to * return the next start point so that successive * calls will retrieve the next occurence of the option. * Before the first call, *start should be set to 0. */ void * dhcpol_find(dhcpol_t * list, int tag, int * len_p, int * start) { int i = 0; if (tag == dhcptag_end_e || tag == dhcptag_pad_e) return (NULL); if (start) i = *start; for (; i < dhcpol_count(list); i++) { unsigned char * option = dhcpol_element(list, i); if (option[DHCP_TAG_OFFSET] == tag) { if (len_p) *len_p = option[DHCP_LEN_OFFSET]; if (start) *start = i + 1; return (option + DHCP_OPTION_OFFSET); } } return (NULL); }