This source file includes following definitions.
- natm_usrreq
- natmintr
- natm0_sysctl
- natm5_sysctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/domain.h>
43 #include <sys/ioctl.h>
44 #include <sys/proc.h>
45 #include <sys/protosw.h>
46 #include <sys/mbuf.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49
50 #include <net/if.h>
51 #include <net/if_atm.h>
52 #include <net/netisr.h>
53 #include <net/radix.h>
54 #include <net/route.h>
55
56 #include <netinet/in.h>
57
58 #include <netnatm/natm.h>
59
60 u_long natm5_sendspace = 16*1024;
61 u_long natm5_recvspace = 16*1024;
62
63 u_long natm0_sendspace = 16*1024;
64 u_long natm0_recvspace = 16*1024;
65
66
67
68
69
70 #if defined(__NetBSD__)
71 int natm_usrreq(so, req, m, nam, control)
72 #elif defined(__OpenBSD__) || defined(__FreeBSD__)
73 int natm_usrreq(so, req, m, nam, control)
74 #endif
75 struct socket *so;
76 int req;
77 struct mbuf *m, *nam, *control;
78 #if defined(__NetBSD__)
79 struct proc *p;
80 #endif
81 {
82 int error = 0, s, s2;
83 struct natmpcb *npcb;
84 struct sockaddr_natm *snatm;
85 struct atm_pseudoioctl api;
86 struct atm_pseudohdr *aph;
87 struct atm_rawioctl ario;
88 struct ifnet *ifp;
89 int proto = so->so_proto->pr_protocol;
90
91 s = SPLSOFTNET();
92
93 npcb = (struct natmpcb *) so->so_pcb;
94
95 if (npcb == NULL && req != PRU_ATTACH) {
96 error = EINVAL;
97 goto done;
98 }
99
100
101 switch (req) {
102 case PRU_ATTACH:
103
104 if (npcb) {
105 error = EISCONN;
106 break;
107 }
108
109 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
110 if (proto == PROTO_NATMAAL5)
111 error = soreserve(so, natm5_sendspace, natm5_recvspace);
112 else
113 error = soreserve(so, natm0_sendspace, natm0_recvspace);
114 if (error)
115 break;
116 }
117
118 so->so_pcb = (caddr_t) (npcb = npcb_alloc(M_WAITOK));
119 npcb->npcb_socket = so;
120
121 break;
122
123 case PRU_DETACH:
124
125
126
127
128
129 npcb_free(npcb, NPCB_DESTROY);
130 so->so_pcb = NULL;
131 sofree(so);
132
133 break;
134
135 case PRU_CONNECT:
136
137
138
139
140
141 if (nam->m_len != sizeof(*snatm)) {
142 error = EINVAL;
143 break;
144 }
145 snatm = mtod(nam, struct sockaddr_natm *);
146 if (snatm->snatm_len != sizeof(*snatm) ||
147 (npcb->npcb_flags & NPCB_FREE) == 0) {
148 error = EINVAL;
149 break;
150 }
151 if (snatm->snatm_family != AF_NATM) {
152 error = EAFNOSUPPORT;
153 break;
154 }
155
156 snatm->snatm_if[IFNAMSIZ-1] = '\0';
157
158
159
160
161
162
163 ifp = ifunit(snatm->snatm_if);
164 if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0) {
165 error = ENXIO;
166 break;
167 }
168 if (ifp->if_output != atm_output) {
169 error = EAFNOSUPPORT;
170 break;
171 }
172
173
174
175
176
177
178 if (npcb_add(npcb, ifp, snatm->snatm_vci, snatm->snatm_vpi) != npcb) {
179 error = EADDRINUSE;
180 break;
181 }
182
183
184
185
186
187 ATM_PH_FLAGS(&api.aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
188 ATM_PH_VPI(&api.aph) = npcb->npcb_vpi;
189 ATM_PH_SETVCI(&api.aph, npcb->npcb_vci);
190 api.rxhand = npcb;
191 s2 = splnet();
192 if (ifp->if_ioctl == NULL ||
193 ifp->if_ioctl(ifp, SIOCATMENA, (caddr_t) &api) != 0) {
194 splx(s2);
195 npcb_free(npcb, NPCB_REMOVE);
196 error = EIO;
197 break;
198 }
199 splx(s2);
200
201 soisconnected(so);
202
203 break;
204
205 case PRU_DISCONNECT:
206
207 if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) {
208 printf("natm: disconnected check\n");
209 error = EIO;
210 break;
211 }
212 ifp = npcb->npcb_ifp;
213
214
215
216
217
218 ATM_PH_FLAGS(&api.aph) = ATM_PH_AAL5;
219 ATM_PH_VPI(&api.aph) = npcb->npcb_vpi;
220 ATM_PH_SETVCI(&api.aph, npcb->npcb_vci);
221 api.rxhand = npcb;
222 s2 = splnet();
223 if (ifp->if_ioctl != NULL)
224 ifp->if_ioctl(ifp, SIOCATMDIS, (caddr_t) &api);
225 splx(s);
226
227 npcb_free(npcb, NPCB_REMOVE);
228 soisdisconnected(so);
229
230 break;
231
232 case PRU_SHUTDOWN:
233 socantsendmore(so);
234 break;
235
236 case PRU_SEND:
237 if (control && control->m_len) {
238 m_freem(control);
239 m_freem(m);
240 error = EINVAL;
241 break;
242 }
243
244
245
246
247
248 M_PREPEND(m, sizeof(*aph), M_WAITOK);
249 aph = mtod(m, struct atm_pseudohdr *);
250 ATM_PH_VPI(aph) = npcb->npcb_vpi;
251 ATM_PH_SETVCI(aph, npcb->npcb_vci);
252 ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
253
254 error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
255
256 break;
257
258 case PRU_SENSE:
259
260 break;
261
262 case PRU_PEERADDR:
263 snatm = mtod(nam, struct sockaddr_natm *);
264 bzero(snatm, sizeof(*snatm));
265 nam->m_len = snatm->snatm_len = sizeof(*snatm);
266 snatm->snatm_family = AF_NATM;
267 #if defined(__NetBSD__) || defined(__OpenBSD__)
268 bcopy(npcb->npcb_ifp->if_xname, snatm->snatm_if, sizeof(snatm->snatm_if));
269 #elif defined(__FreeBSD__)
270 sprintf(snatm->snatm_if, "%s%d", npcb->npcb_ifp->if_name,
271 npcb->npcb_ifp->if_unit);
272 #endif
273 snatm->snatm_vci = npcb->npcb_vci;
274 snatm->snatm_vpi = npcb->npcb_vpi;
275 break;
276
277 case PRU_CONTROL:
278
279
280
281
282 if ((u_long)m == SIOCRAWATM) {
283 if (npcb->npcb_ifp == NULL) {
284 error = ENOTCONN;
285 break;
286 }
287 ario.npcb = npcb;
288 ario.rawvalue = *((int *)nam);
289 error = npcb->npcb_ifp->if_ioctl(npcb->npcb_ifp,
290 SIOCXRAWATM, (caddr_t) &ario);
291 if (!error) {
292 if (ario.rawvalue)
293 npcb->npcb_flags |= NPCB_RAW;
294 else
295 npcb->npcb_flags &= ~(NPCB_RAW);
296 }
297
298 break;
299 }
300
301 error = EOPNOTSUPP;
302 break;
303
304 case PRU_BIND:
305 case PRU_LISTEN:
306 case PRU_ACCEPT:
307 case PRU_CONNECT2:
308 case PRU_ABORT:
309
310 case PRU_RCVD:
311 case PRU_FASTTIMO:
312 case PRU_SLOWTIMO:
313 case PRU_RCVOOB:
314 case PRU_SENDOOB:
315 case PRU_PROTORCV:
316 case PRU_PROTOSEND:
317 case PRU_SOCKADDR:
318 #ifdef DIAGNOSTIC
319 printf("natm: PRU #%d unsupported\n", req);
320 #endif
321 error = EOPNOTSUPP;
322 break;
323
324 default: panic("natm usrreq");
325 }
326
327 done:
328 splx(s);
329 return(error);
330 }
331
332
333
334
335
336
337
338
339
340 void
341 natmintr()
342
343 {
344 int s;
345 struct mbuf *m;
346 struct socket *so;
347 struct natmpcb *npcb;
348
349 next:
350 s = splnet();
351 IF_DEQUEUE(&natmintrq, m);
352 splx(s);
353 if (m == NULL)
354 return;
355
356 #ifdef DIAGNOSTIC
357 if ((m->m_flags & M_PKTHDR) == 0)
358 panic("natmintr no HDR");
359 #endif
360
361 npcb = (struct natmpcb *) m->m_pkthdr.rcvif;
362 so = npcb->npcb_socket;
363
364 s = splnet();
365 npcb->npcb_inq--;
366 splx(s);
367
368 if (npcb->npcb_flags & NPCB_DRAIN) {
369 m_freem(m);
370 if (npcb->npcb_inq == 0)
371 FREE(npcb, M_PCB);
372 goto next;
373 }
374
375 if (npcb->npcb_flags & NPCB_FREE) {
376 m_freem(m);
377 goto next;
378 }
379
380 #ifdef NEED_TO_RESTORE_IFP
381 m->m_pkthdr.rcvif = npcb->npcb_ifp;
382 #else
383 #ifdef DIAGNOSTIC
384 m->m_pkthdr.rcvif = NULL;
385 #endif
386 #endif
387
388 if (sbspace(&so->so_rcv) > m->m_pkthdr.len ||
389 ((npcb->npcb_flags & NPCB_RAW) != 0 && so->so_rcv.sb_cc < NPCB_RAWCC) ) {
390 #ifdef NATM_STAT
391 natm_sookcnt++;
392 natm_sookbytes += m->m_pkthdr.len;
393 #endif
394 sbappendrecord(&so->so_rcv, m);
395 sorwakeup(so);
396 } else {
397 #ifdef NATM_STAT
398 natm_sodropcnt++;
399 natm_sodropbytes += m->m_pkthdr.len;
400 #endif
401 m_freem(m);
402 }
403
404 goto next;
405 }
406
407 #if defined(__FreeBSD__)
408 NETISR_SET(NETISR_NATM, natmintr);
409 #endif
410
411
412
413
414
415
416
417 int natm0_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
418
419 int *name;
420 u_int namelen;
421 void *oldp;
422 size_t *oldlenp;
423 void *newp;
424 size_t newlen;
425
426 {
427
428 if (namelen != 1)
429 return (ENOTDIR);
430 return (ENOPROTOOPT);
431 }
432
433
434
435
436
437
438 int natm5_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
439
440 int *name;
441 u_int namelen;
442 void *oldp;
443 size_t *oldlenp;
444 void *newp;
445 size_t newlen;
446
447 {
448
449 if (namelen != 1)
450 return (ENOTDIR);
451 return (ENOPROTOOPT);
452 }