bug fixes for hlen
[unix-history] / usr / src / sys / netinet / udp_usrreq.c
index 0674bbe..922e4cb 100644 (file)
@@ -1,4 +1,4 @@
-/*     udp_usrreq.c    4.6     81/11/18        */
+/*     udp_usrreq.c    4.14    81/12/03        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
@@ -7,10 +7,9 @@
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
-#include "../net/inet.h"
-#include "../net/inet_host.h"
-#include "../net/inet_pcb.h"
-#include "../net/inet_systm.h"
+#include "../net/in.h"
+#include "../net/in_pcb.h"
+#include "../net/in_systm.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 #include "../net/udp.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 #include "../net/udp.h"
@@ -23,6 +22,7 @@
 udp_init()
 {
 
 udp_init()
 {
 
+COUNT(UDP_INIT);
        udb.inp_next = udb.inp_prev = &udb;
 }
 
        udb.inp_next = udb.inp_prev = &udb;
 }
 
@@ -37,24 +37,25 @@ udp_input(m0)
        register struct mbuf *m;
        int len, ulen;
 
        register struct mbuf *m;
        int len, ulen;
 
+COUNT(UDP_INPUT);
        /*
         * Get ip and udp header together in first mbuf.
         */
        m = m0;
        /*
         * Get ip and udp header together in first mbuf.
         */
        m = m0;
-       ui = mtod(m, struct udpiphdr *);
-       if (ui->ui_len > sizeof (struct ip))
-               ip_stripoptions((struct ip *)ui);
        if (m->m_len < sizeof (struct udpiphdr) &&
            m_pullup(m, sizeof (struct udpiphdr)) == 0) {
                udpstat.udps_hdrops++;
                goto bad;
        }
        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.
         */
 
        /*
         * Make mbuf data length reflect udp length.
         * If not enough data to reflect udp length, drop.
         */
