summaryrefslogtreecommitdiff
path: root/relay/dhcrelay.c
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2019-12-20 10:11:54 -0500
committerThomas Markwalder <tmark@isc.org>2020-01-14 14:28:42 -0500
commit0a2f9a62bceb90b0d30461add2e25c4ce7a24547 (patch)
tree26125fe40514062d8f61a259d1ecb97352b94ea2 /relay/dhcrelay.c
parent5da634c5af4ad1ed21d1822de5105ac3edf0eeee (diff)
downloadisc-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.c72
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 */