[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.129 and 1.129.4.1

version 1.129, 2004/12/21 05:51:32 version 1.129.4.1, 2005/02/12 18:17:54
Line 95  __KERNEL_RCSID(0, "$NetBSD$");
Line 95  __KERNEL_RCSID(0, "$NetBSD$");
 #include <netinet/udp.h>  #include <netinet/udp.h>
 #include <netinet/udp_var.h>  #include <netinet/udp_var.h>
   
   #ifdef IPSEC_NAT_T
   #include <netinet6/ipsec.h>
   #include <netinet6/esp.h>
   #endif
   
 #ifdef INET6  #ifdef INET6
 #include <netinet/ip6.h>  #include <netinet/ip6.h>
 #include <netinet/icmp6.h>  #include <netinet/icmp6.h>
Line 147  struct inpcbtable udbtable;
Line 152  struct inpcbtable udbtable;
 struct  udpstat udpstat;  struct  udpstat udpstat;
   
 #ifdef INET  #ifdef INET
   #ifdef IPSEC_NAT_T
   static int udp4_espinudp (struct mbuf *, int, struct sockaddr *,
           struct socket *);
   #endif
 static void udp4_sendup (struct mbuf *, int, struct sockaddr *,  static void udp4_sendup (struct mbuf *, int, struct sockaddr *,
         struct socket *);          struct socket *);
 static int udp4_realinput (struct sockaddr_in *, struct sockaddr_in *,  static int udp4_realinput (struct sockaddr_in *, struct sockaddr_in *,
Line 740  udp4_realinput(struct sockaddr_in *src, 
Line 749  udp4_realinput(struct sockaddr_in *src, 
                                 return rcvcnt;                                  return rcvcnt;
                 }                  }
   
   #ifdef IPSEC_NAT_T
                   /* Handle ESP over UDP */
                   if (inp->inp_flags & INP_ESPINUDP_ALL) {
                           struct sockaddr *sa = (struct sockaddr *)src;
   
                           if (udp4_espinudp(m, off, sa, inp->inp_socket) != 0) {
                                   rcvcnt++;
                                   goto bad;
                           }
   
                           /* Normal UDP processing will take place */
                   }
   #endif
   
                 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket);                  udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket);
                 rcvcnt++;                  rcvcnt++;
         }          }
