[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.29.2.2 and 1.30

version 1.29.2.2, 1996/12/11 04:01:12 version 1.30, 1996/05/22 13:55:37
Line 76  int udpcksum = 0;  /* XXX */
Line 76  int udpcksum = 0;  /* XXX */
   
 struct  sockaddr_in udp_in = { sizeof(udp_in), AF_INET };  struct  sockaddr_in udp_in = { sizeof(udp_in), AF_INET };
   
   static  void udp_detach __P((struct inpcb *));
 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));  static  struct mbuf *udp_saveopt __P((caddr_t, int, int));
   
Line 413  udp_output(m, va_alist)
Line 414  udp_output(m, va_alist)
 #endif  #endif
 {  {
         register struct inpcb *inp;          register struct inpcb *inp;
           struct mbuf *addr, *control;
         register struct udpiphdr *ui;          register struct udpiphdr *ui;
         register int len = m->m_pkthdr.len;          register int len = m->m_pkthdr.len;
         int error = 0;          struct in_addr laddr;
           int s = 0, error = 0;
         va_list ap;          va_list ap;
   
         va_start(ap, m);          va_start(ap, m);
         inp = va_arg(ap, struct inpcb *);          inp = va_arg(ap, struct inpcb *);
           addr = va_arg(ap, struct mbuf *);
           control = va_arg(ap, struct mbuf *);
         va_end(ap);          va_end(ap);
   
           if (control)
                   m_freem(control);               /* XXX */
   
           if (addr) {
                   laddr = inp->inp_laddr;
                   if (inp->inp_faddr.s_addr != INADDR_ANY) {
                           error = EISCONN;
                           goto release;
                   }
                   /*
                    * Must block input while temporarily connected.
                    */
                   s = splsoftnet();
                   error = in_pcbconnect(inp, addr);
                   if (error) {
                           splx(s);
                           goto release;
                   }
           } else {
                   if (inp->inp_faddr.s_addr == INADDR_ANY) {
                           error = ENOTCONN;
                           goto release;
                   }
           }
         /*          /*
          * Calculate data length and get a mbuf           * Calculate data length and get a mbuf
          * for UDP and IP headers.           * for UDP and IP headers.
Line 433  udp_output(m, va_alist)
Line 462  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 467  udp_output(m, va_alist)
Line 487  udp_output(m, va_alist)
         ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */          ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */
         ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */          ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */
         udpstat.udps_opackets++;          udpstat.udps_opackets++;
         return (ip_output(m, inp->inp_options, &inp->inp_route,          error = ip_output(m, inp->inp_options, &inp->inp_route,
             inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),              inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
             inp->inp_moptions));              inp->inp_moptions);
   
           if (addr) {
                   in_pcbdisconnect(inp);
                   inp->inp_laddr = laddr;
                   splx(s);
           }
           return (error);
   
 release:  release:
         m_freem(m);          m_freem(m);
Line 482  u_long udp_recvspace = 40 * (1024 + size
Line 509  u_long udp_recvspace = 40 * (1024 + size
   
 /*ARGSUSED*/  /*ARGSUSED*/
 int  int
 udp_usrreq(so, req, m, nam, control, p)  udp_usrreq(so, req, m, addr, control, p)
         struct socket *so;          struct socket *so;
         int req;          int req;
         struct mbuf *m, *nam, *control;          struct mbuf *m, *addr, *control;
         struct proc *p;          struct proc *p;
 {  {
         register struct inpcb *inp;          struct inpcb *inp = sotoinpcb(so);
           int error = 0;
         int s;          int s;
         register int error = 0;  
   
         if (req == PRU_CONTROL)          if (req == PRU_CONTROL)
                 return (in_control(so, (long)m, (caddr_t)nam,                  return (in_control(so, (long)m, (caddr_t)addr,
                     (struct ifnet *)control, p));                      (struct ifnet *)control, p));
           if (inp == NULL && req != PRU_ATTACH) {
         s = splsoftnet();  
         inp = sotoinpcb(so);  
 #ifdef DIAGNOSTIC  
         if (req != PRU_SEND && req != PRU_SENDOOB && control)  
                 panic("udp_usrreq: unexpected control mbuf");  
 #endif  
         if (inp == 0 && req != PRU_ATTACH) {  
                 error = EINVAL;                  error = EINVAL;
                 goto release;                  goto release;
         }          }
   
         /*          /*
          * Note: need to block udp_input while changing           * Note: need to block udp_input while changing
          * the udp pcb queue and/or pcb addresses.           * the udp pcb queue and/or pcb addresses.
Line 514  udp_usrreq(so, req, m, nam, control, p)
Line 533  udp_usrreq(so, req, m, nam, control, p)
         switch (req) {          switch (req) {
   
         case PRU_ATTACH:          case PRU_ATTACH:
                 if (inp != 0) {                  if (inp != NULL) {
                         error = EISCONN;                          error = EINVAL;
                         break;                          break;
                 }                  }
                 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {                  s = splsoftnet();
                         error = soreserve(so, udp_sendspace, udp_recvspace);  
                         if (error)  
                                 break;  
                 }  
                 error = in_pcballoc(so, &udbtable);                  error = in_pcballoc(so, &udbtable);
                   splx(s);
                   if (error)
                           break;
                   error = soreserve(so, udp_sendspace, udp_recvspace);
                 if (error)                  if (error)
                         break;                          break;
                 inp = sotoinpcb(so);                  ((struct inpcb *) so->so_pcb)->inp_ip.ip_ttl = ip_defttl;
                 inp->inp_ip.ip_ttl = ip_defttl;  
                 break;                  break;
   
         case PRU_DETACH:          case PRU_DETACH:
                 in_pcbdetach(inp);                  udp_detach(inp);
                 break;                  break;
   
         case PRU_BIND:          case PRU_BIND:
                 error = in_pcbbind(inp, nam, p);                  s = splsoftnet();
                   error = in_pcbbind(inp, addr, p);
                   splx(s);
                 break;                  break;
   
         case PRU_LISTEN:          case PRU_LISTEN:
Line 543  udp_usrreq(so, req, m, nam, control, p)
Line 563  udp_usrreq(so, req, m, nam, control, p)
                 break;                  break;
   
         case PRU_CONNECT:          case PRU_CONNECT:
                 error = in_pcbconnect(inp, nam);                  if (inp->inp_faddr.s_addr != INADDR_ANY) {
                 if (error)                          error = EISCONN;
                         break;                          break;
                 soisconnected(so);                  }
                   s = splsoftnet();
                   error = in_pcbconnect(inp, addr);
                   splx(s);
                   if (error == 0)
                           soisconnected(so);
                 break;                  break;
   
         case PRU_CONNECT2:          case PRU_CONNECT2:
                 error = EOPNOTSUPP;                  error = EOPNOTSUPP;
                 break;                  break;
   
           case PRU_ACCEPT:
                   error = EOPNOTSUPP;
                   break;
   
         case PRU_DISCONNECT:          case PRU_DISCONNECT:
                 /*soisdisconnected(so);*/                  if (inp->inp_faddr.s_addr == INADDR_ANY) {
                 so->so_state &= ~SS_ISCONNECTED;        /* XXX */                          error = ENOTCONN;
                           break;
                   }
                   s = splsoftnet();
                 in_pcbdisconnect(inp);                  in_pcbdisconnect(inp);
                 inp->inp_laddr.s_addr = INADDR_ANY;     /* XXX */                  inp->inp_laddr.s_addr = INADDR_ANY;
                   splx(s);
                   so->so_state &= ~SS_ISCONNECTED;                /* XXX */
                 break;                  break;
   
         case PRU_SHUTDOWN:          case PRU_SHUTDOWN:
                 socantsendmore(so);                  socantsendmore(so);
                 break;                  break;
   
         case PRU_RCVD:          case PRU_SEND:
                 error = EOPNOTSUPP;                  return (udp_output(m, inp, addr, control));
   
           case PRU_ABORT:
                   soisdisconnected(so);
                   udp_detach(inp);
                 break;                  break;
   
         case PRU_SEND:          case PRU_SOCKADDR:
                 if (control && control->m_len) {                  in_setsockaddr(inp, addr);
                         m_freem(control);                  break;
                         m_freem(m);  
                         error = EINVAL;  
                         break;  
                 }  
         {  
                 struct in_addr laddr;  
   
                 if (nam) {          case PRU_PEERADDR:
                         laddr = inp->inp_laddr;                  in_setpeeraddr(inp, addr);
                         if ((so->so_state & SS_ISCONNECTED) != 0) {  
                                 error = EISCONN;  
                                 goto die;  
                         }  
                         error = in_pcbconnect(inp, nam);  
                         if (error) {  
                         die:  
                                 m_freem(m);  
                                 break;  
                         }  
                 } else {  
                         if ((so->so_state & SS_ISCONNECTED) == 0) {  
                                 error = ENOTCONN;  
                                 goto die;  
                         }  
                 }  
                 error = udp_output(m, inp);  
                 if (nam) {  
                         in_pcbdisconnect(inp);  
                         inp->inp_laddr = laddr;  
                 }  
         }  
                 break;                  break;
   
         case PRU_SENSE:          case PRU_SENSE:
                 /*                  /*
                  * stat: don't bother with a blocksize.                   * stat: don't bother with a blocksize.
                  */                   */
                 splx(s);  
                 return (0);                  return (0);
   
         case PRU_RCVOOB:  
                 error =  EOPNOTSUPP;  
                 break;  
   
         case PRU_SENDOOB:          case PRU_SENDOOB:
                 m_freem(control);          case PRU_FASTTIMO:
                 m_freem(m);          case PRU_SLOWTIMO:
           case PRU_PROTORCV:
           case PRU_PROTOSEND:
                 error =  EOPNOTSUPP;                  error =  EOPNOTSUPP;
                 break;                  break;
   
         case PRU_SOCKADDR:          case PRU_RCVD:
                 in_setsockaddr(inp, nam);          case PRU_RCVOOB:
                 break;                  return (EOPNOTSUPP);    /* do not free mbuf's */
   
         case PRU_PEERADDR:  
                 in_setpeeraddr(inp, nam);  
                 break;  
   
         default:          default:
                 panic("udp_usrreq");                  panic("udp_usrreq");
         }          }
   
 release:  release:
         splx(s);          if (control) {
                   printf("udp control data unexpectedly retained\n");
                   m_freem(control);
           }
           if (m)
                   m_freem(m);
         return (error);          return (error);
 }  }
   
   static void
   udp_detach(inp)
           struct inpcb *inp;
   {
           int s = splsoftnet();
   
           in_pcbdetach(inp);
           splx(s);
   }
   
 /*  /*
  * Sysctl for udp variables.   * Sysctl for udp variables.
  */   */

Legend:
Removed from v.1.29.2.2  
changed lines
  Added in v.1.30

CVSweb <webmaster@jp.NetBSD.org>