Commit | Line | Data |
---|---|---|
24d3bb4c | 1 | /* tp_input.c 1.2 82/05/15 */ |
944419ad SL |
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 | } |