#include "../h/param.h" #include "../h/systm.h" #include "../h/clock.h" #include "../h/mbuf.h" #include "../h/protosw.h" #include "../h/socket.h" #include "../net/dn_systm.h" #include "../net/if.h" #include "../net/tp.h" #include "../net/tp_var.h" /* * Initialize a few of the Transport variables here. */ tp_init() { tp_host = 244; tprp.tprp_nn = 255; /* max node number */ } /* * Attach a DECnet interface. * For now, since we are an end node, * there can only be one. */ tp_attach(ifp) register struct ifnet *ifp; { if (tpifp) { printf("tp: Only one DECnet interface allowed, "); printf("%s%d ignored\n", ifp->if_name, ifp->if_unit); return; } tpifp = ifp; } /* * Transport input routine. Decode header, process * initialization messages, flush other control messages, * and strip route headers and pass to NSP. */ tp_input() { register struct mbuf *m; register char *p; next: /* * Get next packet off input queue. */ IF_DEQUEUE(&tpintrq, m); if (m == 0) return; p = mtod(m, char *); switch (*p & TP_MSGTYPE) { /* * Transport initialization message from neighbor. */ case TP_INIT: { register struct tpin *t = (struct tpin *)p; printf("tpinit: node %d, %d, blksize %d, ver %o.%o.%o\n", D_SHORT(t->tpin_srcnode), t->tpin_tiinfo, D_SHORT(t->tpin_blksize), t->tpin_ver[0], t->tpin_ver[1], t->tpin_ver[2]); /* perform a few consistency checks */ if (m->m_len < sizeof (struct tpin)) { tpstat.tps_badinit++; break; } if (D_SHORT(t->tpin_srcnode) > tprp.tprp_nn) { tpstat.tps_badinit++; break; } if (t->tpin_res != 0) { tpstat.tps_badinit++; break; } tpstat.tps_init++; if (tpstate == TPS_TIS) { tpstate = TPS_RUN; wakeup((caddr_t)&tpstate); } else if (tpstate == TPS_HALT) { tp_linit(); tpstate = TPS_RUN; } break; } /* * Route header. Flush bad ones, * strip good ones and pass to NSP. */ case TP_RH: { register struct tprh *t = (struct tprh *)p; /* * Is it a reasonable route header? */ if (tpstate != TPS_RUN) { printf("tp: not running!\n"); break; } if (t->tprh_rtflg & TPRF_EV) { printf("tp: got P2 ASCII header\n"); tpstat.tps_p2hdr++; break; } if (t->tprh_rtflg & TPRF_RTS) { printf("tp: got returned packet\n"); tpstat.tps_returned++; break; } if (m->m_len <= sizeof (struct tprh)) { printf("tp: got short packet, %d\n", m->m_len); tpstat.tps_shortpacket++; break; } if (D_SHORT(t->tprh_srcnode) > tprp.tprp_nn) { tpstat.tps_badsrc++; break; } /* * Is it for us? If so, * add it to the NSP input queue. */ if (D_SHORT(t->tprh_dstnode) != tp_host) { printf("tp: not for me, %d\n", D_SHORT(t->tprh_dstnode)); tpstat.tps_notforme++; break; } setnspintr(); IF_ENQUEUE(&nspintrq, m); goto next; } /* * Verification messge. We should never see one * of these because we never ask for one. Flush it. */ case TP_VERIF: printf("tp: got verification message\n"); tpstat.tps_verif++; break; /* * Hello and test message. Make sure it's * valid then flush it. */ case TP_TEST: { register struct tpht *t = (struct tpht *)p; register int i; if (D_SHORT(t->tpht_srcnode) > tprp.tprp_nn) { tpstat.tps_badsrc++; break; } if ((i = t->tpht_cnt) < 0 || i > 128) { printf("tp: test, bad count, %d\n", i); tpstat.tps_badtest++; break; } if (m->m_len != sizeof (struct tpht) + i - 1) { printf("tp: test, bad len, %d\n", m->m_len); tpstat.tps_bad_test++; break; } for (p = t->tpht_data; i--; p++) if (*p != 0252) { printf("tp: test, bad data, %o\n", *p); tpstat.tps_badtest++; break; } break; } /* * Routing message. We should never get this, * at least not yet. Just flush it. */ case TP_ROUTE: printf("tp: got routing message\n"); tpstat.tps_route++; break; default: printf("tp: unknown packet type, 0x%x\n", *p); tpstat.tps_unknown++; break; } /* * Free the current packet and get the next one. */ m_freem(m); goto next; }