# 2.11BSD#431 - /usr/src/sys/netns/ns_input.c

##### Functions

    idp_ctlinput      X
    idp_do_route      X
    idp_forward       X
    idp_undo_route    X
    ns_init           X
    ns_watch_output   X
    nsintr            X

##### Variables

    idp_droute        X
    idp_sroute        X
    idpcksum          X
    idpforwarding     X
    idpprintfs        X
    ns_broadhost      X
    ns_broadnet       X
    ns_pexseq         X
    ns_thishost       X
    ns_zerohost       X
    nsctlerrmap       X
    nsintr_getpck     X
    nsintr_swtch      X
    nsintrq           X
    nspcb             X
    nsqmaxlen         X
    nsrawpcb          X

##### unions's

    bytes             X

       1: /*
       2:  * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  *
      12:  *      @(#)ns_input.c	7.2 (Berkeley) 1/20/88
      13:  */
      14:
      15: #include "param.h"
      16: #ifdef  NS
      17: #include "systm.h"
      18: #include "mbuf.h"
      19: #include "domain.h"
      20: #include "protosw.h"
      21: #include "socket.h"
      22: #include "socketvar.h"
      23: #include "errno.h"
      24: #include "time.h"
      25: #include "kernel.h"
      26:
      27: #include "../net/if.h"
      28: #include "../net/route.h"
      29: #include "../net/raw_cb.h"
      30:
      31: #include "ns.h"
      32: #include "ns_if.h"
      33: #include "ns_pcb.h"
      34: #include "idp.h"
      35: #include "idp_var.h"
      36: #include "ns_error.h"
      37:
      38: /*
      39:  * NS initialization.
      40:  */
      41: union ns_host   ns_thishost;
      42: union ns_host   ns_zerohost;
      43: union ns_host   ns_broadhost;
      44: union ns_net    ns_zeronet;
      45: union ns_net    ns_broadnet;
      46:
      47: static u_short allones[] = {-1, -1, -1};
      48:
      49: struct nspcb nspcb;
      50: struct nspcb nsrawpcb;
      51:
      52: struct ifqueue  nsintrq;
      53: int nsqmaxlen = IFQ_MAXLEN;
      54:
      55: int idpcksum = 1;
      56: long    ns_pexseq;
      57:
      58: ns_init()
      59: {
      60:     extern struct timeval time;
      61:
      62:     ns_broadhost = * (union ns_host *) allones;
      63:     ns_broadnet = * (union ns_net *) allones;
      64:     nspcb.nsp_next = nspcb.nsp_prev = &nspcb;
      65:     nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb;
      66:     nsintrq.ifq_maxlen = nsqmaxlen;
      67:     ns_pexseq = time.tv_usec;
      68: }
      69:
      70: /*
      71:  * Idp input routine.  Pass to next level.
      72:  */
      73: int nsintr_getpck = 0;
      74: int nsintr_swtch = 0;
      75: nsintr()
      76: {
      77:     register struct idp *idp;
      78:     register struct mbuf *m;
      79:     register struct nspcb *nsp;
      80:     struct ifnet *ifp;
      81:     struct mbuf *m0;
      82:     register int i;
      83:     int len, s, error;
      84:     char oddpacketp;
      85:
      86: next:
      87:     /*
      88: 	 * Get next datagram off input queue and get IDP header
      89: 	 * in first mbuf.
      90: 	 */
      91:     s = splimp();
      92:     IF_DEQUEUEIF(&nsintrq, m, ifp);
      93:     splx(s);
      94:     nsintr_getpck++;
      95:     if (m == 0)
      96:         return;
      97:     if ((m->m_off > MMAXOFF || m->m_len < sizeof (struct idp)) &&
      98:         (m = m_pullup(m, sizeof (struct idp))) == 0) {
      99:         idpstat.idps_toosmall++;
     100:         goto next;
     101:     }
     102:
     103:     /*
     104: 	 * Give any raw listeners a crack at the packet
     105: 	 */
     106:     for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
     107:         struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL);
     108:         if (m1) idp_input(m1, nsp, ifp);
     109:     }
     110:
     111:     idp = mtod(m, struct idp *);
     112:     len = ntohs(idp->idp_len);
     113:     if (oddpacketp = len & 1) {
     114:         len++;      /* If this packet is of odd length,
     115: 				   preserve garbage byte for checksum */
     116:     }
     117:
     118:     /*
     119: 	 * Check that the amount of data in the buffers
     120: 	 * is as at least much as the IDP header would have us expect.
     121: 	 * Trim mbufs if longer than we expect.
     122: 	 * Drop packet if shorter than we expect.
     123: 	 */
     124:     i = -len;
     125:     m0 = m;
     126:     for (;;) {
     127:         i += m->m_len;
     128:         if (m->m_next == 0)
     129:             break;
     130:         m = m->m_next;
     131:     }
     132:     if (i != 0) {
     133:         if (i < 0) {
     134:             idpstat.idps_tooshort++;
     135:             m = m0;
     136:             goto bad;
     137:         }
     138:         if (i <= m->m_len)
     139:             m->m_len -= i;
     140:         else
     141:             m_adj(m0, -i);
     142:     }
     143:     m = m0;
     144:     if (idpcksum && ((i = idp->idp_sum)!=0xffff)) {
     145:         idp->idp_sum = 0;
     146:         if (i != (idp->idp_sum = ns_cksum(m,len))) {
     147:             idpstat.idps_badsum++;
     148:             idp->idp_sum = i;
     149:             if (ns_hosteqnh(ns_thishost, idp->idp_dna.x_host))
     150:                 error = NS_ERR_BADSUM;
     151:             else
     152:                 error = NS_ERR_BADSUM_T;
     153:             ns_error(m, error, 0);
     154:             goto next;
     155:         }
     156:     }
     157:     /*
     158: 	 * Is this a directed broadcast?
     159: 	 */
     160:     if (ns_hosteqnh(ns_broadhost,idp->idp_dna.x_host)) {
     161:         if ((!ns_neteq(idp->idp_dna, idp->idp_sna)) &&
     162:             (!ns_neteqnn(idp->idp_dna.x_net, ns_broadnet)) &&
     163:             (!ns_neteqnn(idp->idp_sna.x_net, ns_zeronet)) &&
     164:             (!ns_neteqnn(idp->idp_dna.x_net, ns_zeronet)) ) {
     165:             /*
     166: 			 * Look to see if I need to eat this packet.
     167: 			 * Algorithm is to forward all young packets
     168: 			 * and prematurely age any packets which will
     169: 			 * by physically broadcasted.
     170: 			 * Any very old packets eaten without forwarding
     171: 			 * would die anyway.
     172: 			 *
     173: 			 * Suggestion of Bill Nesheim, Cornell U.
     174: 			 */
     175:             if (idp->idp_tc < NS_MAXHOPS) {
     176:                 idp_forward(idp);
     177:                 goto next;
     178:             }
     179:         }
     180:     /*
     181: 	 * Is this our packet? If not, forward.
     182: 	 */
     183:     } else if (!ns_hosteqnh(ns_thishost,idp->idp_dna.x_host)) {
     184:         idp_forward(idp);
     185:         goto next;
     186:     }
     187:     /*
     188: 	 * Locate pcb for datagram.
     189: 	 */
     190:     nsp = ns_pcblookup(&idp->idp_sna, idp->idp_dna.x_port, NS_WILDCARD);
     191:     /*
     192: 	 * Switch out to protocol's input routine.
     193: 	 */
     194:     nsintr_swtch++;
     195:     if (nsp) {
     196:         if (oddpacketp) {
     197:             m_adj(m0, -1);
     198:         }
     199:         if ((nsp->nsp_flags & NSP_ALL_PACKETS)==0)
     200:             switch (idp->idp_pt) {
     201:
     202:                 case NSPROTO_SPP:
     203:                     spp_input(m, nsp, ifp);
     204:                     goto next;
     205:
     206:                 case NSPROTO_ERROR:
     207:                     ns_err_input(m);
     208:                     goto next;
     209:             }
     210:         idp_input(m, nsp, ifp);
     211:     } else {
     212:         ns_error(m, NS_ERR_NOSOCK, 0);
     213:     }
     214:     goto next;
     215:
     216: bad:
     217:     m_freem(m);
     218:     goto next;
     219: }
     220:
     221: u_char nsctlerrmap[PRC_NCMDS] = {
     222:     ECONNABORTED,   ECONNABORTED,   0,      0,
     223:     0,      0,      EHOSTDOWN,  EHOSTUNREACH,
     224:     ENETUNREACH,    EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
     225:     EMSGSIZE,   0,      0,      0,
     226:     0,      0,      0,      0
     227: };
     228:
     229: idp_donosocks = 1;
     230:
     231: idp_ctlinput(cmd, arg)
     232:     int cmd;
     233:     caddr_t arg;
     234: {
     235:     struct ns_addr *ns;
     236:     struct nspcb *nsp;
     237:     struct ns_errp *errp;
     238:     int idp_abort();
     239:     extern struct nspcb *idp_drop();
     240:     int type;
     241:
     242:     if (cmd < 0 || cmd > PRC_NCMDS)
     243:         return;
     244:     if (nsctlerrmap[cmd] == 0)
     245:         return;     /* XXX */
     246:     type = NS_ERR_UNREACH_HOST;
     247:     switch (cmd) {
     248:         struct sockaddr_ns *sns;
     249:
     250:     case PRC_IFDOWN:
     251:     case PRC_HOSTDEAD:
     252:     case PRC_HOSTUNREACH:
     253:         sns = (struct sockaddr_ns *)arg;
     254:         if (sns->sns_family != AF_INET)
     255:             return;
     256:         ns = &sns->sns_addr;
     257:         break;
     258:
     259:     default:
     260:         errp = (struct ns_errp *)arg;
     261:         ns = &errp->ns_err_idp.idp_dna;
     262:         type = errp->ns_err_num;
     263:         type = ntohs((u_short)type);
     264:     }
     265:     switch (type) {
     266:
     267:     case NS_ERR_UNREACH_HOST:
     268:         ns_pcbnotify(ns, (int)nsctlerrmap[cmd], idp_abort, (long)0);
     269:         break;
     270:
     271:     case NS_ERR_NOSOCK:
     272:         nsp = ns_pcblookup(ns, errp->ns_err_idp.idp_sna.x_port,
     273:             NS_WILDCARD);
     274:         if(nsp && idp_donosocks && ! ns_nullhost(nsp->nsp_faddr))
     275:             (void) idp_drop(nsp, (int)nsctlerrmap[cmd]);
     276:     }
     277: }
     278:
     279: int idpprintfs = 0;
     280: int idpforwarding = 1;
     281: /*
     282:  * Forward a packet.  If some error occurs return the sender
     283:  * an error packet.  Note we can't always generate a meaningful
     284:  * error message because the NS errors don't have a large enough repetoire
     285:  * of codes and types.
     286:  */
     287: struct route idp_droute;
     288: struct route idp_sroute;
     289:
     290: idp_forward(idp)
     291:     register struct idp *idp;
     292: {
     293:     register int error, type, code;
     294:     struct mbuf *mcopy = NULL;
     295:     int agedelta = 1;
     296:     int flags = NS_FORWARDING;
     297:     int ok_there = 0;
     298:     int ok_back = 0;
     299:
     300:     if (idpprintfs) {
     301:         printf("forward: src ");
     302:         ns_printhost(&idp->idp_sna);
     303:         printf(", dst ");
     304:         ns_printhost(&idp->idp_dna);
     305:         printf("hop count %d\n", idp->idp_tc);
     306:     }
     307:     if (idpforwarding == 0) {
     308:         /* can't tell difference between net and host */
     309:         type = NS_ERR_UNREACH_HOST, code = 0;
     310:         goto senderror;
     311:     }
     312:     idp->idp_tc++;
     313:     if (idp->idp_tc > NS_MAXHOPS) {
     314:         type = NS_ERR_TOO_OLD, code = 0;
     315:         goto senderror;
     316:     }
     317:     /*
     318: 	 * Save at most 42 bytes of the packet in case
     319: 	 * we need to generate an NS error message to the src.
     320: 	 */
     321:     mcopy = m_copy(dtom(idp), 0, imin((int)ntohs(idp->idp_len), 42));
     322:
     323:     if ((ok_there = idp_do_route(&idp->idp_dna,&idp_droute))==0) {
     324:         type = NS_ERR_UNREACH_HOST, code = 0;
     325:         goto senderror;
     326:     }
     327:     /*
     328: 	 * Here we think about  forwarding  broadcast packets,
     329: 	 * so we try to insure that it doesn't go back out
     330: 	 * on the interface it came in on.  Also, if we
     331: 	 * are going to physically broadcast this, let us
     332: 	 * age the packet so we can eat it safely the second time around.
     333: 	 */
     334:     if (idp->idp_dna.x_host.c_host[0] & 0x1) {
     335:         struct ns_ifaddr *ia = ns_iaonnetof(&idp->idp_dna);
     336:         struct ifnet *ifp;
     337:         if (ia) {
     338:             /* I'm gonna hafta eat this packet */
     339:             agedelta += NS_MAXHOPS - idp->idp_tc;
     340:             idp->idp_tc = NS_MAXHOPS;
     341:         }
     342:         if ((ok_back = idp_do_route(&idp->idp_sna,&idp_sroute))==0) {
     343:             /* error = ENETUNREACH; He'll never get it! */
     344:             m_freem(dtom(idp));
     345:             goto cleanup;
     346:         }
     347:         if (idp_droute.ro_rt &&
     348:             (ifp=idp_droute.ro_rt->rt_ifp) &&
     349:             idp_sroute.ro_rt &&
     350:             (ifp!=idp_sroute.ro_rt->rt_ifp)) {
     351:             flags |= NS_ALLOWBROADCAST;
     352:         } else {
     353:             type = NS_ERR_UNREACH_HOST, code = 0;
     354:             goto senderror;
     355:         }
     356:     }
     357:     /* need to adjust checksum */
     358:     if (idp->idp_sum!=0xffff) {
     359:         union bytes {
     360:             u_char c[4];
     361:             u_short s[2];
     362:             long l;
     363:         } x;
     364:         register int shift;
     365:         x.l = 0; x.c[0] = agedelta;
     366:         shift = (((((int)ntohs(idp->idp_len))+1)>>1)-2) & 0xf;
     367:         x.l = idp->idp_sum + (x.l << shift);
     368:         x.l = x.s[0] + x.s[1];
     369:         x.l = x.s[0] + x.s[1];
     370:         if (x.l==0xffff) idp->idp_sum = 0; else idp->idp_sum = x.l;
     371:     }
     372:     if ((error = ns_output(dtom(idp), &idp_droute, flags)) &&
     373:         (mcopy!=NULL)) {
     374:         idp = mtod(mcopy, struct idp *);
     375:         type = NS_ERR_UNSPEC_T, code = 0;
     376:         switch (error) {
     377:
     378:         case ENETUNREACH:
     379:         case EHOSTDOWN:
     380:         case EHOSTUNREACH:
     381:         case ENETDOWN:
     382:         case EPERM:
     383:             type = NS_ERR_UNREACH_HOST;
     384:             break;
     385:
     386:         case EMSGSIZE:
     387:             type = NS_ERR_TOO_BIG;
     388:             code = 576; /* too hard to figure out mtu here */
     389:             break;
     390:
     391:         case ENOBUFS:
     392:             type = NS_ERR_UNSPEC_T;
     393:             break;
     394:         }
     395:         mcopy = NULL;
     396:     senderror:
     397:         ns_error(dtom(idp), type, code);
     398:     }
     399: cleanup:
     400:     if (ok_there)
     401:         idp_undo_route(&idp_droute);
     402:     if (ok_back)
     403:         idp_undo_route(&idp_sroute);
     404:     if (mcopy != NULL)
     405:         m_freem(mcopy);
     406: }
     407:
     408: idp_do_route(src, ro)
     409: struct ns_addr *src;
     410: struct route *ro;
     411: {
     412:
     413:     struct sockaddr_ns *dst;
     414:
     415:     bzero((caddr_t)ro, sizeof (*ro));
     416:     dst = (struct sockaddr_ns *)&ro->ro_dst;
     417:
     418:     dst->sns_family = AF_NS;
     419:     dst->sns_addr = *src;
     420:     dst->sns_addr.x_port = 0;
     421:     rtalloc(ro);
     422:     if (ro->ro_rt == 0 || ro->ro_rt->rt_ifp == 0) {
     423:         return (0);
     424:     }
     425:     ro->ro_rt->rt_use++;
     426:     return (1);
     427: }
     428:
     429: idp_undo_route(ro)
     430: register struct route *ro;
     431: {
     432:     if (ro->ro_rt) {RTFREE(ro->ro_rt);}
     433: }
     434: static union ns_net
     435: ns_zeronet;
     436:
     437: ns_watch_output(m, ifp)
     438: struct mbuf *m;
     439: struct ifnet *ifp;
     440: {
     441:     register struct nspcb *nsp;
     442:     register struct ifaddr *ia;
     443:     /*
     444: 	 * Give any raw listeners a crack at the packet
     445: 	 */
     446:     for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
     447:         struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
     448:         if (m0) {
     449:             struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
     450:
     451:             if(m1 == NULL)
     452:                 m_freem(m0);
     453:             else {
     454:                 register struct idp *idp;
     455:
     456:                 m1->m_off = MMINOFF;
     457:                 m1->m_len = sizeof (*idp);
     458:                 m1->m_next = m0;
     459:                 idp = mtod(m1, struct idp *);
     460:                 idp->idp_sna.x_net = ns_zeronet;
     461:                 idp->idp_sna.x_host = ns_thishost;
     462:                 if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
     463:                     for(ia = ifp->if_addrlist; ia;
     464:                             ia = ia->ifa_next) {
     465:                     if (ia->ifa_addr.sa_family==AF_NS) {
     466:                         idp->idp_sna =
     467:                         satons_addr(ia->ifa_dstaddr);
     468:                         break;
     469:                     }
     470:                     }
     471:                 idp->idp_len = 0xffff;
     472:                 idp_input(m1, nsp, ifp);
     473:             }
     474:         }
     475:     }
     476: }
     477: #endif	NS

