Commit | Line | Data |
---|---|---|
a37bfda7 | 1 | /* tp_input.c 1.3 82/10/09 */ |
944419ad SL |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
944419ad SL |
5 | #include "../h/mbuf.h" |
6 | #include "../h/protosw.h" | |
7 | #include "../h/socket.h" | |
a37bfda7 | 8 | #include "../netdecnet/dn_systm.h" |
944419ad | 9 | #include "../net/if.h" |
a37bfda7 BJ |
10 | #include "../netdecnet/tp.h" |
11 | #include "../netdecnet/tp_var.h" | |
944419ad SL |
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 | } |