# 2.11BSD#431 - /usr/src/sbin/routed/input.c

##### Functions

    rip_input         X

       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+1L, 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, (int)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, (short)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 == (short)n->rip_metric)) {
     194:                 rtchange(rt, from, (short)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

- in /usr/src/sbin/routed/main.c line 168

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1987-07-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1298 |