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

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

Diff for /src/sys/netinet6/raw_ip6.c between version 1.31 and 1.31.2.10

version 1.31, 2001/03/04 16:49:17 version 1.31.2.10, 2002/06/24 22:11:54
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
 /*      $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $        */  /*      $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $        */
   
 /*  /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.   * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
Line 65 
Line 65 
  *      @(#)raw_ip.c    8.2 (Berkeley) 1/4/94   *      @(#)raw_ip.c    8.2 (Berkeley) 1/4/94
  */   */
   
   #include <sys/cdefs.h>
   __KERNEL_RCSID(0, "$NetBSD$");
   
 #include "opt_ipsec.h"  #include "opt_ipsec.h"
   
 #include <sys/param.h>  #include <sys/param.h>
Line 75 
Line 78 
 #include <sys/socketvar.h>  #include <sys/socketvar.h>
 #include <sys/errno.h>  #include <sys/errno.h>
 #include <sys/systm.h>  #include <sys/systm.h>
   #include <sys/lwp.h>
 #include <sys/proc.h>  #include <sys/proc.h>
   
 #include <net/if.h>  #include <net/if.h>
Line 93 
Line 97 
 #ifdef ENABLE_DEFAULT_SCOPE  #ifdef ENABLE_DEFAULT_SCOPE
 #include <netinet6/scope6_var.h>  #include <netinet6/scope6_var.h>
 #endif  #endif
   #include <netinet6/raw_ip6.h>
   
 #ifdef IPSEC  #ifdef IPSEC
 #include <netinet6/ipsec.h>  #include <netinet6/ipsec.h>
 #endif /*IPSEC*/  #endif /* IPSEC */
   
 #include <machine/stdarg.h>  #include <machine/stdarg.h>
   
 #include "faith.h"  #include "faith.h"
   #if defined(NFAITH) && 0 < NFAITH
   #include <net/if_faith.h>
   #endif
   
 struct  in6pcb rawin6pcb;  struct  in6pcb rawin6pcb;
 #define ifatoia6(ifa)   ((struct in6_ifaddr *)(ifa))  #define ifatoia6(ifa)   ((struct in6_ifaddr *)(ifa))
Line 109  struct in6pcb rawin6pcb;
Line 117  struct in6pcb rawin6pcb;
  * Raw interface to IP6 protocol.   * Raw interface to IP6 protocol.
  */   */
   
   struct rip6stat rip6stat;
   
 /*  /*
  * Initialize raw connection block queue.   * Initialize raw connection block queue.
  */   */
 void  void
 rip6_init()  rip6_init()
 {  {
   
         rawin6pcb.in6p_next = rawin6pcb.in6p_prev = &rawin6pcb;          rawin6pcb.in6p_next = rawin6pcb.in6p_prev = &rawin6pcb;
 }  }
   
Line 135  rip6_input(mp, offp, proto)
Line 146  rip6_input(mp, offp, proto)
         struct sockaddr_in6 rip6src;          struct sockaddr_in6 rip6src;
         struct mbuf *opts = NULL;          struct mbuf *opts = NULL;
   
           rip6stat.rip6s_ipackets++;
   
 #if defined(NFAITH) && 0 < NFAITH  #if defined(NFAITH) && 0 < NFAITH
         if (m->m_pkthdr.rcvif) {          if (faithprefix(&ip6->ip6_dst)) {
                 if (m->m_pkthdr.rcvif->if_type == IFT_FAITH) {                  /* send icmp6 host unreach? */
                         /* send icmp6 host unreach? */                  m_freem(m);
                         m_freem(m);                  return IPPROTO_DONE;
                         return IPPROTO_DONE;  
                 }  
         }          }
 #endif  #endif
   
Line 156  rip6_input(mp, offp, proto)
Line 167  rip6_input(mp, offp, proto)
         bzero(&rip6src, sizeof(rip6src));          bzero(&rip6src, sizeof(rip6src));
         rip6src.sin6_len = sizeof(struct sockaddr_in6);          rip6src.sin6_len = sizeof(struct sockaddr_in6);
         rip6src.sin6_family = AF_INET6;          rip6src.sin6_family = AF_INET6;
 #if 0 /*XXX inbound flowlabel */  #if 0 /* XXX inbound flowlabel */
         rip6src.sin6_flowinfo = ip6->ip6_flow & IPV6_FLOWINFO_MASK;          rip6src.sin6_flowinfo = ip6->ip6_flow & IPV6_FLOWINFO_MASK;
 #endif  #endif
         /* KAME hack: recover scopeid */          /* KAME hack: recover scopeid */
