+ register struct udpiphdr *ui;
+ register struct inpcb *inp;
+ register struct mbuf *m;
+ int len, ulen;
+
+COUNT(UDP_INPUT);
+ /*
+ * Get ip and udp header together in first mbuf.
+ */
+ m = m0;
+ if (m->m_len < sizeof (struct udpiphdr) &&
+ m_pullup(m, sizeof (struct udpiphdr)) == 0) {
+ udpstat.udps_hdrops++;
+ goto bad;
+ }
+ ui = mtod(m, struct udpiphdr *);
+ if (ui->ui_len > sizeof (struct ip))
+ ip_stripoptions((struct ip *)ui, (char *)0);
+
+ /*
+ * Make mbuf data length reflect udp length.
+ * If not enough data to reflect udp length, drop.
+ */
+ ulen = ntohs((u_short)ui->ui_ulen);
+ len = sizeof (struct udpiphdr) + ulen;
+ if (((struct ip *)ui)->ip_len != len) {
+ if (len > ((struct ip *)ui)->ip_len) {
+ udpstat.udps_badlen++;
+ goto bad;
+ }
+ m_adj(m, ((struct ip *)ui)->ip_len - len);
+ /* (struct ip *)ui->ip_len = len; */
+ }
+
+ /*
+ * Checksum extended udp header and data.
+ */
+ if (udpcksum) {
+ ui->ui_next = ui->ui_prev = 0;
+ ui->ui_x1 = 0;
+ ui->ui_len = htons((u_short)(sizeof (struct udpiphdr) + ulen));
+ if ((ui->ui_sum = in_cksum(m, len)) != 0xffff) {
+ udpstat.udps_badsum++;
+ printf("udp cksum %x\n", ui->ui_sum);
+ m_freem(m);
+ return;
+ }
+ }
+
+ /*
+ * Convert addresses and ports to host format.
+ * Locate pcb for datagram.
+ */
+ inp = in_pcblookup(&udb,
+ ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport);
+ if (inp == 0)
+ goto bad;