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