diff options
author | Thomas Markwalder <tmark@isc.org> | 2019-12-20 10:11:54 -0500 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2020-01-14 14:28:42 -0500 |
commit | 0a2f9a62bceb90b0d30461add2e25c4ce7a24547 (patch) | |
tree | 26125fe40514062d8f61a259d1ecb97352b94ea2 /relay/dhcrelay.c | |
parent | 5da634c5af4ad1ed21d1822de5105ac3edf0eeee (diff) | |
download | isc-dhcp-0a2f9a62bceb90b0d30461add2e25c4ce7a24547.tar.gz |
[#71] Fix dhcrelay agent option buffer pointer logic
relay/dhcrelay.c
Added UNIT_TEST conditionals and such for unit test support
strip_relay_agent_options()
strip_relay_agent_options()
- corrected buffer pointer logic
relay/tests/Atffile
relay/tests/Kyuafile
relay/tests/Makefile.am
relay/tests/relay_unittests.c
- new unit test files
configure.ac-base
added relay/tests/Makefile
regenerated configure files
configure
configure.ac
configure.ac+lt
configure.ac-lt
Diffstat (limited to 'relay/dhcrelay.c')
-rw-r--r-- | relay/dhcrelay.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 896e1e2e..980dacae 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -114,9 +114,11 @@ struct stream_list { int id; } *downstreams, *upstreams; +#ifndef UNIT_TEST static struct stream_list *parse_downstream(char *); static struct stream_list *parse_upstream(char *); static void setup_streams(void); +#endif /* UNIT_TEST */ /* * A pointer to a subscriber id to add to the message we forward. @@ -127,18 +129,23 @@ static void setup_streams(void); char *dhcrelay_sub_id = NULL; #endif +#ifndef UNIT_TEST static void do_relay4(struct interface_info *, struct dhcp_packet *, unsigned int, unsigned int, struct iaddr, struct hardware *); -static int add_relay_agent_options(struct interface_info *, - struct dhcp_packet *, unsigned, - struct in_addr); -static int find_interface_by_agent_option(struct dhcp_packet *, - struct interface_info **, u_int8_t *, int); -static int strip_relay_agent_options(struct interface_info *, - struct interface_info **, - struct dhcp_packet *, unsigned); +#endif /* UNIT_TEST */ +extern int add_relay_agent_options(struct interface_info *, + struct dhcp_packet *, unsigned, + struct in_addr); +extern int find_interface_by_agent_option(struct dhcp_packet *, + struct interface_info **, u_int8_t *, int); + +extern int strip_relay_agent_options(struct interface_info *, + struct interface_info **, + struct dhcp_packet *, unsigned); + +#ifndef UNIT_TEST static void request_v4_interface(const char* name, int flags); static const char copyright[] = @@ -269,7 +276,7 @@ usage(const char *sfmt, const char *sarg) { isc_file_basename(progname)); } -int +int main(int argc, char **argv) { isc_result_t status; struct servent *ent; @@ -310,7 +317,7 @@ main(int argc, char **argv) { #if !defined(DEBUG) setlogmask(LOG_UPTO(LOG_INFO)); -#endif +#endif /* Parse arguments changing no_daemon */ for (i = 1; i < argc; i++) { @@ -524,7 +531,7 @@ main(int argc, char **argv) { log_fatal("%s: uplink interface_allocate: %s", argv[i], isc_result_totext(status)); } - + if (strlen(argv[i]) >= sizeof(uplink->name)) { log_fatal("%s: uplink name too long," " it cannot exceed: %ld characters", @@ -665,7 +672,7 @@ main(int argc, char **argv) { log_info(copyright); log_info(arr); log_info(url); - } else + } else log_perror = 0; /* Set default port */ @@ -789,7 +796,7 @@ main(int argc, char **argv) { else { fprintf(pf, "%ld\n",(long)getpid()); fclose(pf); - } + } } } @@ -968,14 +975,16 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, ++client_packets_relayed; } } - + } +#endif /* UNIT_TEST */ + /* Strip any Relay Agent Information options from the DHCP packet option buffer. If there is a circuit ID suboption, look up the outgoing interface based upon it. */ -static int +int strip_relay_agent_options(struct interface_info *in, struct interface_info **out, struct dhcp_packet *packet, @@ -1055,8 +1064,13 @@ strip_relay_agent_options(struct interface_info *in, return (0); if (sp != op) { - memmove(sp, op, op[1] + 2); - sp += op[1] + 2; + size_t mlen = op[1] + 2; + memmove(sp, op, mlen); + sp += mlen; + if (sp > max) { + return (0); + } + op = nextop; } else op = sp = nextop; @@ -1107,7 +1121,7 @@ strip_relay_agent_options(struct interface_info *in, we find a circuit ID that matches an existing interface do we tell the caller to go ahead and process the packet. */ -static int +int find_interface_by_agent_option(struct dhcp_packet *packet, struct interface_info **out, u_int8_t *buf, int len) { @@ -1171,7 +1185,7 @@ find_interface_by_agent_option(struct dhcp_packet *packet, * Agent Information option tacked onto its tail. If it is, tack * the option on. */ -static int +int add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, unsigned length, struct in_addr giaddr) { int is_dhcp = 0, mms; @@ -1284,8 +1298,13 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, end_pad = NULL; if (sp != op) { - memmove(sp, op, op[1] + 2); - sp += op[1] + 2; + size_t mlen = op[1] + 2; + memmove(sp, op, mlen); + sp += mlen; + if (sp > max) { + return (0); + } + op = nextop; } else op = sp = nextop; @@ -1414,6 +1433,8 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, return (length); } +#ifndef UNIT_TEST + #ifdef DHCPv6 /* * Parse a downstream argument: [address%]interface[#index]. @@ -1726,7 +1747,7 @@ process_up6(struct packet *packet, struct stream_list *dp) { if (!option_state_allocate(&opts, MDL)) { log_fatal("No memory for upwards options."); } - + /* Add an interface-id (if used). */ if (use_if_id) { int if_id; @@ -1763,7 +1784,7 @@ process_up6(struct packet *packet, struct stream_list *dp) { return; } } - + #if defined(RELAY_PORT) /* @@ -1802,7 +1823,7 @@ process_up6(struct packet *packet, struct stream_list *dp) { /* Finish the relay-forward message. */ cursor += store_options6(forw_data + cursor, sizeof(forw_data) - cursor, - opts, packet, + opts, packet, required_forw_opts, NULL); option_state_dereference(&opts, MDL); @@ -1812,7 +1833,7 @@ process_up6(struct packet *packet, struct stream_list *dp) { (size_t) cursor, &up->link); } } - + /* * Process a packet downwards, i.e., from server to client. */ @@ -2126,3 +2147,4 @@ void request_v4_interface(const char* name, int flags) { interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); interface_dereference(&tmp, MDL); } +#endif /* UNIT_TEST */ |