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