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