[BACK]Return to udp_usrreq.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/netinet/udp_usrreq.c between version 1.35 and 1.47

version 1.35, 1996/09/15 18:11:11 version 1.47, 1999/01/19 23:03:22
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*  /*
  * Copyright (c) 1982, 1986, 1988, 1990, 1993   * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
  *      The Regents of the University of California.  All rights reserved.   *      The Regents of the University of California.  All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 32 
Line 32 
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.   * SUCH DAMAGE.
  *   *
  *      @(#)udp_usrreq.c        8.4 (Berkeley) 1/21/94   *      @(#)udp_usrreq.c        8.6 (Berkeley) 5/23/95
  */   */
   #include "ipkdb.h"
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/malloc.h>  #include <sys/malloc.h>
Line 75  int udpcksum = 0;  /* XXX */
Line 76  int udpcksum = 0;  /* XXX */
 #endif  #endif
   
 static  void udp_notify __P((struct inpcb *, int));  static  void udp_notify __P((struct inpcb *, int));
 static  struct mbuf *udp_saveopt __P((caddr_t, int, int));  
   
 #ifndef UDBHASHSIZE  #ifndef UDBHASHSIZE
 #define UDBHASHSIZE     128  #define UDBHASHSIZE     128
Line 143  udp_input(m, va_alist)
Line 143  udp_input(m, va_alist)
          * If not enough data to reflect UDP length, drop.           * If not enough data to reflect UDP length, drop.
          */           */
         len = ntohs((u_int16_t)uh->uh_ulen);          len = ntohs((u_int16_t)uh->uh_ulen);
         if (ip->ip_len != len) {          if (ip->ip_len != iphlen + len) {
                 if (len > ip->ip_len) {                  if (ip->ip_len < iphlen + len) {
                         udpstat.udps_badlen++;                          udpstat.udps_badlen++;
                         goto bad;                          goto bad;
                 }                  }
                 m_adj(m, len - ip->ip_len);                  m_adj(m, iphlen + len - ip->ip_len);
                 /* ip->ip_len = len; */  
         }          }
         /*          /*
          * Save a copy of the IP header in case we want restore it           * Save a copy of the IP header in case we want restore it
Line 164  udp_input(m, va_alist)
Line 163  udp_input(m, va_alist)
                 bzero(((struct ipovly *)ip)->ih_x1,                  bzero(((struct ipovly *)ip)->ih_x1,
                     sizeof ((struct ipovly *)ip)->ih_x1);                      sizeof ((struct ipovly *)ip)->ih_x1);
                 ((struct ipovly *)ip)->ih_len = uh->uh_ulen;                  ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
                 if ((uh->uh_sum = in_cksum(m, len + sizeof (struct ip))) != 0) {                  if (in_cksum(m, len + sizeof (struct ip)) != 0) {
                         udpstat.udps_badsum++;                          udpstat.udps_badsum++;
                         m_freem(m);                          m_freem(m);
                         return;                          return;
Line 173  udp_input(m, va_alist)
Line 172  udp_input(m, va_alist)
   
         if (IN_MULTICAST(ip->ip_dst.s_addr) ||          if (IN_MULTICAST(ip->ip_dst.s_addr) ||
             in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {              in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
                 struct socket *last;                  struct inpcb *last;
                 /*                  /*
                  * Deliver a multicast or broadcast datagram to *all* sockets                   * Deliver a multicast or broadcast datagram to *all* sockets
                  * for which the local and remote addresses and ports match                   * for which the local and remote addresses and ports match
Line 195  udp_input(m, va_alist)
Line 194  udp_input(m, va_alist)
                  */                   */
                 udpsrc.sin_family = AF_INET;                  udpsrc.sin_family = AF_INET;
                 udpsrc.sin_len = sizeof(struct sockaddr_in);                  udpsrc.sin_len = sizeof(struct sockaddr_in);
                 udpsrc.sin_port = uh->uh_sport;  
                 udpsrc.sin_addr = ip->ip_src;                  udpsrc.sin_addr = ip->ip_src;
                   udpsrc.sin_port = uh->uh_sport;
                   bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero));
   
                 m->m_len -= sizeof (struct udpiphdr);                  iphlen += sizeof(struct udphdr);
                 m->m_data += sizeof (struct udpiphdr);                  m->m_len -= iphlen;
                   m->m_pkthdr.len -= iphlen;
                   m->m_data += iphlen;
                 /*                  /*
                  * Locate pcb(s) for datagram.                   * Locate pcb(s) for datagram.
                  * (Algorithm copied from raw_intr().)                   * (Algorithm copied from raw_intr().)
Line 224  udp_input(m, va_alist)
Line 226  udp_input(m, va_alist)
                                 struct mbuf *n;                                  struct mbuf *n;
   
                                 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {                                  if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
                                         if (sbappendaddr(&last->so_rcv,                                          if (last->inp_flags & INP_CONTROLOPTS
                                                 sintosa(&udpsrc), n,                                              || last->inp_socket->so_options &
                                                 (struct mbuf *)0) == 0) {                                                 SO_TIMESTAMP) {
                                                   ip_savecontrol(last, &opts,
                                                       ip, n);
                                           }
                                           if (sbappendaddr(
                                               &last->inp_socket->so_rcv,
                                               sintosa(&udpsrc), n, opts) == 0) {
                                                 m_freem(n);                                                  m_freem(n);
                                                 udpstat.udps_fullsock++;                                                  if (opts)
                                                           m_freem(opts);
                                         } else                                          } else
                                                 sorwakeup(last);                                                  sorwakeup(last->inp_socket);
                                           opts = 0;
                                 }                                  }
                         }                          }
                         last = inp->inp_socket;                          last = inp;
                         /*                          /*
                          * Don't look for additional matches if this one does                           * Don't look for additional matches if this one does
                          * not have either the SO_REUSEPORT or SO_REUSEADDR                           * not have either the SO_REUSEPORT or SO_REUSEADDR
Line 242  udp_input(m, va_alist)
Line 252  udp_input(m, va_alist)
                          * port.  It * assumes that an application will never                           * port.  It * assumes that an application will never
                          * clear these options after setting them.                           * clear these options after setting them.
                          */                           */
                         if ((last->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0)                          if ((last->inp_socket->so_options &
                               (SO_REUSEPORT|SO_REUSEADDR)) == 0)
                                 break;                                  break;
                 }                  }
   
