void udp_send(struct net_driver_s *dev, struct udp_conn_s *conn) { FAR struct udp_iphdr_s *pudpbuf = UDPBUF; if (dev->d_sndlen > 0) { /* The total length to send is the size of the application data plus * the IP and UDP headers (and, eventually, the Ethernet header) */ dev->d_len = dev->d_sndlen + IPUDP_HDRLEN; /* Initialize the IP header. Note that for IPv6, the IP length field * does not include the IPv6 IP header length. */ #ifdef CONFIG_NET_IPv6 pudpbuf->vtc = 0x60; pudpbuf->tcf = 0x00; pudpbuf->flow = 0x00; pudpbuf->len[0] = (dev->d_sndlen >> 8); pudpbuf->len[1] = (dev->d_sndlen & 0xff); pudpbuf->nexthdr = IP_PROTO_UDP; pudpbuf->hoplimit = conn->ttl; net_ipaddr_copy(pudpbuf->srcipaddr, &dev->d_ipaddr); net_ipaddr_copy(pudpbuf->destipaddr, &conn->ripaddr); #else /* CONFIG_NET_IPv6 */ pudpbuf->vhl = 0x45; pudpbuf->tos = 0; pudpbuf->len[0] = (dev->d_len >> 8); pudpbuf->len[1] = (dev->d_len & 0xff); ++g_ipid; pudpbuf->ipid[0] = g_ipid >> 8; pudpbuf->ipid[1] = g_ipid & 0xff; pudpbuf->ipoffset[0] = 0; pudpbuf->ipoffset[1] = 0; pudpbuf->ttl = conn->ttl; pudpbuf->proto = IP_PROTO_UDP; net_ipaddr_hdrcopy(pudpbuf->srcipaddr, &dev->d_ipaddr); net_ipaddr_hdrcopy(pudpbuf->destipaddr, &conn->ripaddr); /* Calculate IP checksum. */ pudpbuf->ipchksum = 0; pudpbuf->ipchksum = ~(ip_chksum(dev)); #endif /* CONFIG_NET_IPv6 */ /* Initialize the UDP header */ pudpbuf->srcport = conn->lport; pudpbuf->destport = conn->rport; pudpbuf->udplen = HTONS(dev->d_sndlen + UDP_HDRLEN); #ifdef CONFIG_NET_UDP_CHECKSUMS /* Calculate UDP checksum. */ pudpbuf->udpchksum = 0; pudpbuf->udpchksum = ~(udp_chksum(dev)); if (pudpbuf->udpchksum == 0) { pudpbuf->udpchksum = 0xffff; } #else pudpbuf->udpchksum = 0; #endif nllvdbg("Outgoing UDP packet length: %d (%d)\n", dev->d_len, (pudpbuf->len[0] << 8) | pudpbuf->len[1]); #ifdef CONFIG_NET_STATISTICS g_netstats.udp.sent++; g_netstats.ip.sent++; #endif }
void icmp_send(FAR struct net_driver_s *dev, FAR net_ipaddr_t *destaddr) { FAR struct icmp_iphdr_s *picmp = ICMPBUF; if (dev->d_sndlen > 0) { /* The total length to send is the size of the application data plus * the IP and ICMP headers (and, eventually, the Ethernet header) */ dev->d_len = dev->d_sndlen + IPICMP_HDRLEN; /* The total size of the data (for ICMP checksum calculation) includes * the size of the ICMP header */ dev->d_sndlen += ICMP_HDRLEN; /* Initialize the IP header. Note that for IPv6, the IP length field * does not include the IPv6 IP header length. */ #ifdef CONFIG_NET_IPv6 picmp->vtc = 0x60; picmp->tcf = 0x00; picmp->flow = 0x00; picmp->len[0] = (dev->d_sndlen >> 8); picmp->len[1] = (dev->d_sndlen & 0xff); picmp->nexthdr = IP_PROTO_ICMP; picmp->hoplimit = IP_TTL; net_ipaddr_copy(picmp->srcipaddr, &dev->d_ipaddr); net_ipaddr_copy(picmp->destipaddr, destaddr); #else /* CONFIG_NET_IPv6 */ picmp->vhl = 0x45; picmp->tos = 0; picmp->len[0] = (dev->d_len >> 8); picmp->len[1] = (dev->d_len & 0xff); ++g_ipid; picmp->ipid[0] = g_ipid >> 8; picmp->ipid[1] = g_ipid & 0xff; picmp->ipoffset[0] = TCPFLAG_DONTFRAG >> 8; picmp->ipoffset[1] = TCPFLAG_DONTFRAG & 0xff; picmp->ttl = IP_TTL; picmp->proto = IP_PROTO_ICMP; net_ipaddr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr); net_ipaddr_hdrcopy(picmp->destipaddr, destaddr); /* Calculate IP checksum. */ picmp->ipchksum = 0; picmp->ipchksum = ~(ip_chksum(dev)); #endif /* CONFIG_NET_IPv6 */ /* Calculate the ICMP checksum. */ picmp->icmpchksum = 0; picmp->icmpchksum = ~(icmp_chksum(dev, dev->d_sndlen)); if (picmp->icmpchksum == 0) { picmp->icmpchksum = 0xffff; } nllvdbg("Outgoing ICMP packet length: %d (%d)\n", dev->d_len, (picmp->len[0] << 8) | picmp->len[1]); #ifdef CONFIG_NET_STATISTICS g_netstats.icmp.sent++; g_netstats.ip.sent++; #endif }