Line 169  rip6_input(mp, offp, proto)
Line 180  rip6_input(mp, offp, proto)
                     in6p->in6p_ip6.ip6_nxt != proto)                      in6p->in6p_ip6.ip6_nxt != proto)
                         continue;                          continue;
                 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&                  if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
                    !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))                      !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
                         continue;                          continue;
                 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&                  if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
                    !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))                      !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
                         continue;  
                 if (in6p->in6p_cksum != -1  
                  && in6_cksum(m, ip6->ip6_nxt, *offp, m->m_pkthdr.len - *offp))  
                 {  
                         /* XXX bark something */  
                         continue;                          continue;
                   if (in6p->in6p_cksum != -1) {
                           rip6stat.rip6s_isum++;
                           if (in6_cksum(m, ip6->ip6_nxt, *offp,
                               m->m_pkthdr.len - *offp)) {
                                   rip6stat.rip6s_badsum++;
                                   continue;
                           }
                 }                  }
                 if (last) {                  if (last) {
                         struct  mbuf *n;                          struct  mbuf *n;
Line 191  rip6_input(mp, offp, proto)
Line 204  rip6_input(mp, offp, proto)
                                 ipsec6stat.in_polvio++;                                  ipsec6stat.in_polvio++;
                                 /* do not inject data into pcb */                                  /* do not inject data into pcb */
                         } else                          } else
 #endif /*IPSEC*/  #endif /* IPSEC */
                         if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {                          if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
                                 if (last->in6p_flags & IN6P_CONTROLOPTS)                                  if (last->in6p_flags & IN6P_CONTROLOPTS)
                                         ip6_savecontrol(last, &opts, ip6, n);                                          ip6_savecontrol(last, &opts, ip6, n);
                                 /* strip intermediate headers */                                  /* strip intermediate headers */
                                 m_adj(n, *offp);                                  m_adj(n, *offp);
                                 if (sbappendaddr(&last->in6p_socket->so_rcv,                                  if (sbappendaddr(&last->in6p_socket->so_rcv,
                                                 (struct sockaddr *)&rip6src,                                      (struct sockaddr *)&rip6src, n, opts) == 0) {
                                                  n, opts) == 0) {  
                                         /* should notify about lost packet */                                          /* should notify about lost packet */
                                         m_freem(n);                                          m_freem(n);
                                         if (opts)                                          if (opts)
                                                 m_freem(opts);                                                  m_freem(opts);
                                           rip6stat.rip6s_fullsock++;
                                 } else                                  } else
                                         sorwakeup(last->in6p_socket);                                          sorwakeup(last->in6p_socket);
                                 opts = NULL;                                  opts = NULL;
Line 221  rip6_input(mp, offp, proto)
Line 234  rip6_input(mp, offp, proto)
                 ip6stat.ip6s_delivered--;                  ip6stat.ip6s_delivered--;
                 /* do not inject data into pcb */                  /* do not inject data into pcb */
         } else          } else
 #endif /*IPSEC*/  #endif /* IPSEC */
         if (last) {          if (last) {
                 if (last->in6p_flags & IN6P_CONTROLOPTS)                  if (last->in6p_flags & IN6P_CONTROLOPTS)
                         ip6_savecontrol(last, &opts, ip6, m);                          ip6_savecontrol(last, &opts, ip6, m);
                 /* strip intermediate headers */                  /* strip intermediate headers */
                 m_adj(m, *offp);                  m_adj(m, *offp);
                 if (sbappendaddr(&last->in6p_socket->so_rcv,                  if (sbappendaddr(&last->in6p_socket->so_rcv,
                                 (struct sockaddr *)&rip6src, m, opts) == 0) {                      (struct sockaddr *)&rip6src, m, opts) == 0) {
                         m_freem(m);                          m_freem(m);
                         if (opts)                          if (opts)
                                 m_freem(opts);                                  m_freem(opts);
                           rip6stat.rip6s_fullsock++;
                 } else                  } else
                         sorwakeup(last->in6p_socket);                          sorwakeup(last->in6p_socket);
         } else {          } else {
                   rip6stat.rip6s_nosock++;
                   if (m->m_flags & M_MCAST)
                           rip6stat.rip6s_nosockmcast++;
                 if (proto == IPPROTO_NONE)                  if (proto == IPPROTO_NONE)
                         m_freem(m);                          m_freem(m);
                 else {                  else {
                         char *prvnxtp = ip6_get_prevhdr(m, *offp); /* XXX */                          char *prvnxtp = ip6_get_prevhdr(m, *offp); /* XXX */
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_protounknown);                          in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_protounknown);
                         icmp6_error(m, ICMP6_PARAM_PROB,                          icmp6_error(m, ICMP6_PARAM_PROB,
                                     ICMP6_PARAMPROB_NEXTHEADER,                              ICMP6_PARAMPROB_NEXTHEADER,
                                     prvnxtp - mtod(m, char *));                              prvnxtp - mtod(m, char *));
                 }                  }
                 ip6stat.ip6s_delivered--;                  ip6stat.ip6s_delivered--;
         }          }
