📄 options.c
字号:
} return status;}int fqdn_option_space_encapsulate (result, packet, lease, client_state, in_options, cfg_options, scope, universe) struct data_string *result; struct packet *packet; struct lease *lease; struct client_state *client_state; struct option_state *in_options; struct option_state *cfg_options; struct binding_scope **scope; struct universe *universe;{ pair ocp; struct data_string results [FQDN_SUBOPTION_COUNT + 1]; unsigned i; unsigned len; struct buffer *bp = (struct buffer *)0; struct option_chain_head *head; /* If there's no FQDN universe, don't encapsulate. */ if (fqdn_universe.index >= cfg_options -> universe_count) return 0; head = ((struct option_chain_head *) cfg_options -> universes [fqdn_universe.index]); if (!head) return 0; /* Figure out the values of all the suboptions. */ memset (results, 0, sizeof results); for (ocp = head -> first; ocp; ocp = ocp -> cdr) { struct option_cache *oc = (struct option_cache *)(ocp -> car); if (oc -> option -> code > FQDN_SUBOPTION_COUNT) continue; evaluate_option_cache (&results [oc -> option -> code], packet, lease, client_state, in_options, cfg_options, scope, oc, MDL); } len = 4 + results [FQDN_FQDN].len; /* Save the contents of the option in a buffer. */ if (!buffer_allocate (&bp, len, MDL)) { log_error ("no memory for option buffer."); return 0; } buffer_reference (&result -> buffer, bp, MDL); result -> len = 3; result -> data = &bp -> data [0]; memset (&bp -> data [0], 0, len); if (results [FQDN_NO_CLIENT_UPDATE].len && results [FQDN_NO_CLIENT_UPDATE].data [0]) bp -> data [0] |= 2; if (results [FQDN_SERVER_UPDATE].len && results [FQDN_SERVER_UPDATE].data [0]) bp -> data [0] |= 1; if (results [FQDN_RCODE1].len) bp -> data [1] = results [FQDN_RCODE1].data [0]; if (results [FQDN_RCODE2].len) bp -> data [2] = results [FQDN_RCODE2].data [0]; if (results [FQDN_ENCODED].len && results [FQDN_ENCODED].data [0]) { unsigned char *out; int i; bp -> data [0] |= 4; out = &bp -> data [3]; if (results [FQDN_FQDN].len) { i = 0; while (i < results [FQDN_FQDN].len) { int j; for (j = i; ('.' != results [FQDN_FQDN].data [j]) && j < results [FQDN_FQDN].len; j++) ; *out++ = j - i; memcpy (out, &results [FQDN_FQDN].data [i], (unsigned)(j - i)); out += j - i; i = j; if (results [FQDN_FQDN].data [j] == '.') i++; } if ((results [FQDN_FQDN].data [results [FQDN_FQDN].len - 1] == '.')) *out++ = 0; result -> len = out - result -> data; result -> terminated = 0; } } else { if (results [FQDN_FQDN].len) { memcpy (&bp -> data [3], results [FQDN_FQDN].data, results [FQDN_FQDN].len); result -> len += results [FQDN_FQDN].len; result -> terminated = 0; } } for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) { if (results [i].len) data_string_forget (&results [i], MDL); } buffer_dereference (&bp, MDL); return 1;}void option_space_foreach (struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void (*func) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)){ if (u -> foreach) (*u -> foreach) (packet, lease, client_state, in_options, cfg_options, scope, u, stuff, func);}void suboption_foreach (struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void (*func) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *), struct option_cache *oc, const char *vsname){ struct universe *universe = find_option_universe (oc -> option, vsname); int i; if (universe -> foreach) (*universe -> foreach) (packet, lease, client_state, in_options, cfg_options, scope, universe, stuff, func);}void hashed_option_space_foreach (struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void (*func) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)){ pair *hash; int i; struct option_cache *oc; if (cfg_options -> universe_count <= u -> index) return; hash = cfg_options -> universes [u -> index]; if (!hash) return; for (i = 0; i < OPTION_HASH_SIZE; i++) { pair p; /* XXX save _all_ options! XXX */ for (p = hash [i]; p; p = p -> cdr) { oc = (struct option_cache *)p -> car; (*func) (oc, packet, lease, client_state, in_options, cfg_options, scope, u, stuff); } }}void save_linked_option (universe, options, oc) struct universe *universe; struct option_state *options; struct option_cache *oc;{ pair *tail; pair np = (pair )0; struct option_chain_head *head; if (universe -> index >= options -> universe_count) return; head = ((struct option_chain_head *) options -> universes [universe -> index]); if (!head) { if (!option_chain_head_allocate (((struct option_chain_head **) &options -> universes [universe -> index]), MDL)) return; head = ((struct option_chain_head *) options -> universes [universe -> index]); } /* Find the tail of the list. */ for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) { if (oc -> option == ((struct option_cache *)((*tail) -> car)) -> option) { option_cache_dereference ((struct option_cache **) (&(*tail) -> car), MDL); option_cache_reference ((struct option_cache **) (&(*tail) -> car), oc, MDL); return; } } *tail = cons (0, 0); if (*tail) { option_cache_reference ((struct option_cache **) (&(*tail) -> car), oc, MDL); }}int linked_option_space_encapsulate (result, packet, lease, client_state, in_options, cfg_options, scope, universe) struct data_string *result; struct packet *packet; struct lease *lease; struct client_state *client_state; struct option_state *in_options; struct option_state *cfg_options; struct binding_scope **scope; struct universe *universe;{ int status; pair oc; struct option_chain_head *head; if (universe -> index >= cfg_options -> universe_count) return 0; head = ((struct option_chain_head *) cfg_options -> universes [universe -> index]); if (!head) return 0; status = 0; for (oc = head -> first; oc; oc = oc -> cdr) { if (store_option (result, universe, packet, lease, client_state, in_options, cfg_options, scope, (struct option_cache *)(oc -> car))) status = 1; } return status;}void delete_linked_option (universe, options, code) struct universe *universe; struct option_state *options; int code;{ pair *tail, tmp = (pair)0; struct option_chain_head *head; if (universe -> index >= options -> universe_count) return; head = ((struct option_chain_head *) options -> universes [universe -> index]); if (!head) return; for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) { if (code == ((struct option_cache *)(*tail) -> car) -> option -> code) { tmp = (*tail) -> cdr; option_cache_dereference ((struct option_cache **) (&(*tail) -> car), MDL); dfree (*tail, MDL); (*tail) = tmp; break; } }}struct option_cache *lookup_linked_option (universe, options, code) struct universe *universe; struct option_state *options; unsigned code;{ pair oc; struct option_chain_head *head; if (universe -> index >= options -> universe_count) return 0; head = ((struct option_chain_head *) options -> universes [universe -> index]); if (!head) return 0; for (oc = head -> first; oc; oc = oc -> cdr) { if (code == ((struct option_cache *)(oc -> car)) -> option -> code) { return (struct option_cache *)(oc -> car); } } return (struct option_cache *)0;}int linked_option_state_dereference (universe, state, file, line) struct universe *universe; struct option_state *state; const char *file; int line;{ return (option_chain_head_dereference ((struct option_chain_head **) (&state -> universes [universe -> index]), MDL));}void linked_option_space_foreach (struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void (*func) (struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *)){ pair car; struct option_chain_head *head; if (u -> index >= cfg_options -> universe_count) return; head = ((struct option_chain_head *) cfg_options -> universes [u -> index]); if (!head) return; for (car = head -> first; car; car = car -> cdr) { (*func) ((struct option_cache *)(car -> car), packet, lease, client_state, in_options, cfg_options, scope, u, stuff); }}void do_packet (interface, packet, len, from_port, from, hfrom) struct interface_info *interface; struct dhcp_packet *packet; unsigned len; unsigned int from_port; struct iaddr from; struct hardware *hfrom;{ int i; struct option_cache *op; struct packet *decoded_packet;#if defined (DEBUG_MEMORY_LEAKAGE) unsigned long previous_outstanding = dmalloc_outstanding;#endif#if defined (TRACING) trace_inpacket_stash (interface, packet, len, from_port, from, hfrom);#endif decoded_packet = (struct packet *)0; if (!packet_allocate (&decoded_packet, MDL)) { log_error ("do_packet: no memory for incoming packet!"); return; } decoded_packet -> raw = packet; decoded_packet -> packet_length = len; decoded_packet -> client_port = from_port; decoded_packet -> client_addr = from; interface_reference (&decoded_packet -> interface, interface, MDL); decoded_packet -> haddr = hfrom; if (packet -> hlen > sizeof packet -> chaddr) { packet_dereference (&decoded_packet, MDL); log_info ("Discarding packet with bogus hlen."); return; } /* If there's an option buffer, try to parse it. */ if (decoded_packet -> packet_length >= DHCP_FIXED_NON_UDP + 4) { if (!parse_options (decoded_packet)) { if (decoded_packet -> options) option_state_dereference (&decoded_packet -> options, MDL); packet_dereference (&decoded_packet, MDL); return; } if (decoded_packet -> options_valid && (op = lookup_option (&dhcp_universe, decoded_packet -> options, DHO_DHCP_MESSAGE_TYPE))) { struct data_string dp; memset (&dp, 0, sizeof dp); evaluate_option_cache (&dp, decoded_packet, (struct lease *)0, (struct client_state *)0, decoded_packet -> options, (struct option_state *)0, (struct binding_scope **)0, op, MDL); if (dp.len > 0) decoded_packet -> packet_type = dp.data [0]; else decoded_packet -> packet_type = 0; data_string_forget (&dp, MDL); } } if (decoded_packet -> packet_type) dhcp (decoded_packet); else bootp (decoded_packet); /* If the caller kept the packet, they'll have upped the refcnt. */ packet_dereference (&decoded_packet, MDL);#if defined (DEBUG_MEMORY_LEAKAGE) log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term", dmalloc_generation, dmalloc_outstanding - previous_outstanding, dmalloc_outstanding, dmalloc_longterm);#endif#if defined (DEBUG_MEMORY_LEAKAGE) dmalloc_dump_outstanding ();#endif#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) dump_rc_history (0);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -