1: /*
   2:  * Copyright (c) 1983 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: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)input.c	5.6 (Berkeley) 6/3/86";
   9: #endif not lint
  10: 
  11: /*
  12:  * Routing Table Management Daemon
  13:  */
  14: #include "defs.h"
  15: #include <sys/syslog.h>
  16: 
  17: /*
  18:  * Process a newly received packet.
  19:  */
  20: rip_input(from, size)
  21:     struct sockaddr *from;
  22:     int size;
  23: {
  24:     register struct rt_entry *rt;
  25:     register struct netinfo *n;
  26:     register struct interface *ifp;
  27:     struct interface *if_ifwithdstaddr();
  28:     int newsize;
  29:     register struct afswitch *afp;
  30: 
  31:     ifp = 0;
  32:     TRACE_INPUT(ifp, from, size);
  33:     if (from->sa_family >= af_max ||
  34:         (afp = &afswitch[from->sa_family])->af_hash == (int (*)())0) {
  35:         syslog(LOG_INFO,
  36:      "\"from\" address in unsupported address family (%d), cmd %d\n",
  37:             from->sa_family, msg->rip_cmd);
  38:         return;
  39:     }
  40:     switch (msg->rip_cmd) {
  41: 
  42:     case RIPCMD_REQUEST:
  43:         newsize = 0;
  44:         size -= 4 * sizeof (char);
  45:         n = msg->rip_nets;
  46:         while (size > 0) {
  47:             if (size < sizeof (struct netinfo))
  48:                 break;
  49:             size -= sizeof (struct netinfo);
  50: 
  51:             if (msg->rip_vers > 0) {
  52:                 n->rip_dst.sa_family =
  53:                     ntohs(n->rip_dst.sa_family);
  54:                 n->rip_metric = ntohl(n->rip_metric);
  55:             }
  56:             /*
  57: 			 * A single entry with sa_family == AF_UNSPEC and
  58: 			 * metric ``infinity'' means ``all routes''.
  59: 			 * We respond to routers only if we are acting
  60: 			 * as a supplier, or to anyone other than a router
  61: 			 * (eg, query).
  62: 			 */
  63:             if (n->rip_dst.sa_family == AF_UNSPEC &&
  64:                 n->rip_metric == HOPCNT_INFINITY && size == 0) {
  65:                     if (supplier || (*afp->af_portmatch)(from) == 0)
  66:                     supply(from, 0, 0);
  67:                 return;
  68:             }
  69:             if (n->rip_dst.sa_family < af_max &&
  70:                 afswitch[n->rip_dst.sa_family].af_hash)
  71:                 rt = rtlookup(&n->rip_dst);
  72:             else
  73:                 rt = 0;
  74:             n->rip_metric = rt == 0 ? HOPCNT_INFINITY :
  75:                 min(rt->rt_metric+1, HOPCNT_INFINITY);
  76:             if (msg->rip_vers > 0) {
  77:                 n->rip_dst.sa_family =
  78:                     htons(n->rip_dst.sa_family);
  79:                 n->rip_metric = htonl(n->rip_metric);
  80:             }
  81:             n++, newsize += sizeof (struct netinfo);
  82:         }
  83:         if (newsize > 0) {
  84:             msg->rip_cmd = RIPCMD_RESPONSE;
  85:             newsize += sizeof (int);
  86:             (*afp->af_output)(s, 0, from, newsize);
  87:         }
  88:         return;
  89: 
  90:     case RIPCMD_TRACEON:
  91:     case RIPCMD_TRACEOFF:
  92:         /* verify message came from a privileged port */
  93:         if ((*afp->af_portcheck)(from) == 0)
  94:             return;
  95:         if (if_iflookup(from) == 0) {
  96:             syslog(LOG_ERR, "trace command from unknown router, %s",
  97:                (*afswitch[from->sa_family].af_format)(from));
  98:             return;
  99:         }
 100:         packet[size] = '\0';
 101:         if (msg->rip_cmd == RIPCMD_TRACEON)
 102:             traceon(msg->rip_tracefile);
 103:         else
 104:             traceoff();
 105:         return;
 106: 
 107:     case RIPCMD_RESPONSE:
 108:         /* verify message came from a router */
 109:         if ((*afp->af_portmatch)(from) == 0)
 110:             return;
 111:         (*afp->af_canon)(from);
 112:         /* are we talking to ourselves? */
 113:         ifp = if_ifwithaddr(from);
 114:         if (ifp) {
 115:             rt = rtfind(from);
 116:             if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0)
 117:                 addrouteforif(ifp);
 118:             else
 119:                 rt->rt_timer = 0;
 120:             return;
 121:         }
 122:         /*
 123: 		 * Update timer for interface on which the packet arrived.
 124: 		 * If from other end of a point-to-point link that isn't
 125: 		 * in the routing tables, (re-)add the route.
 126: 		 */
 127:         if ((rt = rtfind(from)) &&
 128:             (rt->rt_state & (RTS_INTERFACE | RTS_REMOTE)))
 129:             rt->rt_timer = 0;
 130:         else if (ifp = if_ifwithdstaddr(from))
 131:             addrouteforif(ifp);
 132:         else if (if_iflookup(from) == 0) {
 133:             syslog(LOG_ERR, "packet from unknown router, %s",
 134:                (*afswitch[from->sa_family].af_format)(from));
 135:             return;
 136:         }
 137:         size -= 4 * sizeof (char);
 138:         n = msg->rip_nets;
 139:         for (; size > 0; size -= sizeof (struct netinfo), n++) {
 140:             if (size < sizeof (struct netinfo))
 141:                 break;
 142:             if (msg->rip_vers > 0) {
 143:                 n->rip_dst.sa_family =
 144:                     ntohs(n->rip_dst.sa_family);
 145:                 n->rip_metric = ntohl(n->rip_metric);
 146:             }
 147:             if ((unsigned) n->rip_metric > HOPCNT_INFINITY)
 148:                 continue;
 149:             if (n->rip_dst.sa_family >= af_max ||
 150:                 (afp = &afswitch[n->rip_dst.sa_family])->af_hash ==
 151:                 (int (*)())0) {
 152:                 syslog(LOG_INFO,
 153:         "route in unsupported address family (%d), from %s (af %d)\n",
 154:                    n->rip_dst.sa_family,
 155:                    (*afswitch[from->sa_family].af_format)(from),
 156:                    from->sa_family);
 157:                 continue;
 158:             }
 159:             if (((*afp->af_checkhost)(&n->rip_dst)) == 0) {
 160:                 syslog(LOG_DEBUG,
 161:                     "bad host in route from %s (af %d)\n",
 162:                    (*afswitch[from->sa_family].af_format)(from),
 163:                    from->sa_family);
 164:                 continue;
 165:             }
 166:             rt = rtlookup(&n->rip_dst);
 167:             if (rt == 0 ||
 168:                 (rt->rt_state & (RTS_INTERNAL|RTS_INTERFACE)) ==
 169:                 (RTS_INTERNAL|RTS_INTERFACE)) {
 170:                 rt = rtfind(&n->rip_dst);
 171:                 if (rt && equal(from, &rt->rt_router) &&
 172:                     rt->rt_metric == n->rip_metric)
 173:                     continue;
 174:                 if (n->rip_metric < HOPCNT_INFINITY)
 175:                     rtadd(&n->rip_dst, from, n->rip_metric, 0);
 176:                 continue;
 177:             }
 178: 
 179:             /*
 180: 			 * Update if from gateway and different,
 181: 			 * shorter, or getting stale and equivalent.
 182: 			 */
 183:             if (equal(from, &rt->rt_router)) {
 184:                 if (n->rip_metric == HOPCNT_INFINITY) {
 185:                     rtdelete(rt);
 186:                     continue;
 187:                 }
 188:                 if (n->rip_metric != rt->rt_metric)
 189:                     rtchange(rt, from, n->rip_metric);
 190:                 rt->rt_timer = 0;
 191:             } else if ((unsigned) (n->rip_metric) < rt->rt_metric ||
 192:                 (rt->rt_timer > (EXPIRE_TIME/2) &&
 193:                 rt->rt_metric == n->rip_metric)) {
 194:                 rtchange(rt, from, n->rip_metric);
 195:                 rt->rt_timer = 0;
 196:             }
 197:         }
 198:         return;
 199:     }
 200: }

Defined functions

rip_input defined in line 20; used 1 times

Defined variables

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