BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / netiso / if_eon.c
index aad00aa..3210eed 100644 (file)
@@ -1,3 +1,38 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ *     @(#)if_eon.c    7.16 (Berkeley) 6/27/91
+ */
+
 /***********************************************************
                Copyright IBM Corporation 1987
 
 /***********************************************************
                Copyright IBM Corporation 1987
 
@@ -27,7 +62,6 @@ SOFTWARE.
 /*
  * $Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $ 
  * $Source: /usr/argo/sys/netiso/RCS/if_eon.c,v $ 
 /*
  * $Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $ 
  * $Source: /usr/argo/sys/netiso/RCS/if_eon.c,v $ 
- *     @(#)if_eon.c    7.10 (Berkeley) 6/20/90 *
  *
  *     EON rfc 
  *  Layer between IP and CLNL
  *
  *     EON rfc 
  *  Layer between IP and CLNL
@@ -37,10 +71,6 @@ SOFTWARE.
  * for the nsel
  */
 
  * for the nsel
  */
 
-#ifndef lint
-static char *rcsid = "$Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $";
-#endif lint
-
 #ifdef EON
 #define NEON 1
 
 #ifdef EON
 #define NEON 1
 
@@ -77,6 +107,7 @@ static char *rcsid = "$Header: if_eon.c,v 1.4 88/07/19 15:53:59 hagens Exp $";
 #include "iso_errno.h"
 #include "eonvar.h"
 extern struct timeval time;
 #include "iso_errno.h"
 #include "eonvar.h"
 extern struct timeval time;
+extern struct ifnet loif;
 
 #define EOK 0
 
 
 #define EOK 0
 
@@ -189,6 +220,23 @@ caddr_t loc;
        sin->sin_family = AF_INET;
        sin->sin_len = sizeof (*sin);
        bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr));
        sin->sin_family = AF_INET;
        sin->sin_len = sizeof (*sin);
        bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr));
+       /*
+        * If there is a cached route,
+        * check that it is to the same destination
+        * and is still up.  If not, free it and try again.
+        */
+       if (ro->ro_rt) {
+               struct sockaddr_in *dst =
+                       (struct sockaddr_in *)rt_key(ro->ro_rt);
+               if ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
+                  sin->sin_addr.s_addr != dst->sin_addr.s_addr) {
+                       RTFREE(ro->ro_rt);
+                       ro->ro_rt = (struct rtentry *)0;
+               }
+       }
+       rtalloc(ro);
+       if (ro->ro_rt)
+               ro->ro_rt->rt_use++;
        hdr->ei_ip.ip_dst = sin->sin_addr;
        hdr->ei_ip.ip_p = IPPROTO_EON;
        hdr->ei_ip.ip_ttl = MAXTTL;     
        hdr->ei_ip.ip_dst = sin->sin_addr;
        hdr->ei_ip.ip_p = IPPROTO_EON;
        hdr->ei_ip.ip_ttl = MAXTTL;     
@@ -236,8 +284,9 @@ register struct sockaddr *gate;
                }
                return;
 
                }
                return;
 
-       case RTM_RESOLVE:
        case RTM_ADD:
        case RTM_ADD:
+       case RTM_RESOLVE:
+               rt->rt_rmx.rmx_mtu = loif.if_mtu; /* unless better below */
                R_Malloc(el, struct eon_llinfo *, sizeof(*el));
                rt->rt_llinfo = (caddr_t)el;
                if (el == 0)
                R_Malloc(el, struct eon_llinfo *, sizeof(*el));
                rt->rt_llinfo = (caddr_t)el;
                if (el == 0)
@@ -264,6 +313,9 @@ register struct sockaddr *gate;
        }
        el->el_flags |= RTF_UP;
        eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0);
        }
        el->el_flags |= RTF_UP;
        eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0);
+       if (el->el_iproute.ro_rt)
+               rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt->rt_rmx.rmx_mtu
+                                                       - sizeof(el->el_ei);
 }
 
 /*
 }
 
 /*
@@ -306,8 +358,8 @@ eonoutput(ifp, m, dst, rt)
        struct route *ro;
        int     datalen;
        struct mbuf *mh;
        struct route *ro;
        int     datalen;
        struct mbuf *mh;
-       int     error = 0;
-       caddr_t ippaddrloc;
+       int     error = 0, class = 0, alen = 0;
+       caddr_t ipaddrloc;
        static struct eon_iphdr eon_iphdr;
        static struct route route;
 
        static struct eon_iphdr eon_iphdr;
        static struct route route;
 
@@ -320,15 +372,21 @@ eonoutput(ifp, m, dst, rt)
        if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) {
                if (dst->siso_family == AF_LINK) {
                        register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst;
        if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) {
                if (dst->siso_family == AF_LINK) {
                        register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst;
-                       caddr_t ipaddrloc = LLADDR(sdl);
-                       int class = (sdl->sdl_alen == 5) ? 4[(u_char *)ipaddrloc] : 0;
-
-                       if (sdl->sdl_alen == 4 || sdl->sdl_alen == 5) {
-                               ro = &route;
-                               ei = &eon_iphdr;
-                               eoniphdr(ei, ipaddrloc, ro, class, 1);
-                               goto send;
-                       }
+
+                       ipaddrloc = LLADDR(sdl);
+                       alen = sdl->sdl_alen;
+               } else if (dst->siso_family == AF_ISO && dst->siso_data[0] == AFI_SNA) {
+                       alen = dst->siso_nlen - 1;
+                       ipaddrloc = (caddr_t) dst->siso_data + 1;
+               }
+               switch (alen) {
+               case 5:
+                       class =  4[(u_char *)ipaddrloc];
+               case 4:
+                       ro = &route;
+                       ei = &eon_iphdr;
+                       eoniphdr(ei, ipaddrloc, ro, class, 1);
+                       goto send;
                }
 einval:
                error =  EINVAL;
                }
 einval:
                error =  EINVAL;
@@ -543,7 +601,7 @@ eonctlinput(cmd, sin)
                case    PRC_REDIRECT_TOSHOST:
                case    PRC_MSGSIZE:
                case    PRC_PARAMPROB:
                case    PRC_REDIRECT_TOSHOST:
                case    PRC_MSGSIZE:
                case    PRC_PARAMPROB:
-                       printf("eonctlinput: ICMP cmd 0x%x\n", cmd );
+                       /* printf("eonctlinput: ICMP cmd 0x%x\n", cmd );*/
                break;
        }
        return 0;
                break;
        }
        return 0;