Line 309  rip6_ctlinput(cmd, sa, d)
Line 326  rip6_ctlinput(cmd, sa, d)
                  * from icmp6_notify_error()                   * from icmp6_notify_error()
                  */                   */
                 in6p = NULL;                  in6p = NULL;
                 in6p = in6_pcblookup_connect(&rawin6pcb,                  in6p = in6_pcblookup_connect(&rawin6pcb, &sa6->sin6_addr, 0,
                     &sa6->sin6_addr, 0,  
                     (struct in6_addr *)&sa6_src->sin6_addr, 0, 0);                      (struct in6_addr *)&sa6_src->sin6_addr, 0, 0);
 #if 0  #if 0
                 if (!in6p) {                  if (!in6p) {
Line 333  rip6_ctlinput(cmd, sa, d)
Line 349  rip6_ctlinput(cmd, sa, d)
                 /*                  /*
                  * Depending on the value of "valid" and routing table                   * Depending on the value of "valid" and routing table
                  * size (mtudisc_{hi,lo}wat), we will:                   * size (mtudisc_{hi,lo}wat), we will:
                  * - recalcurate the new MTU and create the                   * - recalculate the new MTU and create the
                  *   corresponding routing entry, or                   *   corresponding routing entry, or
                  * - ignore the MTU change notification.                   * - ignore the MTU change notification.
                  */                   */
Line 442  rip6_output(m, va_alist)
Line 458  rip6_output(m, va_alist)
         {          {
                 struct in6_addr *in6a;                  struct in6_addr *in6a;
   
                 if ((in6a = in6_selectsrc(dstsock, optp,                  if ((in6a = in6_selectsrc(dstsock, optp, in6p->in6p_moptions,
                                           in6p->in6p_moptions,                      &in6p->in6p_route, &in6p->in6p_laddr, &error)) == 0) {
                                           &in6p->in6p_route,  
                                           &in6p->in6p_laddr,  
                                           &error)) == 0) {  
                         if (error == 0)                          if (error == 0)
                                 error = EADDRNOTAVAIL;                                  error = EADDRNOTAVAIL;
                         goto bad;                          goto bad;
Line 472  rip6_output(m, va_alist)
Line 485  rip6_output(m, va_alist)
                 int off;                  int off;
                 u_int16_t sum;                  u_int16_t sum;
   
 #define offsetof(type, member)  ((size_t)(&((type *)0)->member)) /* XXX */  
   
                 /* compute checksum */                  /* compute checksum */
                 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)                  if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
                         off = offsetof(struct icmp6_hdr, icmp6_cksum);                          off = offsetof(struct icmp6_hdr, icmp6_cksum);
Line 496  rip6_output(m, va_alist)
Line 507  rip6_output(m, va_alist)
                 error = ENOBUFS;                  error = ENOBUFS;
                 goto bad;                  goto bad;
         }          }
 #endif /*IPSEC*/  #endif /* IPSEC */
   
         flags = 0;          flags = 0;
 #ifdef IPV6_MINMTU  #ifdef IN6P_MINMTU
         if (in6p->in6p_flags & IN6P_MINMTU)          if (in6p->in6p_flags & IN6P_MINMTU)
                 flags |= IPV6_MINMTU;                  flags |= IPV6_MINMTU;
 #endif  #endif
   
         error = ip6_output(m, optp, &in6p->in6p_route, flags,          error = ip6_output(m, optp, &in6p->in6p_route, flags,
             in6p->in6p_moptions, &oifp);              in6p->in6p_moptions, &oifp);
         if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {          if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
                 if (oifp)                  if (oifp)
                         icmp6_ifoutstat_inc(oifp, type, code);                          icmp6_ifoutstat_inc(oifp, type, code);
                 icmp6stat.icp6s_outhist[type]++;                  icmp6stat.icp6s_outhist[type]++;
         }          } else
                   rip6stat.rip6s_opackets++;
   
         goto freectl;          goto freectl;
   
Line 530  rip6_output(m, va_alist)
Line 542  rip6_output(m, va_alist)
  * Raw IPv6 socket option processing.   * Raw IPv6 socket option processing.
  */   */
 int  int
 rip6_ctloutput(op, so, level, optname, m)  rip6_ctloutput(op, so, level, optname, mp)
         int op;          int op;
         struct socket *so;          struct socket *so;
         int level, optname;          int level, optname;
         struct mbuf **m;          struct mbuf **mp;
 {  {
         int error = 0;          int error = 0;
   
Line 549  rip6_ctloutput(op, so, level, optname, m
Line 561  rip6_ctloutput(op, so, level, optname, m
                 case MRT6_DEL_MFC:                  case MRT6_DEL_MFC:
                 case MRT6_PIM:                  case MRT6_PIM:
                         if (op == PRCO_SETOPT) {                          if (op == PRCO_SETOPT) {
                                 error = ip6_mrouter_set(optname, so, *m);                                  error = ip6_mrouter_set(optname, so, *mp);
                                 if (*m)                                  if (*mp)
                                         (void)m_free(*m);                                          (void)m_free(*mp);
                         } else if (op == PRCO_GETOPT) {                          } else if (op == PRCO_GETOPT)
                                 error = ip6_mrouter_get(optname, so, m);                                  error = ip6_mrouter_get(optname, so, mp);
                         } else                          else
                                 error = EINVAL;                                  error = EINVAL;
                         return (error);                          return (error);
                   case IPV6_CHECKSUM:
                           return (ip6_raw_ctloutput(op, so, level, optname, mp));
                   default:
                           return (ip6_ctloutput(op, so, level, optname, mp));
                 }                  }
                 return (ip6_ctloutput(op, so, level, optname, m));  
                 /* NOTREACHED */  
   
         case IPPROTO_ICMPV6:          case IPPROTO_ICMPV6:
                 /*                  /*
                  * XXX: is it better to call icmp6_ctloutput() directly                   * XXX: is it better to call icmp6_ctloutput() directly
                  * from protosw?                   * from protosw?
                  */                   */
                 return(icmp6_ctloutput(op, so, level, optname, m));                  return (icmp6_ctloutput(op, so, level, optname, mp));
   
         default:          default:
                 if (op == PRCO_SETOPT && *m)                  if (op == PRCO_SETOPT && *mp)
                         (void)m_free(*m);                          m_free(*mp);
                 return(EINVAL);                  return EINVAL;
         }          }
 }  }
   
