From 49ada27faac70cb63a341206dc4a67dd1c9979bc Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Fri, 23 Apr 2021 21:01:00 +0200 Subject: [PATCH] DHCP OPtion 82 and Config (WIP) --- src/bbl.h | 3 +++ src/bbl_config.c | 24 +++++++++++++++++++---- src/bbl_protocols.c | 47 ++++++++++++++++++++++++++++++++++++++------- src/bbl_protocols.h | 3 +++ 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/bbl.h b/src/bbl.h index 9090c327..e4440e92 100644 --- a/src/bbl.h +++ b/src/bbl.h @@ -576,6 +576,9 @@ typedef struct bbl_ctx_ /* DHCP */ bool dhcp_enable; + uint16_t dhcp_timeout; + uint16_t dhcp_retry; + uint8_t dhcp_vlan_priority; /* DHCPv6 */ bool dhcpv6_enable; diff --git a/src/bbl_config.c b/src/bbl_config.c index 2247a01d..18d55dcd 100644 --- a/src/bbl_config.c +++ b/src/bbl_config.c @@ -263,14 +263,12 @@ json_parse_access_interface (bbl_ctx_s *ctx, json_t *access_interface, bbl_acces } else { access_config->ipv6_enable = ctx->config.ipv6_enable; } -#if 0 value = json_object_get(access_interface, "dhcp"); if (json_is_boolean(value)) { access_config->dhcp_enable = json_boolean_value(value); } else { access_config->dhcp_enable = ctx->config.dhcp_enable; } -#endif value = json_object_get(access_interface, "dhcpv6"); if (json_is_boolean(value)) { access_config->dhcpv6_enable = json_boolean_value(value); @@ -671,7 +669,7 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) { } } } -#if 0 + /* DHCP Configuration */ section = json_object_get(root, "dhcp"); if (json_is_object(section)) { @@ -679,8 +677,23 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) { if (json_is_boolean(value)) { ctx->config.dhcp_enable = json_boolean_value(value); } + value = json_object_get(section, "timeout"); + if (json_is_number(value)) { + ctx->config.dhcp_timeout = json_number_value(value); + } + value = json_object_get(section, "retry"); + if (json_is_number(value)) { + ctx->config.dhcp_retry = json_number_value(value); + } + value = json_object_get(section, "vlan-priority"); + if (json_is_number(value)) { + ctx->config.dhcp_vlan_priority = json_number_value(value); + if(ctx->config.dhcp_vlan_priority > 7) { + fprintf(stderr, "JSON config error: Invalid value for dhcp->vlan-priority\n"); + return false; + } + } } -#endif /* DHCPv6 Configuration */ section = json_object_get(root, "dhcpv6"); @@ -1109,6 +1122,9 @@ bbl_config_init_defaults (bbl_ctx_s *ctx) { ctx->config.ip6cp_enable = true; ctx->config.ip6cp_conf_request_timeout = 5; ctx->config.ip6cp_conf_request_retry = 10; + ctx->config.dhcp_enable = false; + ctx->config.dhcp_timeout = 5; + ctx->config.dhcp_retry = 10; ctx->config.dhcpv6_enable = true; ctx->config.dhcpv6_rapid_commit = true; ctx->config.igmp_autostart = true; diff --git a/src/bbl_protocols.c b/src/bbl_protocols.c index 6f715227..6e9b814f 100644 --- a/src/bbl_protocols.c +++ b/src/bbl_protocols.c @@ -193,7 +193,9 @@ encode_dhcp(uint8_t *buf, uint16_t *len, if(!dhcp->header) return ENCODE_ERROR; - uint8_t *option_len; + uint8_t str_len; + uint8_t option_len; + uint8_t *option_len_ptr; memcpy(buf, dhcp->header, sizeof(struct dhcp_header)); BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); @@ -208,29 +210,30 @@ encode_dhcp(uint8_t *buf, uint16_t *len, if(dhcp->parameter_request_list) { *buf = DHCPV4_OPTION_PARAM_REQUEST_LIST; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); - option_len = buf; /* option len */ - *option_len = 0; + option_len_ptr = buf; + option_len = 0; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); if(dhcp->option_netmask) { - *option_len = *option_len+1; + option_len++; *buf = DHCPV4_OPTION_SUBNET_MASK; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } if(dhcp->option_router) { - *option_len = *option_len+1; + option_len++; *buf = DHCPV4_OPTION_ROUTER; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } if(dhcp->option_dns1 || dhcp->option_dns2) { - *option_len = *option_len+1; + option_len++; *buf = DHCPV4_OPTION_DNS_SERVER; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } if(dhcp->option_domain_name) { - *option_len = *option_len+1; + option_len++; *buf = DHCPV4_OPTION_DOMAIN_NAME; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); } + *option_len_ptr = option_len; } if(dhcp->client_identifier) { *buf = DHCPV4_OPTION_CLIENT_IDENTIFIER; @@ -257,6 +260,36 @@ encode_dhcp(uint8_t *buf, uint16_t *len, BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t)); } + if(dhcp->ari || dhcp->aci) { + /* RFC3046 Relay Agent Information Option (82) */ + *buf = DHCPV4_OPTION_RELAY_AGENT_INFORMATION; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + option_len_ptr = buf; + option_len = 0; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + if(dhcp->aci) { + *buf = ACCESS_LINE_ACI; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + str_len = strnlen(dhcp->aci, UINT8_MAX); + *buf = str_len; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + memcpy(buf, dhcp->aci, str_len); + BUMP_WRITE_BUFFER(buf, len, str_len); + option_len += str_len + 2; + } + if(dhcp->ari) { + *buf = ACCESS_LINE_ARI; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + str_len = strnlen(dhcp->ari, UINT8_MAX); + *buf = str_len; + BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); + memcpy(buf, dhcp->ari, str_len); + BUMP_WRITE_BUFFER(buf, len, str_len); + option_len += str_len + 2; + } + *option_len_ptr = option_len; + } + *buf = DHCPV4_OPTION_END; BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t)); diff --git a/src/bbl_protocols.h b/src/bbl_protocols.h index d97963e6..2eb5c4e3 100644 --- a/src/bbl_protocols.h +++ b/src/bbl_protocols.h @@ -386,6 +386,7 @@ typedef enum dhcp_option_code_ { DHCPV4_OPTION_STREETTALK_SERVER = 75, DHCPV4_OPTION_STDA_SERVER = 76, DHCPV4_OPTION_RAPID_COMMIT = 80, + DHCPV4_OPTION_RELAY_AGENT_INFORMATION = 82, DHCPV4_OPTION_CAPTIVE_PORTAL = 160, DHCPV4_OPTION_END = 255 } dhcp_option_code; @@ -718,6 +719,8 @@ typedef struct bbl_dhcp_ { bool option_host_name; bool option_domain_name; + char *ari; + char *aci; } bbl_dhcp_t; typedef struct bbl_l2tp_ {