void G_parser::store_opt_data(string& nc){ //all_rules[rule_pop].options = {};//is this necessary? NOT! - {""} is first element.. for(int i=0; i<nc.length(); i++){ if (nc[i]=='|'){ all_rules[rule_pop].is_optional = true; all_rules[rule_pop].opt_positions.push_back(all_rules[rule_pop].left_str.size() - 1); store_options(nc); } } }
/* * cons options into a big buffer, and then split them out into the * three separate buffers if needed. This allows us to cons up a set of * vendor options using the same routine. */ int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, int mms, struct tree_cache **options, int overload, /* Overload flags that may be set. */ int terminate, int bootpp, u_int8_t *prl, int prl_len) { unsigned char priority_list[300], buffer[4096]; int priority_len, main_buffer_size, mainbufix, bufix; int option_size, length; /* * If the client has provided a maximum DHCP message size, use * that; otherwise, if it's BOOTP, only 64 bytes; otherwise use * up to the minimum IP MTU size (576 bytes). * * XXX if a BOOTP client specifies a max message size, we will * honor it. */ if (!mms && inpacket && inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data && (inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].len >= sizeof(u_int16_t))) mms = getUShort( inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data); if (mms) main_buffer_size = mms - DHCP_FIXED_LEN; else if (bootpp) main_buffer_size = 64; else main_buffer_size = 576 - DHCP_FIXED_LEN; if (main_buffer_size > sizeof(buffer)) main_buffer_size = sizeof(buffer); /* Preload the option priority list with mandatory options. */ priority_len = 0; priority_list[priority_len++] = DHO_DHCP_MESSAGE_TYPE; priority_list[priority_len++] = DHO_DHCP_SERVER_IDENTIFIER; priority_list[priority_len++] = DHO_DHCP_LEASE_TIME; priority_list[priority_len++] = DHO_DHCP_MESSAGE; /* * If the client has provided a list of options that it wishes * returned, use it to prioritize. Otherwise, prioritize based * on the default priority list. */ if (inpacket && inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data) { int prlen = inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].len; if (prlen + priority_len > sizeof(priority_list)) prlen = sizeof(priority_list) - priority_len; memcpy(&priority_list[priority_len], inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data, prlen); priority_len += prlen; prl = priority_list; } else if (prl) { if (prl_len + priority_len > sizeof(priority_list)) prl_len = sizeof(priority_list) - priority_len; memcpy(&priority_list[priority_len], prl, prl_len); priority_len += prl_len; prl = priority_list; } else { memcpy(&priority_list[priority_len], dhcp_option_default_priority_list, sizeof_dhcp_option_default_priority_list); priority_len += sizeof_dhcp_option_default_priority_list; } /* Copy the options into the big buffer... */ option_size = store_options( buffer, (main_buffer_size - 7 + ((overload & 1) ? DHCP_FILE_LEN : 0) + ((overload & 2) ? DHCP_SNAME_LEN : 0)), options, priority_list, priority_len, main_buffer_size, (main_buffer_size + ((overload & 1) ? DHCP_FILE_LEN : 0)), terminate); /* Put the cookie up front... */ memcpy(outpacket->options, DHCP_OPTIONS_COOKIE, 4); mainbufix = 4; /* * If we're going to have to overload, store the overload option * at the beginning. If we can, though, just store the whole * thing in the packet's option buffer and leave it at that. */ if (option_size <= main_buffer_size - mainbufix) { memcpy(&outpacket->options[mainbufix], buffer, option_size); mainbufix += option_size; if (mainbufix < main_buffer_size) outpacket->options[mainbufix++] = DHO_END; length = DHCP_FIXED_NON_UDP + mainbufix; } else { outpacket->options[mainbufix++] = DHO_DHCP_OPTION_OVERLOAD; outpacket->options[mainbufix++] = 1; if (option_size > main_buffer_size - mainbufix + DHCP_FILE_LEN) outpacket->options[mainbufix++] = 3; else outpacket->options[mainbufix++] = 1; memcpy(&outpacket->options[mainbufix], buffer, main_buffer_size - mainbufix); bufix = main_buffer_size - mainbufix; length = DHCP_FIXED_NON_UDP + mainbufix; if (overload & 1) { if (option_size - bufix <= DHCP_FILE_LEN) { memcpy(outpacket->file, &buffer[bufix], option_size - bufix); mainbufix = option_size - bufix; if (mainbufix < DHCP_FILE_LEN) outpacket->file[mainbufix++] = (char)DHO_END; while (mainbufix < DHCP_FILE_LEN) outpacket->file[mainbufix++] = (char)DHO_PAD; } else { memcpy(outpacket->file, &buffer[bufix], DHCP_FILE_LEN); bufix += DHCP_FILE_LEN; } } if ((overload & 2) && option_size < bufix) { memcpy(outpacket->sname, &buffer[bufix], option_size - bufix); mainbufix = option_size - bufix; if (mainbufix < DHCP_SNAME_LEN) outpacket->file[mainbufix++] = (char)DHO_END; while (mainbufix < DHCP_SNAME_LEN) outpacket->file[mainbufix++] = (char)DHO_PAD; } } return (length); }
/* * cons options into a big buffer, and then split them out into the * three separate buffers if needed. This allows us to cons up a set of * vendor options using the same routine. */ int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, int mms, struct tree_cache **options, int overload, /* Overload flags that may be set. */ int terminate, int bootpp, u_int8_t *prl, int prl_len) { unsigned char priority_list[256]; unsigned char buffer[4096]; /* Really big buffer... */ int bufix, main_buffer_size, option_size; /* * If the client has provided a maximum DHCP message size, use * that; otherwise, if it's BOOTP, only 64 bytes; otherwise use * up to the minimum IP MTU size (576 bytes). * * XXX if a BOOTP client specifies a max message size, we will * honor it. */ if (!mms && inpacket && inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data && (inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].len >= sizeof(u_int16_t))) { mms = getUShort( inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data); } if (mms) { if (mms < 576) mms = 576; /* mms must be >= minimum IP MTU */ main_buffer_size = mms - DHCP_FIXED_LEN; } else if (bootpp) main_buffer_size = 64; else main_buffer_size = 576 - DHCP_FIXED_LEN; if (main_buffer_size > sizeof(outpacket->options)) main_buffer_size = sizeof(outpacket->options); /* * Initialize the available buffers, some or all of which may not be * used. */ memset(outpacket->options, DHO_PAD, sizeof(outpacket->options)); if (overload & 1) memset(outpacket->file, DHO_PAD, DHCP_FILE_LEN); if (overload & 2) memset(outpacket->sname, DHO_PAD, DHCP_SNAME_LEN); if (bootpp) overload = 0; /* Don't use overload buffers for bootp! */ /* * Get complete list of possible options in priority order. Use the * list provided in the options. Lacking that use the list provided by * prl. If that is not available just use the default list. */ bzero(&priority_list, sizeof(priority_list)); if (inpacket && inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data) create_priority_list(priority_list, inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data, inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].len); else if (prl) create_priority_list(priority_list, prl, prl_len); else create_priority_list(priority_list, NULL, 0); /* * Copy the options into the big buffer, including leading cookie and * DHCP_OVERLOAD_OPTION, and DHO_END if it fits. All unused space will * be set to DHO_PAD */ option_size = store_options(buffer, main_buffer_size, options, priority_list, overload, terminate); if (option_size == 0) return (DHCP_FIXED_NON_UDP); /* Copy the main buffer. */ memcpy(&outpacket->options[0], buffer, main_buffer_size); if (option_size <= main_buffer_size) return (DHCP_FIXED_NON_UDP + option_size); /* Copy the overflow buffers. */ bufix = main_buffer_size; if (overload & 1) { memcpy(outpacket->file, &buffer[bufix], DHCP_FILE_LEN); bufix += DHCP_FILE_LEN; } if (overload & 2) memcpy(outpacket->sname, &buffer[bufix], DHCP_SNAME_LEN); return (DHCP_FIXED_NON_UDP + main_buffer_size); }