BSD 4_4 release
[unix-history] / usr / src / sbin / XNSrouted / tables.c
index c04f554..4b00dc5 100644 (file)
@@ -1,22 +1,38 @@
 /*
 /*
- * Copyright (c) 1985 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1985, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not 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 MERCHANTIBILITY 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.
+ *
+ * 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.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)tables.c   5.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)tables.c   8.1 (Berkeley) 6/5/93";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -155,7 +171,7 @@ rtadd(dst, gate, metric, state)
         * from this host, discard the entry.  This should only
         * occur because of an incorrect entry in /etc/gateways.
         */
         * from this host, discard the entry.  This should only
         * occur because of an incorrect entry in /etc/gateways.
         */
-       if (install && ioctl(s, SIOCADDRT, (char *)&rt->rt_rt) < 0) {
+       if (install && rtioctl(ADD, &rt->rt_rt) < 0) {
                if (errno != EEXIST)
                        perror("SIOCADDRT");
                if (errno == ENETUNREACH) {
                if (errno != EEXIST)
                        perror("SIOCADDRT");
                if (errno == ENETUNREACH) {
@@ -201,17 +217,21 @@ rtchange(rt, gate, metric)
        }
        if (doioctl && install) {
 #ifndef RTM_ADD
        }
        if (doioctl && install) {
 #ifndef RTM_ADD
-               if (ioctl(s, SIOCADDRT, (char *)&rt->rt_rt) < 0)
-                 syslog(LOG_ERR, "SIOCADDRT dst %s, gw %s: %m",
+               if (rtioctl(ADD, &rt->rt_rt) < 0)
+                 syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m",
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr),
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr));
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr),
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr));
-               if (delete && ioctl(s, SIOCDELRT, (char *)&oldroute) < 0)
-                       perror("SIOCDELRT");
+               if (delete && rtioctl(DELETE, &oldroute) < 0)
+                       perror("rtioctl DELETE");
 #else
 #else
-               if (delete && ioctl(s, SIOCDELRT, (char *)&oldroute) < 0)
-                       perror("SIOCDELRT");
-               if (ioctl(s, SIOCADDRT, (char *)&rt->rt_rt) < 0)
-                 syslog(LOG_ERR, "SIOCADDRT dst %s, gw %s: %m",
+               if (delete == 0) {
+                       if (rtioctl(ADD, &rt->rt_rt) >= 0)
+                               return;
+               } else {
+                       if (rtioctl(CHANGE, &rt->rt_rt) >= 0)
+                               return;
+               }
+               syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m",
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr),
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr));
 #endif
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr),
                   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr));
 #endif
@@ -232,8 +252,8 @@ rtdelete(rt)
                        rt->rt_ifp->int_name);
        }
        TRACE_ACTION(DELETE, rt);
                        rt->rt_ifp->int_name);
        }
        TRACE_ACTION(DELETE, rt);
-       if (install && ioctl(s, SIOCDELRT, (char *)&rt->rt_rt))
-               perror("SIOCDELRT");
+       if (install && rtioctl(DELETE, &rt->rt_rt) < 0)
+               perror("rtioctl DELETE");
        remque(rt);
        free((char *)rt);
 }
        remque(rt);
        free((char *)rt);
 }
@@ -247,3 +267,53 @@ rtinit()
        for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++)
                rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
 }
        for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++)
                rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
 }
+int seqno;
+
+rtioctl(action, ort)
+       int action;
+       struct ortentry *ort;
+{
+#ifndef RTM_ADD
+       switch (action) {
+
+       case ADD:
+               return (ioctl(s, SIOCADDRT, (char *)ort));
+
+       case DELETE:
+               return (ioctl(s, SIOCDELRT, (char *)ort));
+
+       default:
+               return (-1);
+       }
+#else /* RTM_ADD */
+       struct {
+               struct rt_msghdr w_rtm;
+               struct sockaddr w_dst;
+               struct sockaddr w_gate;
+               struct sockaddr_ns w_netmask;
+       } w;
+#define rtm w.w_rtm
+
+       bzero((char *)&w, sizeof(w));
+       rtm.rtm_msglen = sizeof(w);
+       rtm.rtm_version = RTM_VERSION;
+       rtm.rtm_type = (action == ADD ? RTM_ADD :
+                               (action == DELETE ? RTM_DELETE : RTM_CHANGE));
+#undef rt_flags
+       rtm.rtm_flags = ort->rt_flags;
+       rtm.rtm_seq = ++seqno;
+       rtm.rtm_addrs = RTA_DST|RTA_GATEWAY;
+       bcopy((char *)&ort->rt_dst, (char *)&w.w_dst, sizeof(w.w_dst));
+       bcopy((char *)&ort->rt_gateway, (char *)&w.w_gate, sizeof(w.w_gate));
+       w.w_gate.sa_family = w.w_dst.sa_family = AF_NS;
+       w.w_gate.sa_len = w.w_dst.sa_len = sizeof(w.w_dst);
+       if (rtm.rtm_flags & RTF_HOST) {
+               rtm.rtm_msglen -= sizeof(w.w_netmask);
+       } else {
+               w.w_netmask = ns_netmask;
+               rtm.rtm_msglen -= 8;
+       }
+       errno = 0;
+       return write(r, (char *)&w, rtm.rtm_msglen);
+#endif  /* RTM_ADD */
+}