Annotation of qemu/roms/ipxe/src/net/icmpv6.c, revision 1.1

1.1     ! root        1: #include <stdint.h>
        !             2: #include <string.h>
        !             3: #include <byteswap.h>
        !             4: #include <errno.h>
        !             5: #include <ipxe/in.h>
        !             6: #include <ipxe/ip6.h>
        !             7: #include <ipxe/if_ether.h>
        !             8: #include <ipxe/iobuf.h>
        !             9: #include <ipxe/ndp.h>
        !            10: #include <ipxe/icmp6.h>
        !            11: #include <ipxe/tcpip.h>
        !            12: #include <ipxe/netdevice.h>
        !            13: 
        !            14: /**
        !            15:  * Send neighbour solicitation packet
        !            16:  *
        !            17:  * @v netdev   Network device
        !            18:  * @v src      Source address
        !            19:  * @v dest     Destination address
        !            20:  *
        !            21:  * This function prepares a neighbour solicitation packet and sends it to the
        !            22:  * network layer.
        !            23:  */
        !            24: int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unused,
        !            25:                         struct in6_addr *dest ) {
        !            26:        union {
        !            27:                struct sockaddr_in6 sin6;
        !            28:                struct sockaddr_tcpip st;
        !            29:        } st_dest;
        !            30:        struct ll_protocol *ll_protocol = netdev->ll_protocol;
        !            31:        struct neighbour_solicit *nsolicit;
        !            32:        struct io_buffer *iobuf = alloc_iob ( sizeof ( *nsolicit ) + MIN_IOB_LEN );
        !            33:        iob_reserve ( iobuf, MAX_HDR_LEN );
        !            34:        nsolicit = iob_put ( iobuf, sizeof ( *nsolicit ) );
        !            35: 
        !            36:        /* Fill up the headers */
        !            37:        memset ( nsolicit, 0, sizeof ( *nsolicit ) );
        !            38:        nsolicit->type = ICMP6_NSOLICIT;
        !            39:        nsolicit->code = 0;
        !            40:        nsolicit->target = *dest;
        !            41:        nsolicit->opt_type = 1;
        !            42:        nsolicit->opt_len = ( 2 + ll_protocol->ll_addr_len ) / 8;
        !            43:        memcpy ( nsolicit->opt_ll_addr, netdev->ll_addr,
        !            44:                                netdev->ll_protocol->ll_addr_len );
        !            45:        /* Partial checksum */
        !            46:        nsolicit->csum = 0;
        !            47:        nsolicit->csum = tcpip_chksum ( nsolicit, sizeof ( *nsolicit ) );
        !            48: 
        !            49:        /* Solicited multicast address */
        !            50:        st_dest.sin6.sin_family = AF_INET6;
        !            51:        st_dest.sin6.sin6_addr.in6_u.u6_addr8[0] = 0xff;
        !            52:        st_dest.sin6.sin6_addr.in6_u.u6_addr8[2] = 0x02;
        !            53:        st_dest.sin6.sin6_addr.in6_u.u6_addr16[1] = 0x0000;
        !            54:        st_dest.sin6.sin6_addr.in6_u.u6_addr32[1] = 0x00000000;
        !            55:        st_dest.sin6.sin6_addr.in6_u.u6_addr16[4] = 0x0000;
        !            56:        st_dest.sin6.sin6_addr.in6_u.u6_addr16[5] = 0x0001;
        !            57:        st_dest.sin6.sin6_addr.in6_u.u6_addr32[3] = dest->in6_u.u6_addr32[3];
        !            58:        st_dest.sin6.sin6_addr.in6_u.u6_addr8[13] = 0xff;
        !            59:        
        !            60:        /* Send packet over IP6 */
        !            61:        return tcpip_tx ( iobuf, &icmp6_protocol, NULL, &st_dest.st,
        !            62:                          NULL, &nsolicit->csum );
        !            63: }
        !            64: 
        !            65: /**
        !            66:  * Process ICMP6 headers
        !            67:  *
        !            68:  * @v iobuf    I/O buffer
        !            69:  * @v st_src   Source address
        !            70:  * @v st_dest  Destination address
        !            71:  */
        !            72: static int icmp6_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
        !            73:                      struct sockaddr_tcpip *st_dest, __unused uint16_t pshdr_csum ) {
        !            74:        struct icmp6_header *icmp6hdr = iobuf->data;
        !            75: 
        !            76:        /* Sanity check */
        !            77:        if ( iob_len ( iobuf ) < sizeof ( *icmp6hdr ) ) {
        !            78:                DBG ( "Packet too short (%zd bytes)\n", iob_len ( iobuf ) );
        !            79:                free_iob ( iobuf );
        !            80:                return -EINVAL;
        !            81:        }
        !            82: 
        !            83:        /* TODO: Verify checksum */
        !            84: 
        !            85:        /* Process the ICMP header */
        !            86:        switch ( icmp6hdr->type ) {
        !            87:        case ICMP6_NADVERT:
        !            88:                return ndp_process_advert ( iobuf, st_src, st_dest );
        !            89:        }
        !            90:        return -ENOSYS;
        !            91: }
        !            92: 
        !            93: #if 0
        !            94: void icmp6_test_nadvert (struct net_device *netdev, struct sockaddr_in6 *server_p, char *ll_addr) {
        !            95: 
        !            96:                struct sockaddr_in6 server;
        !            97:                memcpy ( &server, server_p, sizeof ( server ) );
        !            98:                 struct io_buffer *rxiobuf = alloc_iob ( 500 );
        !            99:                 iob_reserve ( rxiobuf, MAX_HDR_LEN );
        !           100:                 struct neighbour_advert *nadvert = iob_put ( rxiobuf, sizeof ( *nadvert ) );
        !           101:                 nadvert->type = 136;
        !           102:                 nadvert->code = 0;
        !           103:                 nadvert->flags = ICMP6_FLAGS_SOLICITED;
        !           104:                nadvert->csum = 0xffff;
        !           105:                nadvert->target = server.sin6_addr;
        !           106:                 nadvert->opt_type = 2;
        !           107:                 nadvert->opt_len = 1;
        !           108:                 memcpy ( nadvert->opt_ll_addr, ll_addr, 6 );
        !           109:                 struct ip6_header *ip6hdr = iob_push ( rxiobuf, sizeof ( *ip6hdr ) );
        !           110:                 ip6hdr->ver_traffic_class_flow_label = htonl ( 0x60000000 );
        !           111:                ip6hdr->hop_limit = 255;
        !           112:                ip6hdr->nxt_hdr = 58;
        !           113:                ip6hdr->payload_len = htons ( sizeof ( *nadvert ) );
        !           114:                 ip6hdr->src = server.sin6_addr;
        !           115:                 ip6hdr->dest = server.sin6_addr;
        !           116:                hex_dump ( rxiobuf->data, iob_len ( rxiobuf ) );
        !           117:                 net_rx ( rxiobuf, netdev, htons ( ETH_P_IPV6 ), ll_addr );
        !           118: }
        !           119: #endif
        !           120: 
        !           121: /** ICMP6 protocol */
        !           122: struct tcpip_protocol icmp6_protocol __tcpip_protocol = {
        !           123:        .name = "ICMP6",
        !           124:        .rx = icmp6_rx,
        !           125:        .tcpip_proto = IP_ICMP6, // 58
        !           126: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.