1
0
mirror of https://github.com/rtbrick/bngblaster.git synced 2024-05-06 15:54:57 +00:00

Add IPv6 DNS Servers

Store and display IPv6 DNS servers
learned via RA and DHCPv6.
This commit is contained in:
Christian Giese
2021-02-26 17:53:27 +01:00
parent 000d6ce07a
commit c54b38b640
6 changed files with 74 additions and 3 deletions

View File

@ -170,10 +170,14 @@ bbl_session_update_state(bbl_ctx_s *ctx, bbl_session_s *session, session_state_t
session->ipv6_prefix.len = 0;
session->delegated_ipv6_prefix.len = 0;
session->icmpv6_ra_received = false;
memset(session->ipv6_dns1, 0x0, IPV6_ADDR_LEN);
memset(session->ipv6_dns2, 0x0, IPV6_ADDR_LEN);
session->dhcpv6_requested = false;
session->dhcpv6_received = false;
session->dhcpv6_type = DHCPV6_MESSAGE_SOLICIT;
session->dhcpv6_ia_pd_option_len = 0;
memset(session->dhcpv6_dns1, 0x0, IPV6_ADDR_LEN);
memset(session->dhcpv6_dns2, 0x0, IPV6_ADDR_LEN);
session->zapping_joined_group = NULL;
session->zapping_leaved_group = NULL;
session->zapping_count = 0;

View File

@ -710,18 +710,22 @@ typedef struct bbl_session_
ipv6addr_t link_local_ipv6_address;
ipv6_prefix ipv6_prefix;
ipv6addr_t ipv6_address;
ipv6addr_t ipv6_dns1; /* DNS learned via RA */
ipv6addr_t ipv6_dns2; /* DNS learned via RA */
/* DHCPv6 */
ipv6_prefix delegated_ipv6_prefix;
ipv6addr_t delegated_ipv6_address;
uint8_t duid[DUID_LEN];
uint8_t server_duid[DHCPV6_BUFFER];
uint8_t server_duid_len;
/* DHCPv6 */
bool dhcpv6_requested;
bool dhcpv6_received;
uint8_t dhcpv6_type;
uint8_t dhcpv6_ia_pd_option[DHCPV6_BUFFER];
uint8_t dhcpv6_ia_pd_option_len;
ipv6addr_t dhcpv6_dns1;
ipv6addr_t dhcpv6_dns2;
/* IGMP */
bool igmp_autostart;

View File

@ -394,6 +394,10 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, session_key_t *key, json_t* argume
const char *dns2 = NULL;
const char *ipv6 = NULL;
const char *ipv6pd = NULL;
const char *ipv6_dns1 = NULL;
const char *ipv6_dns2 = NULL;
const char *dhcpv6_dns1 = NULL;
const char *dhcpv6_dns2 = NULL;
const char *type = NULL;
const char *username = NULL;
const char *lcp = NULL;
@ -418,6 +422,18 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, session_key_t *key, json_t* argume
if(session->delegated_ipv6_prefix.len) {
ipv6pd = format_ipv6_prefix(&session->delegated_ipv6_prefix);
}
if(*(uint64_t*)session->ipv6_dns1) {
ipv6_dns1 = format_ipv6_address(&session->ipv6_dns1);
}
if(*(uint64_t*)session->ipv6_dns2) {
ipv6_dns2 = format_ipv6_address(&session->ipv6_dns2);
}
if(*(uint64_t*)session->dhcpv6_dns1) {
dhcpv6_dns1 = format_ipv6_address(&session->dhcpv6_dns1);
}
if(*(uint64_t*)session->dhcpv6_dns2) {
dhcpv6_dns2 = format_ipv6_address(&session->dhcpv6_dns2);
}
if(session->access_type == ACCESS_TYPE_PPPOE) {
type = "pppoe";
@ -456,7 +472,7 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, session_key_t *key, json_t* argume
"network-rx-session-packets-ipv6pd", session->stats.network_ipv6pd_rx,
"network-rx-session-packets-ipv6pd-loss", session->stats.network_ipv6pd_loss);
}
root = json_pack("{ss si s{ss ss* ss ss ss ss* ss* ss* ss* ss* ss* ss* ss* so*}}",
root = json_pack("{ss si s{ss ss* ss ss ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* so*}}",
"status", "ok",
"code", 200,
"session-information",
@ -473,6 +489,10 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, session_key_t *key, json_t* argume
"ipv4-dns2", dns2,
"ipv6-prefix", ipv6,
"ipv6-delegated-prefix", ipv6pd,
"ipv6-dns1", ipv6_dns1,
"ipv6-dns2", ipv6_dns2,
"dhcpv6-dns1", dhcpv6_dns1,
"dhcpv6-dns2", dhcpv6_dns2,
"session-traffic", session_traffic);
if(root) {
result = json_dumpfd(root, fd, 0);

View File

@ -1247,8 +1247,18 @@ decode_icmpv6(uint8_t *buf, uint16_t len,
return DECODE_ERROR;
}
if(option == ICMPV6_OPTION_PREFIX) {
if(option_len < 32) {
return DECODE_ERROR;
}
icmpv6->prefix.len = *buf;
memcpy(&icmpv6->prefix.address, buf+14, IPV6_ADDR_LEN);
} else if(option == ICMPV6_OPTION_DNS) {
if(option_len >= 24) {
icmpv6->dns1 = (ipv6addr_t*)(buf+6);
if(option_len >= 40) {
icmpv6->dns2 = (ipv6addr_t*)(buf+22);
}
}
}
BUMP_BUFFER(buf, len, option_len-2);
}
@ -1379,11 +1389,17 @@ decode_dhcpv6(uint8_t *buf, uint16_t len,
BUMP_BUFFER(buf, len, sizeof(uint16_t));
option_len = be16toh(*(uint16_t*)buf);
BUMP_BUFFER(buf, len, sizeof(uint16_t));
if(option_len > len) {
return DECODE_ERROR;
}
switch(option) {
case DHCPV6_OPTION_RAPID_COMMIT:
dhcpv6->rapid = true;
break;
case DHCPV6_OPTION_IA_PD:
if(option_len < 41) {
return DECODE_ERROR;
}
dhcpv6->ia_pd_option = buf;
dhcpv6->ia_pd_option_len = option_len;
option = be16toh(*(uint16_t*)(buf+12));
@ -1392,9 +1408,19 @@ decode_dhcpv6(uint8_t *buf, uint16_t len,
}
break;
case DHCPV6_OPTION_SERVERID:
if(option_len < 2) {
return DECODE_ERROR;
}
dhcpv6->server_duid = buf;
dhcpv6->server_duid_len = option_len;
break;
case DHCPV6_OPTION_DNS_SERVERS:
if(option_len >= 16) {
dhcpv6->dns1 = (ipv6addr_t*)(buf);
if(option_len >= 32) {
dhcpv6->dns2 = (ipv6addr_t*)(buf+16);
}
}
default:
break;
}

View File

@ -144,6 +144,7 @@
#define ICMPV6_FLAGS_OTHER_CONFIG 0x40
#define ICMPV6_OPTION_PREFIX 3
#define ICMPV6_OPTION_DNS 25
#define DHCPV6_TRANS_ID_LEN 3
#define DHCPV6_TYPE_MASK 0x00ffffff
@ -539,6 +540,8 @@ typedef struct bbl_icmpv6_ {
uint8_t *mac;
uint8_t *data;
uint16_t data_len;
ipv6addr_t *dns1;
ipv6addr_t *dns2;
} bbl_icmpv6_t;
typedef struct bbl_dhcpv6_ {
@ -554,6 +557,8 @@ typedef struct bbl_dhcpv6_ {
ipv6_prefix *delegated_prefix;
uint8_t *ia_pd_option;
uint8_t ia_pd_option_len;
ipv6addr_t *dns1;
ipv6addr_t *dns2;
} bbl_dhcpv6_t;
typedef struct bbl_l2tp_ {

View File

@ -592,6 +592,12 @@ bbl_rx_dhcpv6(bbl_ipv6_t *ipv6, bbl_interface_s *interface, bbl_session_s *sessi
LOG(IP, "IPv6 (Q-in-Q %u:%u) DHCPv6 PD prefix %s/%d\n",
session->key.outer_vlan_id, session->key.inner_vlan_id,
format_ipv6_address(&session->delegated_ipv6_prefix.address), session->delegated_ipv6_prefix.len);
if(dhcpv6->dns1) {
memcpy(&session->dhcpv6_dns1, dhcpv6->dns1, IPV6_ADDR_LEN);
if(dhcpv6->dns2) {
memcpy(&session->dhcpv6_dns2, dhcpv6->dns2, IPV6_ADDR_LEN);
}
}
if(session->l2tp == false && ctx->config.session_traffic_ipv6pd_pps &&
ctx->op.network_if && ctx->op.network_if->ip6.len) {
/* Start IPv6 PD Session Traffic */
@ -745,6 +751,12 @@ bbl_rx_icmpv6(bbl_ipv6_t *ipv6, bbl_interface_s *interface, bbl_session_s *sessi
LOG(IP, "IPv6 (Q-in-Q %u:%u) ICMPv6 RA prefix %s/%d\n",
session->key.outer_vlan_id, session->key.inner_vlan_id,
format_ipv6_address(&session->ipv6_prefix.address), session->ipv6_prefix.len);
if(icmpv6->dns1) {
memcpy(&session->ipv6_dns1, icmpv6->dns1, IPV6_ADDR_LEN);
if(icmpv6->dns2) {
memcpy(&session->ipv6_dns2, icmpv6->dns2, IPV6_ADDR_LEN);
}
}
if(session->l2tp == false && ctx->config.session_traffic_ipv6_pps &&
ctx->op.network_if && ctx->op.network_if->ip6.len) {
/* Start IPv6 Session Traffic */