1*8412Swnj /* tp_input.c 1.3 82/10/09 */
26832Ssam
36832Ssam #include "../h/param.h"
46832Ssam #include "../h/systm.h"
56832Ssam #include "../h/mbuf.h"
66832Ssam #include "../h/protosw.h"
76832Ssam #include "../h/socket.h"
8*8412Swnj #include "../netdecnet/dn_systm.h"
96832Ssam #include "../net/if.h"
10*8412Swnj #include "../netdecnet/tp.h"
11*8412Swnj #include "../netdecnet/tp_var.h"
126832Ssam
136832Ssam /*
146832Ssam * Initialize a few of the Transport variables here.
156832Ssam */
tp_init()166832Ssam tp_init()
176832Ssam {
186832Ssam tp_host = 244;
196832Ssam tprp.tprp_nn = 255; /* max node number */
206832Ssam }
216832Ssam
226832Ssam /*
236832Ssam * Attach a DECnet interface.
246832Ssam * For now, since we are an end node,
256832Ssam * there can only be one.
266832Ssam */
tp_attach(ifp)276832Ssam tp_attach(ifp)
286832Ssam register struct ifnet *ifp;
296832Ssam {
306832Ssam if (tpifp) {
316832Ssam printf("tp: Only one DECnet interface allowed, ");
326832Ssam printf("%s%d ignored\n", ifp->if_name, ifp->if_unit);
336832Ssam return;
346832Ssam }
356832Ssam tpifp = ifp;
366832Ssam }
376832Ssam
386832Ssam /*
396832Ssam * Transport input routine. Decode header, process
406832Ssam * initialization messages, flush other control messages,
416832Ssam * and strip route headers and pass to NSP.
426832Ssam */
tp_input()436832Ssam tp_input()
446832Ssam {
456832Ssam register struct mbuf *m;
466832Ssam register char *p;
476832Ssam
486832Ssam next:
496832Ssam /*
506832Ssam * Get next packet off input queue.
516832Ssam */
526832Ssam IF_DEQUEUE(&tpintrq, m);
536832Ssam if (m == 0)
546832Ssam return;
556832Ssam p = mtod(m, char *);
566832Ssam switch (*p & TP_MSGTYPE) {
576832Ssam /*
586832Ssam * Transport initialization message from neighbor.
596832Ssam */
606832Ssam case TP_INIT:
616832Ssam {
626832Ssam register struct tpin *t = (struct tpin *)p;
636832Ssam
646832Ssam printf("tpinit: node %d, %d, blksize %d, ver %o.%o.%o\n",
656832Ssam D_SHORT(t->tpin_srcnode), t->tpin_tiinfo,
666832Ssam D_SHORT(t->tpin_blksize),
676832Ssam t->tpin_ver[0], t->tpin_ver[1], t->tpin_ver[2]);
686832Ssam /* perform a few consistency checks */
696832Ssam if (m->m_len < sizeof (struct tpin)) {
706832Ssam tpstat.tps_badinit++;
716832Ssam break;
726832Ssam }
736832Ssam if (D_SHORT(t->tpin_srcnode) > tprp.tprp_nn) {
746832Ssam tpstat.tps_badinit++;
756832Ssam break;
766832Ssam }
776832Ssam if (t->tpin_res != 0) {
786832Ssam tpstat.tps_badinit++;
796832Ssam break;
806832Ssam }
816832Ssam tpstat.tps_init++;
826832Ssam if (tpstate == TPS_TIS) {
836832Ssam tpstate = TPS_RUN;
846832Ssam wakeup((caddr_t)&tpstate);
856832Ssam } else if (tpstate == TPS_HALT) {
866832Ssam tp_linit();
876832Ssam tpstate = TPS_RUN;
886832Ssam }
896832Ssam break;
906832Ssam }
916832Ssam
926832Ssam /*
936832Ssam * Route header. Flush bad ones,
946832Ssam * strip good ones and pass to NSP.
956832Ssam */
966832Ssam case TP_RH:
976832Ssam {
986832Ssam register struct tprh *t = (struct tprh *)p;
996832Ssam
1006832Ssam /*
1016832Ssam * Is it a reasonable route header?
1026832Ssam */
1036832Ssam if (tpstate != TPS_RUN) {
1046832Ssam printf("tp: not running!\n");
1056832Ssam break;
1066832Ssam }
1076832Ssam if (t->tprh_rtflg & TPRF_EV) {
1086832Ssam printf("tp: got P2 ASCII header\n");
1096832Ssam tpstat.tps_p2hdr++;
1106832Ssam break;
1116832Ssam }
1126832Ssam if (t->tprh_rtflg & TPRF_RTS) {
1136832Ssam printf("tp: got returned packet\n");
1146832Ssam tpstat.tps_returned++;
1156832Ssam break;
1166832Ssam }
1176832Ssam if (m->m_len <= sizeof (struct tprh)) {
1186832Ssam printf("tp: got short packet, %d\n", m->m_len);
1196832Ssam tpstat.tps_shortpacket++;
1206832Ssam break;
1216832Ssam }
1226832Ssam if (D_SHORT(t->tprh_srcnode) > tprp.tprp_nn) {
1236832Ssam tpstat.tps_badsrc++;
1246832Ssam break;
1256832Ssam }
1266832Ssam
1276832Ssam /*
1286832Ssam * Is it for us? If so,
1296832Ssam * add it to the NSP input queue.
1306832Ssam */
1316832Ssam if (D_SHORT(t->tprh_dstnode) != tp_host) {
1326832Ssam printf("tp: not for me, %d\n", D_SHORT(t->tprh_dstnode));
1336832Ssam tpstat.tps_notforme++;
1346832Ssam break;
1356832Ssam }
1366832Ssam setnspintr();
1376832Ssam IF_ENQUEUE(&nspintrq, m);
1386832Ssam goto next;
1396832Ssam }
1406832Ssam
1416832Ssam /*
1426832Ssam * Verification messge. We should never see one
1436832Ssam * of these because we never ask for one. Flush it.
1446832Ssam */
1456832Ssam case TP_VERIF:
1466832Ssam printf("tp: got verification message\n");
1476832Ssam tpstat.tps_verif++;
1486832Ssam break;
1496832Ssam
1506832Ssam /*
1516832Ssam * Hello and test message. Make sure it's
1526832Ssam * valid then flush it.
1536832Ssam */
1546832Ssam case TP_TEST:
1556832Ssam {
1566832Ssam register struct tpht *t = (struct tpht *)p;
1576832Ssam register int i;
1586832Ssam
1596832Ssam if (D_SHORT(t->tpht_srcnode) > tprp.tprp_nn) {
1606832Ssam tpstat.tps_badsrc++;
1616832Ssam break;
1626832Ssam }
1636832Ssam if ((i = t->tpht_cnt) < 0 || i > 128) {
1646832Ssam printf("tp: test, bad count, %d\n", i);
1656832Ssam tpstat.tps_badtest++;
1666832Ssam break;
1676832Ssam }
1686832Ssam if (m->m_len != sizeof (struct tpht) + i - 1) {
1696832Ssam printf("tp: test, bad len, %d\n", m->m_len);
1706832Ssam tpstat.tps_bad_test++;
1716832Ssam break;
1726832Ssam }
1736832Ssam for (p = t->tpht_data; i--; p++)
1746832Ssam if (*p != 0252) {
1756832Ssam printf("tp: test, bad data, %o\n", *p);
1766832Ssam tpstat.tps_badtest++;
1776832Ssam break;
1786832Ssam }
1796832Ssam break;
1806832Ssam }
1816832Ssam
1826832Ssam /*
1836832Ssam * Routing message. We should never get this,
1846832Ssam * at least not yet. Just flush it.
1856832Ssam */
1866832Ssam case TP_ROUTE:
1876832Ssam printf("tp: got routing message\n");
1886832Ssam tpstat.tps_route++;
1896832Ssam break;
1906832Ssam
1916832Ssam default:
1926832Ssam printf("tp: unknown packet type, 0x%x\n", *p);
1936832Ssam tpstat.tps_unknown++;
1946832Ssam break;
1956832Ssam }
1966832Ssam
1976832Ssam /*
1986832Ssam * Free the current packet and get the next one.
1996832Ssam */
2006832Ssam m_freem(m);
2016832Ssam goto next;
2026832Ssam }
203