1: /*
   2:  * Copyright (c) 1985 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  * Includes material written at Cornell University by Bill Nesheim,
   7:  * by permission of the author.
   8:  */
   9: 
  10: 
  11: #ifndef lint
  12: static char sccsid[] = "@(#)input.c	5.6 (Berkeley) 2/14/86";
  13: #endif not lint
  14: 
  15: /*
  16:  * XNS Routing Table Management Daemon
  17:  */
  18: #include "defs.h"
  19: 
  20: struct sockaddr *
  21: xns_nettosa(net)
  22: union ns_net net;
  23: {
  24:     static struct sockaddr_ns sxn;
  25:     extern char ether_broadcast_addr[6];
  26: 
  27:     bzero(&sxn, sizeof (struct sockaddr_ns));
  28:     sxn.sns_family = AF_NS;
  29:     sxn.sns_addr.x_net = net;
  30:     sxn.sns_addr.x_host = *(union ns_host *)ether_broadcast_addr;
  31:     return( (struct sockaddr *)&sxn);
  32: 
  33: }
  34: 
  35: /*
  36:  * Process a newly received packet.
  37:  */
  38: rip_input(from, size)
  39:     struct sockaddr *from;
  40:     int size;
  41: {
  42:     struct rt_entry *rt;
  43:     struct netinfo *n;
  44:     struct interface *ifp;
  45:     int newsize;
  46:     struct afswitch *afp;
  47: 
  48: 
  49:     ifp = 0;
  50:     TRACE_INPUT(ifp, from, size);
  51:     if (from->sa_family >= AF_MAX)
  52:         return;
  53:     afp = &afswitch[from->sa_family];
  54: 
  55:     size -= sizeof (u_short)    /* command */;
  56:     n = msg->rip_nets;
  57: 
  58:     switch (ntohs(msg->rip_cmd)) {
  59: 
  60:     case RIPCMD_REQUEST:
  61:         newsize = 0;
  62:         while (size > 0) {
  63:             if (size < sizeof (struct netinfo))
  64:                 break;
  65:             size -= sizeof (struct netinfo);
  66: 
  67:             /*
  68: 			 * A single entry with rip_dst == DSTNETS_ALL and
  69: 			 * metric ``infinity'' means ``all routes''.
  70: 			 */
  71:             if (ns_neteqnn(n->rip_dst, ns_anynet) &&
  72:                     ntohs(n->rip_metric) == HOPCNT_INFINITY &&
  73:                 size == 0) {
  74:                 ifp = if_ifwithnet(from);
  75:                 supply(from, 0, ifp);
  76:                 return;
  77:             }
  78:             /*
  79: 			 * request for specific nets
  80: 			 */
  81:             rt = rtlookup(xns_nettosa(n->rip_dst));
  82:             if (ftrace) {
  83:                 fprintf(ftrace,
  84:                     "specific request for %s",
  85:                     xns_nettoa(n->rip_dst));
  86:                 fprintf(ftrace,
  87:                     " yields route %x\n",
  88:                     rt);
  89:             }
  90:             n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY :
  91:                 min(rt->rt_metric+1, HOPCNT_INFINITY));
  92:             n++;
  93:                 newsize += sizeof (struct netinfo);
  94:         }
  95:         if (newsize > 0) {
  96:             msg->rip_cmd = htons(RIPCMD_RESPONSE);
  97:             newsize += sizeof (u_short);
  98:             /* should check for if with dstaddr(from) first */
  99:             (*afp->af_output)(0, from, newsize);
 100:             ifp = if_ifwithnet(from);
 101:             TRACE_OUTPUT(ifp, from, newsize);
 102:             if (ftrace) {
 103:                 fprintf(ftrace,
 104:                     "request arrived on interface %s\n",
 105:                     ifp->int_name);
 106:             }
 107:         }
 108:         return;
 109: 
 110:     case RIPCMD_RESPONSE:
 111:         /* verify message came from a router */
 112:         if ((*afp->af_portmatch)(from) == 0)
 113:             return;
 114:         (*afp->af_canon)(from);
 115:         /* are we talking to ourselves? */
 116:         if (ifp = if_ifwithaddr(from)) {
 117:             rt = rtfind(from);
 118:             if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0)
 119:                 addrouteforif(ifp);
 120:             else
 121:                 rt->rt_timer = 0;
 122:             return;
 123:         }
 124:         /* Update timer for interface on which the packet arrived.
 125: 		 * If from other end of a point-to-point link that isn't
 126: 		 * in the routing tables, (re-)add the route.
 127: 		 */
 128:         if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE)) {
 129:             if(ftrace) fprintf(ftrace, "Got route\n");
 130:             rt->rt_timer = 0;
 131:         } else if (ifp = if_ifwithdstaddr(from)) {
 132:             if(ftrace) fprintf(ftrace, "Got partner\n");
 133:             addrouteforif(ifp);
 134:         }
 135:         for (; size > 0; size -= sizeof (struct netinfo), n++) {
 136:             struct sockaddr *sa;
 137:             if (size < sizeof (struct netinfo))
 138:                 break;
 139:             if ((unsigned) ntohs(n->rip_metric) >= HOPCNT_INFINITY)
 140:                 continue;
 141:             rt = rtfind(sa = xns_nettosa(n->rip_dst));
 142:             if (rt == 0) {
 143:                 rtadd(sa, from, ntohs(n->rip_metric), 0);
 144:                 continue;
 145:             }
 146: 
 147:             /*
 148: 			 * Update if from gateway and different,
 149: 			 * from anywhere and shorter, or getting stale and equivalent.
 150: 			 */
 151:             if ((equal(from, &rt->rt_router) &&
 152:                 ntohs(n->rip_metric) != rt->rt_metric ) ||
 153:                 (unsigned) ntohs(n->rip_metric) < rt->rt_metric ||
 154:                 (rt->rt_timer > (EXPIRE_TIME/2) &&
 155:                 rt->rt_metric == ntohs(n->rip_metric))) {
 156:                 rtchange(rt, from, ntohs(n->rip_metric));
 157:                 rt->rt_timer = 0;
 158:             }
 159:         }
 160:         return;
 161:     }
 162: }

Defined functions

rip_input defined in line 38; used 1 times
xns_nettosa defined in line 20; used 2 times

Defined variables

sccsid defined in line 12; never used
Last modified: 1986-02-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 999
Valid CSS Valid XHTML 1.0 Strict