void udp_ipv6_select(FAR struct net_driver_s *dev) { /* Set a bit in the d_flags to distinguish this from an IPv6 packet */ IFF_SET_IPv6(dev->d_flags); /* Set the offset to the beginning of the UDP data payload */ dev->d_appdata = &dev->d_buf[IPv6UDP_HDRLEN + NET_LL_HDRLEN(dev)]; }
static void icmpv6_echo_request(FAR struct net_driver_s *dev, FAR struct icmpv6_ping_s *pstate) { FAR struct icmpv6_iphdr_s *icmp; FAR struct icmpv6_echo_request_s *req; uint16_t reqlen; int i; nllvdbg("Send ECHO request: seqno=%d\n", pstate->png_seqno); /* Set up the IPv6 header (most is probably already in place) */ icmp = ICMPv6BUF; icmp->vtc = 0x60; /* Version/traffic class (MS) */ icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */ icmp->flow = 0; /* Flow label (LS) */ /* Length excludes the IPv6 header */ reqlen = SIZEOF_ICMPV6_ECHO_REQUEST_S(pstate->png_datlen); icmp->len[0] = (reqlen >> 8); icmp->len[1] = (reqlen & 0xff); icmp->proto = IP_PROTO_ICMP6; /* Next header */ icmp->ttl = IP_TTL; /* Hop limit */ /* Set the multicast destination IP address */ net_ipv6addr_copy(icmp->destipaddr, pstate->png_addr); /* Add out IPv6 address as the source address */ net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr); /* Set up the ICMPv6 Echo Request message */ req = ICMPv6ECHOREQ; req->type = ICMPv6_ECHO_REQUEST; /* Message type */ req->code = 0; /* Message qualifier */ req->id = htons(pstate->png_id); req->seqno = htons(pstate->png_seqno); /* Add some easily verifiable data */ for (i = 0; i < pstate->png_datlen; i++) { req->data[i] = i; } /* Calculate the checksum over both the ICMP header and payload */ icmp->chksum = 0; icmp->chksum = ~icmpv6_chksum(dev); /* Set the size to the size of the IPv6 header and the payload size */ IFF_SET_IPv6(dev->d_flags); dev->d_sndlen = reqlen; dev->d_len = reqlen + IPv6_HDRLEN; nllvdbg("Outgoing ICMPv6 Echo Request length: %d (%d)\n", dev->d_len, (icmp->len[0] << 8) | icmp->len[1]); #ifdef CONFIG_NET_STATISTICS g_netstats.icmpv6.sent++; g_netstats.ipv6.sent++; #endif }