#### Defined functions

idp_ctlinput defined in line 231; never used
idp_do_route defined in line 408; used 2 times

- in line 323, 342

idp_forward defined in line 290; used 2 times

- in line 176, 184

idp_undo_route defined in line 429; used 2 times

- in line 401-403(2)

ns_init defined in line 58; never used
ns_watch_output defined in line 437; never used
nsintr defined in line 75; never used

#### Defined variables

allones defined in line 47; used 2 times

- in line 62-63(2)

idp_droute defined in line 287; used 5 times

- in line 323, 347-348(2), 372, 401

idp_sroute defined in line 288; used 4 times

- in line 342, 349-350(2), 403

idpcksum defined in line 55; used 1 times

- in line 144

idpforwarding defined in line 280; used 1 times

- in line 307

idpprintfs defined in line 279; used 1 times

- in line 300

ns_broadhost defined in line 43; used 2 times

- in line 62, 160

ns_broadnet defined in line 45; used 2 times

- in line 63, 162

ns_pexseq defined in line 56; used 1 times

- in line 67

ns_thishost defined in line 41; used 3 times

- in line 149, 183, 461

ns_zerohost defined in line 42; never used
ns_zeronet defined in line 435; used 3 times

- in line 163-164(2), 460

nsctlerrmap defined in line 221; used 3 times

- in line 244, 268, 275

nsintr_getpck defined in line 73; used 1 times

- in line 94

nsintr_swtch defined in line 74; used 1 times

- in line 194

nsintrq defined in line 52; used 2 times

- in line 66, 92

nspcb defined in line 49; used 3 times

- in line 64(3)

nsqmaxlen defined in line 53; used 1 times

- in line 66

nsrawpcb defined in line 50; used 7 times

- in line 65(3), 106(2), 446(2)

#### Defined union's

bytes defined in line 359; never used

Last modified: 1988-04-29 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1430 |