BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / netinet / in.c
index 3abd775..75824d1 100644 (file)
@@ -1,36 +1,47 @@
 /*
 /*
- * Copyright (c) 1982, 1986 Regents of the University of California.
+ * Copyright (c) 1982, 1986, 1991 Regents of the University of California.
  * All rights reserved.
  *
  * All rights reserved.
  *
- * Redistribution is only permitted until one year after the first shipment
- * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
- * binary forms are permitted provided that: (1) source distributions retain
- * this entire copyright notice and comment, and (2) distributions including
- * binaries display the following acknowledgement:  This product includes
- * software developed by the University of California, Berkeley and its
- * contributors'' in the documentation or other materials provided with the
- * distribution and in all advertising materials mentioning features or use
- * of this software.  Neither the name of the University nor the names of
- * its contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)in.c        7.15 (Berkeley) 6/28/90
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)in.c        7.17 (Berkeley) 4/20/91
  */
 
 #include "param.h"
 #include "ioctl.h"
 #include "mbuf.h"
  */
 
 #include "param.h"
 #include "ioctl.h"
 #include "mbuf.h"
-#include "protosw.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "socket.h"
 #include "socketvar.h"
-#include "user.h"
 #include "in_systm.h"
 #include "in_systm.h"
-#include "../net/if.h"
-#include "../net/route.h"
-#include "../net/af.h"
+#include "net/if.h"
+#include "net/route.h"
+#include "net/af.h"
 #include "in.h"
 #include "in_var.h"
 
 #include "in.h"
 #include "in_var.h"
 
@@ -269,8 +280,8 @@ in_control(so, cmd, data, ifp)
        case SIOCSIFADDR:
        case SIOCSIFNETMASK:
        case SIOCSIFDSTADDR:
        case SIOCSIFADDR:
        case SIOCSIFNETMASK:
        case SIOCSIFDSTADDR:
-               if (error = suser(u.u_cred, &u.u_acflag))
-                       return (error);
+               if ((so->so_state & SS_PRIV) == 0)
+                       return (EPERM);
 
                if (ifp == 0)
                        panic("in_control");
 
                if (ifp == 0)
                        panic("in_control");
@@ -308,8 +319,8 @@ in_control(so, cmd, data, ifp)
                break;
 
        case SIOCSIFBRDADDR:
                break;
 
        case SIOCSIFBRDADDR:
-               if (error = suser(u.u_cred, &u.u_acflag))
-                       return (error);
+               if ((so->so_state & SS_PRIV) == 0)
+                       return (EPERM);
                /* FALLTHROUGH */
 
        case SIOCGIFADDR:
                /* FALLTHROUGH */
 
        case SIOCGIFADDR:
@@ -359,7 +370,8 @@ in_control(so, cmd, data, ifp)
                if (ia->ia_flags & IFA_ROUTE) {
                        ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
                        rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
                if (ia->ia_flags & IFA_ROUTE) {
                        ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
                        rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
-                       ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_addr;
+                       ia->ia_ifa.ifa_dstaddr =
+                                       (struct sockaddr *)&ia->ia_dstaddr;
                        rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
                }
                break;
                        rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
                }
                break;
@@ -475,7 +487,7 @@ in_ifinit(ifp, ia, sin, scrub)
 {
        register u_long i = ntohl(sin->sin_addr.s_addr);
        struct sockaddr_in oldaddr;
 {
        register u_long i = ntohl(sin->sin_addr.s_addr);
        struct sockaddr_in oldaddr;
-       int s = splimp(), error;
+       int s = splimp(), error, flags = RTF_UP;
 
        oldaddr = ia->ia_addr;
        ia->ia_addr = *sin;
 
        oldaddr = ia->ia_addr;
        ia->ia_addr = *sin;
@@ -489,6 +501,7 @@ in_ifinit(ifp, ia, sin, scrub)
                ia->ia_addr = oldaddr;
                return (error);
        }
                ia->ia_addr = oldaddr;
                return (error);
        }
+       splx(s);
        if (scrub) {
                ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
                in_ifscrub(ifp, ia);
        if (scrub) {
                ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
                in_ifscrub(ifp, ia);
@@ -518,27 +531,25 @@ in_ifinit(ifp, ia, sin, scrub)
                                break;
                        }
        }
                                break;
                        }
        }
+       /*
+        * Add route for the network.
+        */
        if (ifp->if_flags & IFF_BROADCAST) {
                ia->ia_broadaddr.sin_addr = 
                        in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
                ia->ia_netbroadcast.s_addr =
                    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
        if (ifp->if_flags & IFF_BROADCAST) {
                ia->ia_broadaddr.sin_addr = 
                        in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
                ia->ia_netbroadcast.s_addr =
                    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
-       }
-       /*
-        * Add route for the network.
-        */
-       if (ifp->if_flags & IFF_LOOPBACK) {
+       } else if (ifp->if_flags & IFF_LOOPBACK) {
                ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
                ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
-               rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
-       } else if (ifp->if_flags & IFF_POINTOPOINT &&
-                ia->ia_dstaddr.sin_family == AF_INET)
-               rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
-       else {
-               rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
+               flags |= RTF_HOST;
+       } else if (ifp->if_flags & IFF_POINTOPOINT) {
+               if (ia->ia_dstaddr.sin_family != AF_INET)
+                       return (0);
+               flags |= RTF_HOST;
        }
        }
-       ia->ia_flags |= IFA_ROUTE;
-       splx(s);
-       return (0);
+       if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
+               ia->ia_flags |= IFA_ROUTE;
+       return (error);
 }
 
 /*
 }
 
 /*