1*6832Ssam 
2*6832Ssam #include "../h/param.h"
3*6832Ssam #include "../h/systm.h"
4*6832Ssam #include "../h/clock.h"
5*6832Ssam #include "../h/mbuf.h"
6*6832Ssam #include "../h/protosw.h"
7*6832Ssam #include "../h/socket.h"
8*6832Ssam #include "../net/dn_systm.h"
9*6832Ssam #include "../net/if.h"
10*6832Ssam #include "../net/tp.h"
11*6832Ssam #include "../net/tp_var.h"
12*6832Ssam 
13*6832Ssam 
14*6832Ssam /*
15*6832Ssam  * Initialize a few of the Transport variables here.
16*6832Ssam  */
17*6832Ssam tp_init()
18*6832Ssam {
19*6832Ssam 	tp_host = 244;
20*6832Ssam 	tprp.tprp_nn = 255;	/* max node number */
21*6832Ssam }
22*6832Ssam 
23*6832Ssam /*
24*6832Ssam  * Attach a DECnet interface.
25*6832Ssam  * For now, since we are an end node,
26*6832Ssam  * there can only be one.
27*6832Ssam  */
28*6832Ssam tp_attach(ifp)
29*6832Ssam 	register struct ifnet *ifp;
30*6832Ssam {
31*6832Ssam 	if (tpifp) {
32*6832Ssam 		printf("tp: Only one DECnet interface allowed, ");
33*6832Ssam 		printf("%s%d ignored\n", ifp->if_name, ifp->if_unit);
34*6832Ssam 		return;
35*6832Ssam 	}
36*6832Ssam 	tpifp = ifp;
37*6832Ssam }
38*6832Ssam 
39*6832Ssam /*
40*6832Ssam  * Transport input routine.  Decode header, process
41*6832Ssam  * initialization messages, flush other control messages,
42*6832Ssam  * and strip route headers and pass to NSP.
43*6832Ssam  */
44*6832Ssam tp_input()
45*6832Ssam {
46*6832Ssam 	register struct mbuf *m;
47*6832Ssam 	register char *p;
48*6832Ssam 
49*6832Ssam next:
50*6832Ssam 	/*
51*6832Ssam 	 * Get next packet off input queue.
52*6832Ssam 	 */
53*6832Ssam 	IF_DEQUEUE(&tpintrq, m);
54*6832Ssam 	if (m == 0)
55*6832Ssam 		return;
56*6832Ssam 	p = mtod(m, char *);
57*6832Ssam 	switch (*p & TP_MSGTYPE) {
58*6832Ssam 	/*
59*6832Ssam 	 * Transport initialization message from neighbor.
60*6832Ssam 	 */
61*6832Ssam 	case TP_INIT:
62*6832Ssam 	{
63*6832Ssam 		register struct tpin *t = (struct tpin *)p;
64*6832Ssam 
65*6832Ssam 		printf("tpinit: node %d, %d, blksize %d, ver %o.%o.%o\n",
66*6832Ssam 			D_SHORT(t->tpin_srcnode), t->tpin_tiinfo,
67*6832Ssam 			D_SHORT(t->tpin_blksize),
68*6832Ssam 			t->tpin_ver[0], t->tpin_ver[1], t->tpin_ver[2]);
69*6832Ssam 		/* perform a few consistency checks */
70*6832Ssam 		if (m->m_len < sizeof (struct tpin)) {
71*6832Ssam 			tpstat.tps_badinit++;
72*6832Ssam 			break;
73*6832Ssam 		}
74*6832Ssam 		if (D_SHORT(t->tpin_srcnode) > tprp.tprp_nn) {
75*6832Ssam 			tpstat.tps_badinit++;
76*6832Ssam 			break;
77*6832Ssam 		}
78*6832Ssam 		if (t->tpin_res != 0) {
79*6832Ssam 			tpstat.tps_badinit++;
80*6832Ssam 			break;
81*6832Ssam 		}
82*6832Ssam 		tpstat.tps_init++;
83*6832Ssam 		if (tpstate == TPS_TIS) {
84*6832Ssam 			tpstate = TPS_RUN;
85*6832Ssam 			wakeup((caddr_t)&tpstate);
86*6832Ssam 		} else if (tpstate == TPS_HALT) {
87*6832Ssam 			tp_linit();
88*6832Ssam 			tpstate = TPS_RUN;
89*6832Ssam 		}
90*6832Ssam 		break;
91*6832Ssam 	}
92*6832Ssam 
93*6832Ssam 	/*
94*6832Ssam 	 * Route header.  Flush bad ones,
95*6832Ssam 	 * strip good ones and pass to NSP.
96*6832Ssam 	 */
97*6832Ssam 	case TP_RH:
98*6832Ssam 	{
99*6832Ssam 		register struct tprh *t = (struct tprh *)p;
100*6832Ssam 
101*6832Ssam 		/*
102*6832Ssam 		 * Is it a reasonable route header?
103*6832Ssam 		 */
104*6832Ssam 		if (tpstate != TPS_RUN) {
105*6832Ssam 			printf("tp: not running!\n");
106*6832Ssam 			break;
107*6832Ssam 		}
108*6832Ssam 		if (t->tprh_rtflg & TPRF_EV) {
109*6832Ssam 			printf("tp: got P2 ASCII header\n");
110*6832Ssam 			tpstat.tps_p2hdr++;
111*6832Ssam 			break;
112*6832Ssam 		}
113*6832Ssam 		if (t->tprh_rtflg & TPRF_RTS) {
114*6832Ssam 			printf("tp: got returned packet\n");
115*6832Ssam 			tpstat.tps_returned++;
116*6832Ssam 			break;
117*6832Ssam 		}
118*6832Ssam 		if (m->m_len <= sizeof (struct tprh)) {
119*6832Ssam 			printf("tp: got short packet, %d\n", m->m_len);
120*6832Ssam 			tpstat.tps_shortpacket++;
121*6832Ssam 			break;
122*6832Ssam 		}
123*6832Ssam 		if (D_SHORT(t->tprh_srcnode) > tprp.tprp_nn) {
124*6832Ssam 			tpstat.tps_badsrc++;
125*6832Ssam 			break;
126*6832Ssam 		}
127*6832Ssam 
128*6832Ssam 		/*
129*6832Ssam 		 * Is it for us?  If so,
130*6832Ssam 		 * add it to the NSP input queue.
131*6832Ssam 		 */
132*6832Ssam 		if (D_SHORT(t->tprh_dstnode) != tp_host) {
133*6832Ssam 			printf("tp: not for me, %d\n", D_SHORT(t->tprh_dstnode));
134*6832Ssam 			tpstat.tps_notforme++;
135*6832Ssam 			break;
136*6832Ssam 		}
137*6832Ssam 		setnspintr();
138*6832Ssam 		IF_ENQUEUE(&nspintrq, m);
139*6832Ssam 		goto next;
140*6832Ssam 	}
141*6832Ssam 
142*6832Ssam 	/*
143*6832Ssam 	 * Verification messge.  We should never see one
144*6832Ssam 	 * of these because we never ask for one.  Flush it.
145*6832Ssam 	 */
146*6832Ssam 	case TP_VERIF:
147*6832Ssam 		printf("tp: got verification message\n");
148*6832Ssam 		tpstat.tps_verif++;
149*6832Ssam 		break;
150*6832Ssam 
151*6832Ssam 	/*
152*6832Ssam 	 * Hello and test message.  Make sure it's
153*6832Ssam 	 * valid then flush it.
154*6832Ssam 	 */
155*6832Ssam 	case TP_TEST:
156*6832Ssam 	{
157*6832Ssam 		register struct tpht *t = (struct tpht *)p;
158*6832Ssam 		register int i;
159*6832Ssam 
160*6832Ssam 		if (D_SHORT(t->tpht_srcnode) > tprp.tprp_nn) {
161*6832Ssam 			tpstat.tps_badsrc++;
162*6832Ssam 			break;
163*6832Ssam 		}
164*6832Ssam 		if ((i = t->tpht_cnt) < 0 || i > 128) {
165*6832Ssam 			printf("tp: test, bad count, %d\n", i);
166*6832Ssam 			tpstat.tps_badtest++;
167*6832Ssam 			break;
168*6832Ssam 		}
169*6832Ssam 		if (m->m_len != sizeof (struct tpht) + i - 1) {
170*6832Ssam 			printf("tp: test, bad len, %d\n", m->m_len);
171*6832Ssam 			tpstat.tps_bad_test++;
172*6832Ssam 			break;
173*6832Ssam 		}
174*6832Ssam 		for (p = t->tpht_data; i--; p++)
175*6832Ssam 			if (*p != 0252) {
176*6832Ssam 				printf("tp: test, bad data, %o\n", *p);
177*6832Ssam 				tpstat.tps_badtest++;
178*6832Ssam 				break;
179*6832Ssam 			}
180*6832Ssam 		break;
181*6832Ssam 	}
182*6832Ssam 
183*6832Ssam 	/*
184*6832Ssam 	 * Routing message.  We should never get this,
185*6832Ssam 	 * at least not yet.  Just flush it.
186*6832Ssam 	 */
187*6832Ssam 	case TP_ROUTE:
188*6832Ssam 		printf("tp: got routing message\n");
189*6832Ssam 		tpstat.tps_route++;
190*6832Ssam 		break;
191*6832Ssam 
192*6832Ssam 	default:
193*6832Ssam 		printf("tp: unknown packet type, 0x%x\n", *p);
194*6832Ssam 		tpstat.tps_unknown++;
195*6832Ssam 		break;
196*6832Ssam 	}
197*6832Ssam 
198*6832Ssam 	/*
199*6832Ssam 	 * Free the current packet and get the next one.
200*6832Ssam 	 */
201*6832Ssam 	m_freem(m);
202*6832Ssam 	goto next;
203*6832Ssam }
204