-       ulen = ntohs(ui->ui_ulen);
+       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) {
        len = sizeof (struct udpiphdr) + ulen;
        if (((struct ip *)ui)->ip_len != len) {
                if (len > ((struct ip *)ui)->ip_len) {
@@ -71,8 +72,8 @@ udp_input(m0)
        if (udpcksum) {
                ui->ui_next = ui->ui_prev = 0;
                ui->ui_x1 = 0;
        if (udpcksum) {
                ui->ui_next = ui->ui_prev = 0;
                ui->ui_x1 = 0;
-               ui->ui_len = htons(sizeof (struct udpiphdr) + ulen);
-               if (ui->ui_sum = inet_cksum(m, len)) {
+               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);
                        udpstat.udps_badsum++;
                        printf("udp cksum %x\n", ui->ui_sum);
                        m_freem(m);
@@ -84,10 +85,6 @@ udp_input(m0)
         * Convert addresses and ports to host format.
         * Locate pcb for datagram.
         */
         * Convert addresses and ports to host format.
         * Locate pcb for datagram.
         */
-       ui->ui_src.s_addr = ntohl(ui->ui_src.s_addr);
-       ui->ui_dst.s_addr = ntohl(ui->ui_dst.s_addr);
-       ui->ui_sport = ntohs(ui->ui_sport);
-       ui->ui_dport = ntohs(ui->ui_dport);
        inp = in_pcblookup(&udb,
            ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport);
        if (inp == 0)
        inp = in_pcblookup(&udb,
            ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport);
        if (inp == 0)
@@ -99,8 +96,11 @@ udp_input(m0)
         */
        udp_in.sin_port = ui->ui_sport;
        udp_in.sin_addr = ui->ui_src;
         */
        udp_in.sin_port = ui->ui_sport;
        udp_in.sin_addr = ui->ui_src;
-       if (sbappendaddr(inp->inp_socket, &udp_in, m) == 0)
+       m->m_len -= sizeof (struct udpiphdr);
+       m->m_off += sizeof (struct udpiphdr);
+       if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in, m) == 0)
                goto bad;
                goto bad;
+       sorwakeup(inp->inp_socket);
        return;
 bad:
        m_freem(m);
        return;
 bad:
        m_freem(m);
@@ -110,20 +110,21 @@ udp_ctlinput(m)
        struct mbuf *m;
 {
 
        struct mbuf *m;
 {
 
+COUNT(UDP_CTLINPUT);
+       printf("udp_ctlinput\n");
        m_freem(m);
 }
 
 /*ARGSUSED*/
        m_freem(m);
 }
 
 /*ARGSUSED*/
-udp_output(inp, raddr, rport, m0)
+udp_output(inp, m0)
        struct inpcb *inp;
        struct inpcb *inp;
-       struct in_addr *raddr;
-       u_short rport;
        struct mbuf *m0;
 {
        register struct mbuf *m;
        register struct udpiphdr *ui;
        register int len = 0;
 
        struct mbuf *m0;
 {
        register struct mbuf *m;
        register struct udpiphdr *ui;
        register int len = 0;
 
+COUNT(UDP_OUTPUT);
        /*
         * Calculate data length and get a mbuf
         * for udp and ip headers.
        /*
         * Calculate data length and get a mbuf
         * for udp and ip headers.
@@ -145,19 +146,21 @@ udp_output(inp, raddr, rport, m0)
        ui->ui_next = ui->ui_prev = 0;
        ui->ui_x1 = 0;
        ui->ui_pr = IPPROTO_UDP;
        ui->ui_next = ui->ui_prev = 0;
        ui->ui_x1 = 0;
        ui->ui_pr = IPPROTO_UDP;
-       ui->ui_len = htons(sizeof (struct udphdr) + len);
-       ui->ui_src.s_addr = htonl(inp->inp_lhost);
-       ui->ui_dst.s_addr = htonl(raddr->s_addr);
-       ui->ui_sport = htons(inp->inp_lport);
-       ui->ui_dport = htons(inp->inp_fport);
-       ui->ui_ulen = htons(len);
+       ui->ui_len = sizeof (struct udpiphdr) + len;
+       ui->ui_src = inp->inp_laddr;
+       ui->ui_dst = inp->inp_faddr;
+       ui->ui_sport = inp->inp_lport;
+       ui->ui_dport = inp->inp_fport;
+       ui->ui_ulen = htons((u_short)len);
 
        /*
         * Stuff checksum and output datagram.
         */
        ui->ui_sum = 0;
 
        /*
         * Stuff checksum and output datagram.
         */
        ui->ui_sum = 0;
-       ui->ui_sum = inet_cksum(m, sizeof (struct udpiphdr) + len);
-       ip_output(m);
+       ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len);
+       ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
+       ((struct ip *)ui)->ip_ttl = MAXTTL;
+       (void) ip_output(m, (struct mbuf *)0);
        return;
 bad:
        m_freem(m);
        return;
 bad:
        m_freem(m);
@@ -171,31 +174,32 @@ udp_usrreq(so, req, m, addr)
        caddr_t addr;
 {
        struct inpcb *inp = sotoinpcb(so);
        caddr_t addr;
 {
        struct inpcb *inp = sotoinpcb(so);
-       struct sockaddr_in *sin;
        int error;
 
        int error;
 
+COUNT(UDP_USRREQ);
+       if (inp == 0 && req != PRU_ATTACH)
+               return (EINVAL);
        switch (req) {
 
        case PRU_ATTACH:
                if (inp != 0)
                        return (EINVAL);
        switch (req) {
 
        case PRU_ATTACH:
                if (inp != 0)
                        return (EINVAL);
-               inp = in_pcballoc();
-               if (inp == NULL)
-                       return (ENOBUFS);
-               so->so_pcb = (caddr_t)inp;
+               error = in_pcbattach(so, &udb, 2048, 2048, (struct sockaddr_in *)addr);
+               if (error)
+                       return (error);
                break;
 
        case PRU_DETACH:
                if (inp == 0)
                        return (ENOTCONN);
                break;
 
        case PRU_DETACH:
                if (inp == 0)
                        return (ENOTCONN);
-               in_pcbfree(inp);
+               in_pcbdetach(inp);
                break;
 
        case PRU_CONNECT:
                break;
 
        case PRU_CONNECT:
-               if (inp->inp_fhost)
+               if (inp->inp_faddr.s_addr)
                        return (EISCONN);
                        return (EISCONN);
-               in_hosteval(inp, (struct sockaddr *)addr, &error);
-               if (inp->inp_fhost == 0)
+               error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
+               if (error)
                        return (error);
                soisconnected(so);
                break;
                        return (error);
                soisconnected(so);
                break;
@@ -204,10 +208,9 @@ udp_usrreq(so, req, m, addr)
                return (EOPNOTSUPP);
 
        case PRU_DISCONNECT:
                return (EOPNOTSUPP);
 
        case PRU_DISCONNECT:
-               if (inp->inp_fhost == 0)
+               if (inp->inp_faddr.s_addr == 0)
                        return (ENOTCONN);
                        return (ENOTCONN);
-               in_hostfree(inp->inp_fhost);
-               inp->inp_fhost = 0;
+               in_pcbdisconnect(inp);
                soisdisconnected(so);
                break;
 
                soisdisconnected(so);
                break;
 
@@ -217,19 +220,22 @@ udp_usrreq(so, req, m, addr)
 
        case PRU_SEND:
                if (addr) {
 
        case PRU_SEND:
                if (addr) {
-                       if (inp->inp_fhost)
+                       if (inp->inp_faddr.s_addr)
                                return (EISCONN);
                                return (EISCONN);
-                       sin = (struct sockaddr_in *)addr;
-                       if (sin->sin_family != AF_INET)
-                               return (EAFNOSUPPORT);
-                       udp_output(inp, sin->sin_addr, sin->sin_port, m);
-               } else
-                       udp_output(inp,
-                           inp->inp_fhost->h_addr, inp->inp_fport, m);
+                       error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
+                       if (error)
+                               return (error);
+               } else {
+                       if (inp->inp_faddr.s_addr == 0)
+                               return (ENOTCONN);
+               }
+               udp_output(inp, m);
+               if (addr)
+                       in_pcbdisconnect(inp);
                break;
 
        case PRU_ABORT:
                break;
 
        case PRU_ABORT:
-               in_pcbfree(inp);
+               in_pcbdetach(inp);
                sofree(so);
                soisdisconnected(so);
                break;
                sofree(so);
                soisdisconnected(so);
                break;
@@ -242,10 +248,3 @@ udp_usrreq(so, req, m, addr)
        }
        return (0);
 }
        }
        return (0);
 }
-
-udp_sense(m)
-       struct mbuf *m;
-{
-       return (EOPNOTSUPP);
-
-}