Line 909  udp_ctlinput(int cmd, struct sockaddr *s
Line 932  udp_ctlinput(int cmd, struct sockaddr *s
 }  }
   
 int  int
   udp_ctloutput(op, so, level, optname, mp)
           int op;
           struct socket *so;
           int level, optname;
           struct mbuf **mp;
   {
           int s;
           int error = 0;
           struct mbuf *m;
           struct inpcb *inp;
           int family;
   
           family = so->so_proto->pr_domain->dom_family;
   
           s = splsoftnet();
           switch (family) {
   #ifdef INET
           case PF_INET:
                   if (level != IPPROTO_UDP) {
                           error = ip_ctloutput(op, so, level, optname, mp);
                           goto end;
                   }
                   break;
   #endif
   #ifdef INET6
           case PF_INET6:
                   if (level != IPPROTO_UDP) {
                           error = ip6_ctloutput(op, so, level, optname, mp);
                           goto end;
                   }
                   break;
   #endif
           default:
                   error = EAFNOSUPPORT;
                   goto end;
                   break;
           }
   
   
           switch (op) {
           case PRCO_SETOPT:
                   m = *mp;
                   inp = sotoinpcb(so);
   
                   switch (optname) {
                   case UDP_ENCAP:
                           if (m == NULL || m->m_len < sizeof (int)) {
                                   error = EINVAL;
                                   goto end;
                           }
   
                           switch(*mtod(m, int *)) {
   #ifdef IPSEC_NAT_T
                           case 0:
                                   inp->inp_flags &= ~INP_ESPINUDP_ALL;
                                   break;
   
                           case UDP_ENCAP_ESPINUDP:
                                   inp->inp_flags &= ~INP_ESPINUDP_ALL;
                                   inp->inp_flags |= INP_ESPINUDP;
                                   break;
   
                           case UDP_ENCAP_ESPINUDP_NON_IKE:
                                   inp->inp_flags &= ~INP_ESPINUDP_ALL;
                                   inp->inp_flags |= INP_ESPINUDP_NON_IKE;
                                   break;
   #endif
                           default:
                                   error = EINVAL;
                                   goto end;
                                   break;
                           }
                           break;
   
                   default:
                           error = ENOPROTOOPT;
                           goto end;
                           break;
                   }
                   break;
   
           default:
                   error = EINVAL;
                   goto end;
                   break;
           }
   
   end:
           splx(s);
           return error;
   }
   
   
   int
 udp_output(struct mbuf *m, ...)  udp_output(struct mbuf *m, ...)
 {  {
         struct inpcb *inp;          struct inpcb *inp;
Line 1219  SYSCTL_SETUP(sysctl_net_inet_udp_setup, 
Line 1336  SYSCTL_SETUP(sysctl_net_inet_udp_setup, 
                        CTL_EOL);                         CTL_EOL);
 }  }
 #endif  #endif
   
   #if (defined INET && defined IPSEC_NAT_T)
   /*
    * Returns:
    * 1 if the packet was processed
    * 0 if normal UDP processing should take place
    */
   static int
   udp4_espinudp(m, off, src, so)
           struct mbuf *m;
           int off;
           struct sockaddr *src;
           struct socket *so;
   {
           size_t len;
           caddr_t data;
           struct inpcb *inp;
           size_t skip = 0;
           size_t minlen;
           size_t iphdrlen;
           struct ip *ip;
           struct mbuf *n;
   
           /*
            * Collapse the mbuf chain if the first mbuf is too short
            * The longest case is: UDP + non ESP marker + ESP
            */
           minlen = off + sizeof(u_int64_t) + sizeof(struct esp);
           if (minlen > m->m_pkthdr.len)
                   minlen = m->m_pkthdr.len;
   
           if (m->m_len < minlen) {
                   if ((m = m_pullup(m, minlen)) == NULL) {
                           printf("udp4_espinudp: m_pullup failed\n");
                           return 0;
                   }
           }
   
           len = m->m_len - off;
           data = mtod(m, caddr_t) + off;
           inp = sotoinpcb(so);
   
           /* Ignore keepalive packets */
           if ((len == 1) && (data[0] == '\xff')) {
                   return 1;
           }
   
           /*
            * Check that the payload is long enough to hold
            * an ESP header and compute the length of encapsulation
            * header to remove
            */
           if (inp->inp_flags & INP_ESPINUDP) {
                   u_int32_t *st = (u_int32_t *)data;
   
                   if ((len <= sizeof(struct esp)) || (*st == 0))
                           return 0; /* Normal UDP processing */
   
                   skip = sizeof(struct udphdr);
           }
   
           if (inp->inp_flags & INP_ESPINUDP_NON_IKE) {
                   u_int64_t *st = (u_int64_t *)data;
   
                   if ((len <= sizeof(u_int64_t) + sizeof(struct esp))
                       || (*st != 0))
                           return 0; /* Normal UDP processing */
   
                   skip = sizeof(struct udphdr) + sizeof(u_int64_t);
           }
   
           /*
            * Remove the UDP header (and possibly the non ESP marker)
            * IP header lendth is iphdrlen
            * Before:
            *   <--- off --->
            *   +----+------+-----+
            *   | IP |  UDP | ESP |
            *   +----+------+-----+
            *        <-skip->
            * After:
            *          +----+-----+
            *          | IP | ESP |
            *          +----+-----+
            *   <-skip->
            */
           iphdrlen = off - sizeof(struct udphdr);
           memmove(mtod(m, caddr_t) + skip, mtod(m, caddr_t), iphdrlen);
           m_adj(m, skip);
   
           ip = mtod(m, struct ip *);
           ip->ip_len = htons(ntohs(ip->ip_len) - skip);
           ip->ip_p = IPPROTO_ESP;
   
           /*
            * Copy the mbuf to avoid multiple free, as both
            * esp4_input (which we call) and udp_input (which
            * called us) free the mbuf.
            */
           if ((n = m_dup(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
                   printf("udp4_espinudp: m_dup failed\n");
                   return 0;
           }
   
           esp4_input(n, iphdrlen);
   
           /* We handled it, it shoudln't be handled by UDP */
           return 1;
   }
   #endif

Legend:
Removed from v.1.129  
changed lines
  Added in v.1.129.4.1

CVSweb <webmaster@jp.NetBSD.org>