+ /*
+ * Checksum extended UDP header and data.
+ */
+ if (udpcksum && ui->ui_sum) {
+ ui->ui_next = ui->ui_prev = 0;
+ ui->ui_x1 = 0;
+ ui->ui_len = ui->ui_ulen;
+ if (ui->ui_sum = in_cksum(m, len + sizeof (struct ip))) {
+ udpstat.udps_badsum++;
+ m_freem(m);
+ return;
+ }
+ }
+
+ /*
+ * Locate pcb for datagram.
+ */
+ inp = in_pcblookup(&udb,
+ ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport,
+ INPLOOKUP_WILDCARD);
+ if (inp == 0) {
+ /* don't send ICMP response for broadcast packet */
+ if (m->m_flags & M_BCAST)
+ goto bad;
+ *(struct ip *)ui = ip;
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT);
+ return;
+ }
+
+ /*
+ * Construct sockaddr format source address.
+ * Stuff source address and datagram in user buffer.
+ */
+ udp_in.sin_port = ui->ui_sport;
+ udp_in.sin_addr = ui->ui_src;
+ m->m_len -= sizeof (struct udpiphdr);
+ m->m_pkthdr.len -= sizeof (struct udpiphdr);
+ m->m_data += sizeof (struct udpiphdr);
+ if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in,
+ m, (struct mbuf *)0) == 0)
+ goto bad;
+ sorwakeup(inp->inp_socket);
+ return;
+bad: