mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
Merge pull request #159 from rtbrick/icmpv6-ra
add ICMPv6 RA support for network interfaces
This commit is contained in:
@@ -584,6 +584,13 @@ json_parse_network_interface(json_t *network_interface, bbl_network_config_s *ne
|
||||
return false;
|
||||
}
|
||||
}
|
||||
value = json_object_get(network_interface, "ipv6-router-advertisement");
|
||||
if(json_is_boolean(value)) {
|
||||
network_config->ipv6_ra = json_boolean_value(value);
|
||||
} else {
|
||||
network_config->ipv6_ra = true;
|
||||
}
|
||||
|
||||
if(json_unpack(network_interface, "{s:s}", "gateway-mac", &s) == 0) {
|
||||
if(sscanf(s, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||
&network_config->gateway_mac[0],
|
||||
|
||||
@@ -100,6 +100,7 @@ typedef struct bbl_network_config_
|
||||
ipv4_prefix ip;
|
||||
ipv4addr_t gateway;
|
||||
|
||||
bool ipv6_ra;
|
||||
ipv6_prefix ip6;
|
||||
ipv6addr_t gateway6;
|
||||
|
||||
|
||||
@@ -89,8 +89,9 @@
|
||||
/* Network Interface Send Mask */
|
||||
#define BBL_IF_SEND_ARP_REQUEST 0x00000001
|
||||
#define BBL_IF_SEND_ICMPV6_NS 0x00000002
|
||||
#define BBL_IF_SEND_ISIS_P2P_HELLO 0x00000004
|
||||
#define BBL_IF_SEND_LDP_HELLO 0x00000008
|
||||
#define BBL_IF_SEND_ICMPV6_RA 0x00000004
|
||||
#define BBL_IF_SEND_ISIS_P2P_HELLO 0x00000008
|
||||
#define BBL_IF_SEND_LDP_HELLO 0x00000010
|
||||
|
||||
#define BBL_AVG_SAMPLES 5
|
||||
#define BBL_MAX_STREAM_OVERHEAD 128
|
||||
|
||||
@@ -118,6 +118,10 @@ bbl_network_interfaces_add()
|
||||
network_interface->ip6_ll[13] = network_interface->mac[3];
|
||||
network_interface->ip6_ll[14] = network_interface->mac[4];
|
||||
network_interface->ip6_ll[15] = network_interface->mac[5];
|
||||
if(network_config->ipv6_ra) {
|
||||
network_interface->ipv6_ra = true;
|
||||
network_interface->send_requests |= BBL_IF_SEND_ICMPV6_RA;
|
||||
}
|
||||
|
||||
/* Init IPv6 */
|
||||
if(ipv6_prefix_not_zero(&network_config->ip6) &&
|
||||
@@ -366,6 +370,8 @@ bbl_network_rx_icmpv6(bbl_network_interface_s *interface,
|
||||
secondary_ip6 = secondary_ip6->next;
|
||||
}
|
||||
}
|
||||
} else if(icmpv6->type == IPV6_ICMPV6_ROUTER_SOLICITATION && interface->ipv6_ra) {
|
||||
interface->send_requests |= BBL_IF_SEND_ICMPV6_RA;
|
||||
} else if(icmpv6->type == IPV6_ICMPV6_ECHO_REQUEST) {
|
||||
bbl_network_icmpv6_echo_reply(interface, eth, ipv6, icmpv6);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@ typedef struct bbl_network_interface_
|
||||
ipv4_prefix ip;
|
||||
ipv4addr_t gateway;
|
||||
|
||||
bool ipv6_enabled;
|
||||
bool ipv6_ra;
|
||||
|
||||
ipv6_prefix ip6; /* global IPv6 address */
|
||||
ipv6addr_t ip6_ll; /* link-local IPv6 address */
|
||||
ipv6addr_t gateway6;
|
||||
|
||||
@@ -713,6 +713,24 @@ encode_icmpv6(uint8_t *buf, uint16_t *len,
|
||||
*(uint32_t*)buf = 0;
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
|
||||
break;
|
||||
case IPV6_ICMPV6_ROUTER_ADVERTISEMENT:
|
||||
*buf = 64; /* Hop Limit */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
|
||||
*buf = 0; /* Flags */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
|
||||
*(uint16_t*)buf = htobe16(30); /* Router lifetime */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
|
||||
*(uint32_t*)buf = 0; /* Reachable time */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
|
||||
*(uint32_t*)buf = 0; /* Retrans time */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
|
||||
*buf = 1; /* Source link-layer address */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
|
||||
*buf = 1; /* Length (1 = 8 byte) */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
|
||||
memcpy(buf, icmp->mac, ETH_ADDR_LEN);
|
||||
BUMP_WRITE_BUFFER(buf, len, ETH_ADDR_LEN);
|
||||
break;
|
||||
case IPV6_ICMPV6_NEIGHBOR_SOLICITATION:
|
||||
*(uint32_t*)buf = 0; /* Reserved */
|
||||
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
|
||||
|
||||
@@ -1373,6 +1373,13 @@ bbl_tx_network_nd_timeout(timer_s *timer)
|
||||
interface->send_requests |= BBL_IF_SEND_ICMPV6_NS;
|
||||
}
|
||||
|
||||
void
|
||||
bbl_tx_network_ra_timeout(timer_s *timer)
|
||||
{
|
||||
bbl_network_interface_s *interface = timer->data;
|
||||
interface->send_requests |= BBL_IF_SEND_ICMPV6_RA;
|
||||
}
|
||||
|
||||
static protocol_error_t
|
||||
bbl_tx_encode_network_packet(bbl_network_interface_s *interface, uint8_t *buf, uint16_t *len)
|
||||
{
|
||||
@@ -1426,6 +1433,22 @@ bbl_tx_encode_network_packet(bbl_network_interface_s *interface, uint8_t *buf, u
|
||||
1, 0, interface, &bbl_tx_network_nd_timeout);
|
||||
}
|
||||
result = encode_ethernet(buf, len, ð);
|
||||
} else if(interface->send_requests & BBL_IF_SEND_ICMPV6_RA) {
|
||||
interface->send_requests &= ~BBL_IF_SEND_ICMPV6_RA;
|
||||
ipv6_multicast_mac(ipv6_multicast_all_nodes, mac);
|
||||
eth.dst = mac;
|
||||
eth.type = ETH_TYPE_IPV6;
|
||||
eth.next = &ipv6;
|
||||
ipv6.src = interface->ip6_ll;
|
||||
ipv6.dst = (void*)ipv6_multicast_all_nodes;
|
||||
ipv6.protocol = IPV6_NEXT_HEADER_ICMPV6;
|
||||
ipv6.next = &icmpv6;
|
||||
ipv6.ttl = 255;
|
||||
icmpv6.type = IPV6_ICMPV6_ROUTER_ADVERTISEMENT;
|
||||
icmpv6.mac = interface->mac;
|
||||
timer_add(&g_ctx->timer_root, &interface->timer_nd, "RA timer",
|
||||
10, 0, interface, &bbl_tx_network_ra_timeout);
|
||||
result = encode_ethernet(buf, len, ð);
|
||||
} else if(interface->send_requests & BBL_IF_SEND_ISIS_P2P_HELLO) {
|
||||
interface->send_requests &= ~BBL_IF_SEND_ISIS_P2P_HELLO;
|
||||
result = isis_p2p_hello_encode(interface, buf, len, ð);
|
||||
|
||||
Reference in New Issue
Block a user