Line 255  udp_input(m, va_alist)
Line 266  udp_input(m, va_alist)
                         udpstat.udps_noportbcast++;                          udpstat.udps_noportbcast++;
                         goto bad;                          goto bad;
                 }                  }
                 if (sbappendaddr(&last->so_rcv, sintosa(&udpsrc), m,                  if (last->inp_flags & INP_CONTROLOPTS ||
                     (struct mbuf *)0) == 0) {                      last->inp_socket->so_options & SO_TIMESTAMP)
                           ip_savecontrol(last, &opts, ip, m);
                   if (sbappendaddr(&last->inp_socket->so_rcv,
                       sintosa(&udpsrc), m, opts) == 0) {
                         udpstat.udps_fullsock++;                          udpstat.udps_fullsock++;
                         goto bad;                          goto bad;
                 }                  }
                 sorwakeup(last);                  sorwakeup(last->inp_socket);
                 return;                  return;
         }          }
         /*          /*
Line 278  udp_input(m, va_alist)
Line 292  udp_input(m, va_alist)
                                 goto bad;                                  goto bad;
                         }                          }
                         *ip = save_ip;                          *ip = save_ip;
                         ip->ip_len += iphlen;  #if NIPKDB > 0
                           if (checkipkdb(&ip->ip_src,
                                          uh->uh_sport,
                                          uh->uh_dport,
                                          m,
                                          iphlen + sizeof(struct udphdr),
                                          len - sizeof(struct udphdr)))
                           /* It was a debugger connect packet, just drop it now */
                                   goto bad;
   #endif
                         icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);                          icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
                         return;                          return;
                 }                  }
