/* Setup IPv4 + UDP header */ static void setup_header(struct net_buf *buf) { struct net_ipv4_hdr *ipv4; struct net_udp_hdr *udp; uint16_t len; ipv4 = NET_IPV4_BUF(buf); udp = NET_UDP_BUF(buf); len = net_buf_frags_len(buf->frags); /* Setup IPv4 header */ memset(ipv4, 0, sizeof(struct net_ipv4_hdr)); ipv4->vhl = 0x45; ipv4->ttl = 0xFF; ipv4->proto = IPPROTO_UDP; ipv4->len[0] = len >> 8; ipv4->len[1] = (uint8_t)len; ipv4->chksum = ~net_calc_chksum_ipv4(buf); net_ipaddr_copy(&ipv4->dst, net_ipv4_broadcast_address()); len -= NET_IPV4H_LEN; /* Setup UDP header */ udp->src_port = htons(DHCPV4_CLIENT_PORT); udp->dst_port = htons(DHCPV4_SERVER_PORT); udp->len = htons(len); udp->chksum = ~net_calc_chksum_udp(buf); }
enum net_verdict net_ipv4_process_pkt(struct net_pkt *pkt) { struct net_ipv4_hdr *hdr = NET_IPV4_HDR(pkt); int real_len = net_pkt_get_len(pkt); int pkt_len = (hdr->len[0] << 8) + hdr->len[1]; enum net_verdict verdict = NET_DROP; if (real_len != pkt_len) { NET_DBG("IPv4 packet size %d pkt len %d", pkt_len, real_len); goto drop; } #if defined(CONFIG_NET_DEBUG_IPV4) do { char out[sizeof("xxx.xxx.xxx.xxx")]; snprintk(out, sizeof(out), "%s", net_sprint_ipv4_addr(&hdr->dst)); NET_DBG("IPv4 packet received from %s to %s", net_sprint_ipv4_addr(&hdr->src), out); } while (0); #endif /* CONFIG_NET_DEBUG_IPV4 */ net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr)); if (!net_is_my_ipv4_addr(&hdr->dst)) { #if defined(CONFIG_NET_DHCPV4) if (hdr->proto == IPPROTO_UDP && net_ipv4_addr_cmp(&hdr->dst, net_ipv4_broadcast_address())) { verdict = net_conn_input(IPPROTO_UDP, pkt); if (verdict != NET_DROP) { return verdict; } } #endif NET_DBG("IPv4 packet in pkt %p not for me", pkt); goto drop; } switch (hdr->proto) { case IPPROTO_ICMP: verdict = process_icmpv4_pkt(pkt, hdr); break; case IPPROTO_UDP: verdict = net_conn_input(IPPROTO_UDP, pkt); break; case IPPROTO_TCP: verdict = net_conn_input(IPPROTO_TCP, pkt); break; } if (verdict != NET_DROP) { return verdict; } drop: net_stats_update_ipv4_drop(); return NET_DROP; }