Line 597  rip6_usrreq(so, req, m, nam, control, p)
Line 611  rip6_usrreq(so, req, m, nam, control, p)
   
         if (req == PRU_CONTROL)          if (req == PRU_CONTROL)
                 return (in6_control(so, (u_long)m, (caddr_t)nam,                  return (in6_control(so, (u_long)m, (caddr_t)nam,
                                     (struct ifnet *)control, p));                      (struct ifnet *)control, p));
   
         if (req == PRU_PURGEIF) {          if (req == PRU_PURGEIF) {
                   in6_pcbpurgeif0(&rawin6pcb, (struct ifnet *)control);
                 in6_purgeif((struct ifnet *)control);                  in6_purgeif((struct ifnet *)control);
                 in6_pcbpurgeif(&rawin6pcb, (struct ifnet *)control);                  in6_pcbpurgeif(&rawin6pcb, (struct ifnet *)control);
                 return (0);                  return (0);
Line 627  rip6_usrreq(so, req, m, nam, control, p)
Line 642  rip6_usrreq(so, req, m, nam, control, p)
                 in6p = sotoin6pcb(so);                  in6p = sotoin6pcb(so);
                 in6p->in6p_ip6.ip6_nxt = (long)nam;                  in6p->in6p_ip6.ip6_nxt = (long)nam;
                 in6p->in6p_cksum = -1;                  in6p->in6p_cksum = -1;
 #ifdef IPSEC  
                 error = ipsec_init_policy(so, &in6p->in6p_sp);  
                 if (error != 0) {  
                         in6_pcbdetach(in6p);  
                         break;  
                 }  
 #endif /*IPSEC*/  
   
                 MALLOC(in6p->in6p_icmp6filt, struct icmp6_filter *,                  MALLOC(in6p->in6p_icmp6filt, struct icmp6_filter *,
                         sizeof(struct icmp6_filter), M_PCB, M_NOWAIT);                      sizeof(struct icmp6_filter), M_PCB, M_NOWAIT);
                 if (in6p->in6p_icmp6filt == NULL) {                  if (in6p->in6p_icmp6filt == NULL) {
                         in6_pcbdetach(in6p);                          in6_pcbdetach(in6p);
                         error = ENOMEM;                          error = ENOMEM;
Line 686  rip6_usrreq(so, req, m, nam, control, p)
Line 694  rip6_usrreq(so, req, m, nam, control, p)
 #ifdef ENABLE_DEFAULT_SCOPE  #ifdef ENABLE_DEFAULT_SCOPE
                 if (addr->sin6_scope_id == 0)   /* not change if specified  */                  if (addr->sin6_scope_id == 0)   /* not change if specified  */
                         addr->sin6_scope_id =                          addr->sin6_scope_id =
                                 scope6_addr2default(&addr->sin6_addr);                              scope6_addr2default(&addr->sin6_addr);
   #endif
                   /* KAME hack: embed scopeid */
                   if (in6_embedscope(&addr->sin6_addr, addr, in6p, NULL) != 0)
                           return EINVAL;
   #ifndef SCOPEDROUTING
                   addr->sin6_scope_id = 0; /* for ifa_ifwithaddr */
 #endif  #endif
   
                 /*                  /*
                  * we don't support mapped address here, it would confuse                   * we don't support mapped address here, it would confuse
                  * users so reject it                   * users so reject it
Line 696  rip6_usrreq(so, req, m, nam, control, p)
Line 711  rip6_usrreq(so, req, m, nam, control, p)
                         error = EADDRNOTAVAIL;                          error = EADDRNOTAVAIL;
                         break;                          break;
                 }                  }
                 /*  
                  * Currently, ifa_ifwithaddr tends to fail for a link-local  
                  * address, since it implicitly expects that the link ID  
                  * for the address is embedded in the sin6_addr part.  
                  * For now, we'd rather keep this "as is". We'll eventually fix  
                  * this in a more natural way.  
                  */  
                 if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) &&                  if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) &&
                     (ia = ifa_ifwithaddr((struct sockaddr *)addr)) == 0) {                      (ia = ifa_ifwithaddr((struct sockaddr *)addr)) == 0) {
                         error = EADDRNOTAVAIL;                          error = EADDRNOTAVAIL;
                         break;                          break;
                 }                  }
                 if (ia &&                  if (ia && ((struct in6_ifaddr *)ia)->ia6_flags &
                     ((struct in6_ifaddr *)ia)->ia6_flags &  
                     (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|                      (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|
                      IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) {                       IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) {
                         error = EADDRNOTAVAIL;                          error = EADDRNOTAVAIL;
Line 718  rip6_usrreq(so, req, m, nam, control, p)
Line 725  rip6_usrreq(so, req, m, nam, control, p)
                 in6p->in6p_laddr = addr->sin6_addr;                  in6p->in6p_laddr = addr->sin6_addr;
                 break;                  break;
             }              }
   
         case PRU_CONNECT:          case PRU_CONNECT:
             {          {
                 struct sockaddr_in6 *addr = mtod(nam, struct sockaddr_in6 *);                  struct sockaddr_in6 *addr = mtod(nam, struct sockaddr_in6 *);
                 struct in6_addr *in6a = NULL;                  struct in6_addr *in6a = NULL;
 #ifdef ENABLE_DEFAULT_SCOPE  #ifdef ENABLE_DEFAULT_SCOPE
Line 747  rip6_usrreq(so, req, m, nam, control, p)
Line 754  rip6_usrreq(so, req, m, nam, control, p)
                         sin6 = *addr;                          sin6 = *addr;
                         addr = &sin6;                          addr = &sin6;
                         addr->sin6_scope_id =                          addr->sin6_scope_id =
                                 scope6_addr2default(&addr->sin6_addr);                              scope6_addr2default(&addr->sin6_addr);
                 }                  }
 #endif  #endif
   
                 /* Source address selection. XXX: need pcblookup? */                  /* Source address selection. XXX: need pcblookup? */
                 in6a = in6_selectsrc(addr, in6p->in6p_outputopts,                  in6a = in6_selectsrc(addr, in6p->in6p_outputopts,
                                      in6p->in6p_moptions,                      in6p->in6p_moptions, &in6p->in6p_route,
                                      &in6p->in6p_route,                      &in6p->in6p_laddr, &error);
                                      &in6p->in6p_laddr,  
                                      &error);  
                 if (in6a == NULL) {                  if (in6a == NULL) {
                         if (error == 0)                          if (error == 0)
                                 error = EADDRNOTAVAIL;                                  error = EADDRNOTAVAIL;
Line 766  rip6_usrreq(so, req, m, nam, control, p)
Line 771  rip6_usrreq(so, req, m, nam, control, p)
                 in6p->in6p_faddr = addr->sin6_addr;                  in6p->in6p_faddr = addr->sin6_addr;
                 soisconnected(so);                  soisconnected(so);
                 break;                  break;
             }          }
   
         case PRU_CONNECT2:          case PRU_CONNECT2:
                 error = EOPNOTSUPP;                  error = EOPNOTSUPP;
Line 783  rip6_usrreq(so, req, m, nam, control, p)
Line 788  rip6_usrreq(so, req, m, nam, control, p)
          * routine handles any messaging necessary.           * routine handles any messaging necessary.
          */           */
         case PRU_SEND:          case PRU_SEND:
             {          {
                 struct sockaddr_in6 tmp;                  struct sockaddr_in6 tmp;
                 struct sockaddr_in6 *dst;                  struct sockaddr_in6 *dst;
   
Line 798  rip6_usrreq(so, req, m, nam, control, p)
Line 803  rip6_usrreq(so, req, m, nam, control, p)
                         tmp.sin6_family = AF_INET6;                          tmp.sin6_family = AF_INET6;
                         tmp.sin6_len = sizeof(struct sockaddr_in6);                          tmp.sin6_len = sizeof(struct sockaddr_in6);
                         bcopy(&in6p->in6p_faddr, &tmp.sin6_addr,                          bcopy(&in6p->in6p_faddr, &tmp.sin6_addr,
                                 sizeof(struct in6_addr));                              sizeof(struct in6_addr));
                         dst = &tmp;                          dst = &tmp;
                 } else {                  } else {
                         if (nam == NULL) {                          if (nam == NULL) {
                                 error = ENOTCONN;                                  error = ENOTCONN;
                                 break;                                  break;
                         }                          }
                           if (nam->m_len != sizeof(tmp)) {
                                   error = EINVAL;
                                   break;
                           }
   
                         tmp = *mtod(nam, struct sockaddr_in6 *);                          tmp = *mtod(nam, struct sockaddr_in6 *);
                         dst = &tmp;                          dst = &tmp;
   
                           if (dst->sin6_family != AF_INET6) {
                                   error = EAFNOSUPPORT;
                                   break;
                           }
                 }                  }
 #ifdef ENABLE_DEFAULT_SCOPE  #ifdef ENABLE_DEFAULT_SCOPE
                 if (dst->sin6_scope_id == 0) {                  if (dst->sin6_scope_id == 0) {
                         dst->sin6_scope_id =                          dst->sin6_scope_id =
                                 scope6_addr2default(&dst->sin6_addr);                              scope6_addr2default(&dst->sin6_addr);
                 }                  }
 #endif  #endif
                 error = rip6_output(m, so, dst, control);                  error = rip6_output(m, so, dst, control);
                 m = NULL;                  m = NULL;
                 break;                  break;
             }          }
   
         case PRU_SENSE:          case PRU_SENSE:
                 /*                  /*

Legend:
Removed from v.1.31  
changed lines
  Added in v.1.31.2.10

CVSweb <webmaster@jp.NetBSD.org>