Line 290  udp_input(m, va_alist)
Line 313  udp_input(m, va_alist)
          */           */
         udpsrc.sin_family = AF_INET;          udpsrc.sin_family = AF_INET;
         udpsrc.sin_len = sizeof(struct sockaddr_in);          udpsrc.sin_len = sizeof(struct sockaddr_in);
         udpsrc.sin_port = uh->uh_sport;  
         udpsrc.sin_addr = ip->ip_src;          udpsrc.sin_addr = ip->ip_src;
           udpsrc.sin_port = uh->uh_sport;
           bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero));
   
         if (inp->inp_flags & INP_CONTROLOPTS) {          if (inp->inp_flags & INP_CONTROLOPTS ||
                 struct mbuf **mp = &opts;              inp->inp_socket->so_options & SO_TIMESTAMP)
                   ip_savecontrol(inp, &opts, ip, m);
                 if (inp->inp_flags & INP_RECVDSTADDR) {  
                         *mp = udp_saveopt((caddr_t) &ip->ip_dst,  
                             sizeof(struct in_addr), IP_RECVDSTADDR);  
                         if (*mp)  
                                 mp = &(*mp)->m_next;  
                 }  
 #ifdef notyet  
                 /* options were tossed above */  
                 if (inp->inp_flags & INP_RECVOPTS) {  
                         *mp = udp_saveopt((caddr_t) opts_deleted_above,  
                             sizeof(struct in_addr), IP_RECVOPTS);  
                         if (*mp)  
                                 mp = &(*mp)->m_next;  
                 }  
                 /* ip_srcroute doesn't do what we want here, need to fix */  
                 if (inp->inp_flags & INP_RECVRETOPTS) {  
                         *mp = udp_saveopt((caddr_t) ip_srcroute(),  
                             sizeof(struct in_addr), IP_RECVRETOPTS);  
                         if (*mp)  
                                 mp = &(*mp)->m_next;  
                 }  
 #endif  
         }  
         iphlen += sizeof(struct udphdr);          iphlen += sizeof(struct udphdr);
         m->m_len -= iphlen;          m->m_len -= iphlen;
         m->m_pkthdr.len -= iphlen;          m->m_pkthdr.len -= iphlen;
Line 337  bad:
Line 338  bad:
 }  }
   
 /*  /*
  * Create a "control" mbuf containing the specified data  
  * with the specified type for presentation with a datagram.  
  */  
 struct mbuf *  
 udp_saveopt(p, size, type)  
         caddr_t p;  
         register int size;  
         int type;  
 {  
         register struct cmsghdr *cp;  
         struct mbuf *m;  
   
         if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)  
                 return ((struct mbuf *) NULL);  
         cp = (struct cmsghdr *) mtod(m, struct cmsghdr *);  
         bcopy(p, CMSG_DATA(cp), size);  
         size += sizeof(*cp);  
         m->m_len = size;  
         cp->cmsg_len = size;  
         cp->cmsg_level = IPPROTO_IP;  
         cp->cmsg_type = type;  
         return (m);  
 }  
   
 /*  
  * Notify a udp user of an asynchronous error;   * Notify a udp user of an asynchronous error;
  * just wake up so that he can collect error status.   * just wake up so that he can collect error status.
  */   */
Line 437  udp_output(m, va_alist)
Line 413  udp_output(m, va_alist)
         }          }
   
         /*          /*
            * Compute the packet length of the IP header, and
            * punt if the length looks bogus.
            */
           if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
                   error = EMSGSIZE;
                   goto release;
           }
   
           /*
          * Fill in mbuf with extended UDP header           * Fill in mbuf with extended UDP header
          * and addresses and length put into network format.           * and addresses and length put into network format.
          */           */
Line 471  release:
Line 456  release:
         return (error);          return (error);
 }  }
   
 u_long  udp_sendspace = 9216;           /* really max datagram size */  int     udp_sendspace = 9216;           /* really max datagram size */
 u_long  udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));  int     udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
                                         /* 40 1K datagrams */                                          /* 40 1K datagrams */
   
 /*ARGSUSED*/  /*ARGSUSED*/
Line 654  udp_sysctl(name, namelen, oldp, oldlenp,
Line 639  udp_sysctl(name, namelen, oldp, oldlenp,
         switch (name[0]) {          switch (name[0]) {
         case UDPCTL_CHECKSUM:          case UDPCTL_CHECKSUM:
                 return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum));                  return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum));
           case UDPCTL_SENDSPACE:
                   return (sysctl_int(oldp, oldlenp, newp, newlen,
                       &udp_sendspace));
           case UDPCTL_RECVSPACE:
                   return (sysctl_int(oldp, oldlenp, newp, newlen,
                       &udp_recvspace));
         default:          default:
                 return (ENOPROTOOPT);                  return (ENOPROTOOPT);
         }          }

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.47

CVSweb <webmaster@jp.NetBSD.org>