From: Matthew Iselin <matt...@theiselins.net> Signed-off-by: Matthew Iselin <matt...@theiselins.net> --- src/include/gpxe/icmp6.h | 2 ++ src/include/gpxe/ndp.h | 3 ++- src/net/icmpv6.c | 44 +++++++++++++++++++++++++++++++++++++++++++- src/usr/ip6mgmt.c | 4 ++++ 4 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/src/include/gpxe/icmp6.h b/src/include/gpxe/icmp6.h index 6040258..23b7b56 100644 --- a/src/include/gpxe/icmp6.h +++ b/src/include/gpxe/icmp6.h @@ -65,6 +65,8 @@ int icmp6_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest ); +int icmp6_send_rsolicit ( struct net_device *netdev ); + int icmp6_send_advert ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest ); #endif /* _GPXE_ICMP6_H */ diff --git a/src/include/gpxe/ndp.h b/src/include/gpxe/ndp.h index 6830362..be387ce 100644 --- a/src/include/gpxe/ndp.h +++ b/src/include/gpxe/ndp.h @@ -4,13 +4,14 @@ #include <stdint.h> #include <byteswap.h> #include <string.h> -#include <gpxe/icmp6.h> #include <gpxe/ip6.h> #include <gpxe/in.h> #include <gpxe/netdevice.h> #include <gpxe/iobuf.h> #include <gpxe/tcpip.h> +struct icmp6_net_protocol; + #define NDP_STATE_INVALID 0 #define NDP_STATE_INCOMPLETE 1 #define NDP_STATE_REACHABLE 2 diff --git a/src/net/icmpv6.c b/src/net/icmpv6.c index fb4d9ea..dcc5851 100644 --- a/src/net/icmpv6.c +++ b/src/net/icmpv6.c @@ -64,7 +64,49 @@ int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unuse /* Send packet over IP6 */ return tcpip_tx ( iobuf, &icmp6_protocol, NULL, &st_dest.st, - NULL, &nsolicit->csum ); + netdev, &nsolicit->csum ); +} + +/** + * Send router solicitation packet + * + * @v netdev Network device + * @v src Source address + * @v dest Destination address + * + * This function prepares a neighbour solicitation packet and sends it to the + * network layer. + */ +int icmp6_send_rsolicit ( struct net_device *netdev ) { + union { + struct sockaddr_in6 sin6; + struct sockaddr_tcpip st; + } st_dest; + struct router_solicit *solicit; + struct io_buffer *iobuf = alloc_iob ( sizeof ( *solicit ) + MIN_IOB_LEN ); + + iob_reserve ( iobuf, MAX_HDR_LEN ); + solicit = iob_put ( iobuf, sizeof ( *solicit ) ); + + /* Fill up the headers */ + memset ( solicit, 0, sizeof ( *solicit ) ); + solicit->type = ICMP6_ROUTER_SOLICIT; + solicit->code = 0; + + /* Partial checksum */ + solicit->csum = 0; + solicit->csum = tcpip_chksum ( solicit, sizeof ( *solicit ) ); + + /* Solicited multicast address - FF02::2 (all routers on local network) */ + memset(&st_dest.sin6, 0, sizeof(st_dest.sin6)); + st_dest.sin6.sin_family = AF_INET6; + st_dest.sin6.sin6_addr.in6_u.u6_addr8[0] = 0xff; + st_dest.sin6.sin6_addr.in6_u.u6_addr8[1] = 0x2; + st_dest.sin6.sin6_addr.in6_u.u6_addr8[15] = 0x2; + + /* Send packet over IP6 */ + return tcpip_tx ( iobuf, &icmp6_protocol, NULL, &st_dest.st, + netdev, &solicit->csum ); } /** diff --git a/src/usr/ip6mgmt.c b/src/usr/ip6mgmt.c index f0b69d4..4f8cebb 100644 --- a/src/usr/ip6mgmt.c +++ b/src/usr/ip6mgmt.c @@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <gpxe/netdevice.h> #include <gpxe/in.h> #include <gpxe/ip6.h> +#include <gpxe/icmp6.h> #include <gpxe/monojob.h> #include <gpxe/process.h> #include <usr/ifmgmt.h> @@ -78,6 +79,9 @@ int ip6_autoconf ( struct net_device *netdev ) { /* Add as a route. */ add_ipv6_address ( netdev, ip6addr, 10, ip6addr, ip6zero ); + /* Solicit routers on the network. */ + icmp6_send_rsolicit ( netdev ); + return 0; } -- 1.7.2.5 _______________________________________________ gPXE-devel mailing list gPXE-devel@etherboot.org http://etherboot.org/mailman/listinfo/gpxe-devel