inline size_t Packet_v<Ptr_type>::fill(const uint8_t* buffer, size_t length) { size_t rem = ip_capacity() - udp_length(); if(rem == 0) return 0; size_t total = std::min(length, rem); // copy from buffer to packet buffer memcpy(udp_data() + udp_data_length(), buffer, total); // set new packet length set_length(udp_data_length() + total); return total; }
static int udp_rcv(struct sk_buff *skb) { struct sock *sk; assert(skb != NULL); assert(ip_check_version(ip_hdr(skb)) || ip6_check_version(ip6_hdr(skb))); /* Check CRC */ if (MODOPS_VERIFY_CHKSUM) { uint16_t old_check; old_check = skb->h.uh->check; udp_set_check_field(skb->h.uh, skb->nh.raw); if (old_check != skb->h.uh->check) { return 0; /* error: bad checksum */ } } sk = sock_lookup(NULL, udp_sock_ops, ip_check_version(ip_hdr(skb)) ? udp4_rcv_tester : udp6_rcv_tester, skb); if (sk != NULL) { if (ip_check_version(ip_hdr(skb)) ? udp4_accept_dst(sk, skb) : udp6_accept_dst(sk, skb)) { sock_rcv(sk, skb, skb->h.raw + UDP_HEADER_SIZE, udp_data_length(udp_hdr(skb))); } else { skb_free(skb); } } else { icmp_discard(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH); } return 0; }
uint16_t udp_length() const noexcept { return udp_header_length() + udp_data_length(); }