1 /*
2 *
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
6 *
7 *
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
12 *
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
20 *
21 * Copyright 1994-1998 Network Computing Services, Inc.
22 *
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
25 *
26 * @(#) $FreeBSD$
27 *
28 */
29
30 /*
31 * Core ATM Services
32 * -----------------
33 *
34 * ATM common socket protocol processing
35 *
36 */
37
38 #include <netatm/kern_include.h>
39
40 #ifndef lint
41 __RCSID("@(#) $FreeBSD$");
42 #endif
43
44
45 /*
46 * Local functions
47 */
48
49
50 /*
51 * Local variables
52 */
53 static struct sp_info atm_pcb_pool = {
54 "atm pcb pool", /* si_name */
55 sizeof(Atm_pcb), /* si_blksiz */
56 10, /* si_blkcnt */
57 100 /* si_maxallow */
58 };
59
60 static struct t_atm_cause atm_sock_cause = {
61 T_ATM_ITU_CODING,
62 T_ATM_LOC_USER,
63 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
64 {0, 0, 0, 0}
65 };
66
67
68 /*
69 * Allocate resources for a new ATM socket
70 *
71 * Called at splnet.
72 *
73 * Arguments:
74 * so pointer to socket
75 * send socket send buffer maximum
76 * recv socket receive buffer maximum
77 *
78 * Returns:
79 * 0 attach successful
80 * errno attach failed - reason indicated
81 *
82 */
83 int
84 atm_sock_attach(so, send, recv)
85 struct socket *so;
86 u_long send;
87 u_long recv;
88 {
89 Atm_pcb *atp = sotoatmpcb(so);
90 int err;
91
92 /*
93 * Make sure initialization has happened
94 */
95 if (!atm_init)
96 atm_initialize();
97
98 /*
99 * Make sure we're not already attached
100 */
101 if (atp)
102 return (EISCONN);
103
104 /*
105 * Reserve socket buffer space, if not already done
106 */
107 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
108 err = soreserve(so, send, recv);
109 if (err)
110 return (err);
111 }
112
113 /*
114 * Allocate and initialize our control block
115 */
116 atp = (Atm_pcb *)atm_allocate(&atm_pcb_pool);
117 if (atp == NULL)
118 return (ENOMEM);
119
120 atp->atp_socket = so;
121 so->so_pcb = (caddr_t)atp;
122 return (0);
123 }
124
125
126 /*
127 * Detach from socket and free resources
128 *
129 * Called at splnet.
130 *
131 * Arguments:
132 * so pointer to socket
133 *
134 * Returns:
135 * 0 detach successful
136 * errno detach failed - reason indicated
137 *
138 */
139 int
140 atm_sock_detach(so)
141 struct socket *so;
142 {
143 Atm_pcb *atp = sotoatmpcb(so);
144
145 /*
146 * Make sure we're still attached
147 */
148 if (atp == NULL)
149 return (ENOTCONN);
150
151 /*
152 * Terminate any (possibly pending) connection
153 */
154 if (atp->atp_conn) {
155 (void) atm_sock_disconnect(so);
156 }
157
158 /*
159 * Break links and free control blocks
160 */
161 so->so_pcb = NULL;
162 sofree(so);
163
164 atm_free((caddr_t)atp);
165
166 return (0);
167 }
168
169
170 /*
171 * Bind local address to socket
172 *
173 * Called at splnet.
174 *
175 * Arguments:
176 * so pointer to socket
177 * addr pointer to protocol address
178 *
179 * Returns:
180 * 0 request processed
181 * errno error processing request - reason indicated
182 *
183 */
184 int
185 atm_sock_bind(so, addr)
186 struct socket *so;
187 struct sockaddr *addr;
188 {
189 Atm_pcb *atp = sotoatmpcb(so);
190 Atm_attributes attr;
191 struct sockaddr_atm *satm;
192 struct t_atm_sap_addr *sapadr;
193 struct t_atm_sap_layer2 *sapl2;
194 struct t_atm_sap_layer3 *sapl3;
195 struct t_atm_sap_appl *sapapl;
196
197 /*
198 * Make sure we're still attached
199 */
200 if (atp == NULL)
201 return (ENOTCONN);
202
203 /*
204 * Can't change local address once we've started connection process
205 */
206 if (atp->atp_conn != NULL)
207 return (EADDRNOTAVAIL);
208
209 /*
210 * Validate requested local address
211 */
212 satm = (struct sockaddr_atm *)addr;
213 if (satm->satm_family != AF_ATM)
214 return (EAFNOSUPPORT);
215
216 sapadr = &satm->satm_addr.t_atm_sap_addr;
217 if (sapadr->SVE_tag_addr == T_ATM_PRESENT) {
218 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
219 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
220 return (EINVAL);
221 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
222 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
223 return (EINVAL);
224 } else
225 return (EINVAL);
226 } else if ((sapadr->SVE_tag_addr != T_ATM_ABSENT) &&
227 (sapadr->SVE_tag_addr != T_ATM_ANY))
228 return (EINVAL);
229 if (sapadr->address_length > ATM_ADDR_LEN)
230 return (EINVAL);
231
232 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
233 if (sapl2->SVE_tag == T_ATM_PRESENT) {
234 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
235 (sapl2->ID_type != T_ATM_USER_ID))
236 return (EINVAL);
237 } else if ((sapl2->SVE_tag != T_ATM_ABSENT) &&
238 (sapl2->SVE_tag != T_ATM_ANY))
239 return (EINVAL);
240
241 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
242 if (sapl3->SVE_tag == T_ATM_PRESENT) {
243 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
244 (sapl3->ID_type != T_ATM_IPI_ID) &&
245 (sapl3->ID_type != T_ATM_SNAP_ID) &&
246 (sapl3->ID_type != T_ATM_USER_ID))
247 return (EINVAL);
248 } else if ((sapl3->SVE_tag != T_ATM_ABSENT) &&
249 (sapl3->SVE_tag != T_ATM_ANY))
250 return (EINVAL);
251
252 sapapl = &satm->satm_addr.t_atm_sap_appl;
253 if (sapapl->SVE_tag == T_ATM_PRESENT) {
254 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
255 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
256 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
257 return (EINVAL);
258 } else if ((sapapl->SVE_tag != T_ATM_ABSENT) &&
259 (sapapl->SVE_tag != T_ATM_ANY))
260 return (EINVAL);
261
262 /*
263 * Create temporary attributes list so that we can check out the
264 * new bind parameters before we modify the socket's values;
265 */
266 attr = atp->atp_attr;
267 attr.called.tag = sapadr->SVE_tag_addr;
268 KM_COPY(&sapadr->address_format, &attr.called.addr, sizeof(Atm_addr));
269
270 attr.blli.tag_l2 = sapl2->SVE_tag;
271 if (sapl2->SVE_tag == T_ATM_PRESENT) {
272 attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
273 KM_COPY(&sapl2->ID, &attr.blli.v.layer_2_protocol.ID,
274 sizeof(attr.blli.v.layer_2_protocol.ID));
275 }
276
277 attr.blli.tag_l3 = sapl3->SVE_tag;
278 if (sapl3->SVE_tag == T_ATM_PRESENT) {
279 attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
280 KM_COPY(&sapl3->ID, &attr.blli.v.layer_3_protocol.ID,
281 sizeof(attr.blli.v.layer_3_protocol.ID));
282 }
283
284 attr.bhli.tag = sapapl->SVE_tag;
285 if (sapapl->SVE_tag == T_ATM_PRESENT) {
286 attr.bhli.v.ID_type = sapapl->ID_type;
287 KM_COPY(&sapapl->ID, &attr.bhli.v.ID,
288 sizeof(attr.bhli.v.ID));
289 }
290
291 /*
292 * Make sure we have unique listening attributes
293 */
294 if (atm_cm_match(&attr, NULL) != NULL)
295 return (EADDRINUSE);
296
297 /*
298 * Looks good, save new attributes
299 */
300 atp->atp_attr = attr;
301
302 return (0);
303 }
304
305
306 /*
307 * Listen for incoming connections
308 *
309 * Called at splnet.
310 *
311 * Arguments:
312 * so pointer to socket
313 * epp pointer to endpoint definition structure
314 *
315 * Returns:
316 * 0 request processed
317 * errno error processing request - reason indicated
318 *
319 */
320 int
321 atm_sock_listen(so, epp)
322 struct socket *so;
323 Atm_endpoint *epp;
324 {
325 Atm_pcb *atp = sotoatmpcb(so);
326
327 /*
328 * Make sure we're still attached
329 */
330 if (atp == NULL)
331 return (ENOTCONN);
332
333 /*
334 * Start listening for incoming calls
335 */
336 return (atm_cm_listen(epp, atp, &atp->atp_attr, &atp->atp_conn));
337 }
338
339
340 /*
341 * Connect socket to peer
342 *
343 * Called at splnet.
344 *
345 * Arguments:
346 * so pointer to socket
347 * addr pointer to protocol address
348 * epp pointer to endpoint definition structure
349 *
350 * Returns:
351 * 0 request processed
352 * errno error processing request - reason indicated
353 *
354 */
355 int
356 atm_sock_connect(so, addr, epp)
357 struct socket *so;
358 struct sockaddr *addr;
359 Atm_endpoint *epp;
360 {
361 Atm_pcb *atp = sotoatmpcb(so);
362 struct sockaddr_atm *satm;
363 struct t_atm_sap_addr *sapadr;
364 struct t_atm_sap_layer2 *sapl2;
365 struct t_atm_sap_layer3 *sapl3;
366 struct t_atm_sap_appl *sapapl;
367 int err;
368
369 /*
370 * Make sure we're still attached
371 */
372 if (atp == NULL)
373 return (ENOTCONN);
374
375 /*
376 * Validate requested peer address
377 */
378 satm = (struct sockaddr_atm *)addr;
379 if (satm->satm_family != AF_ATM)
380 return (EAFNOSUPPORT);
381
382 sapadr = &satm->satm_addr.t_atm_sap_addr;
383 if (sapadr->SVE_tag_addr != T_ATM_PRESENT)
384 return (EINVAL);
385 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
386 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
387 return (EINVAL);
388 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
389 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
390 return (EINVAL);
391 } else if (sapadr->address_format == T_ATM_PVC_ADDR) {
392 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
393 return (EINVAL);
394 } else
395 return (EINVAL);
396 if (sapadr->address_length > ATM_ADDR_LEN)
397 return (EINVAL);
398
399 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
400 if (sapl2->SVE_tag == T_ATM_PRESENT) {
401 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
402 (sapl2->ID_type != T_ATM_USER_ID))
403 return (EINVAL);
404 } else if (sapl2->SVE_tag != T_ATM_ABSENT)
405 return (EINVAL);
406
407 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
408 if (sapl3->SVE_tag == T_ATM_PRESENT) {
409 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
410 (sapl3->ID_type != T_ATM_IPI_ID) &&
411 (sapl3->ID_type != T_ATM_SNAP_ID) &&
412 (sapl3->ID_type != T_ATM_USER_ID))
413 return (EINVAL);
414 } else if (sapl3->SVE_tag != T_ATM_ABSENT)
415 return (EINVAL);
416
417 sapapl = &satm->satm_addr.t_atm_sap_appl;
418 if (sapapl->SVE_tag == T_ATM_PRESENT) {
419 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
420 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
421 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
422 return (EINVAL);
423 } else if (sapapl->SVE_tag != T_ATM_ABSENT)
424 return (EINVAL);
425
426 /*
427 * Select an outgoing network interface
428 */
429 if (atp->atp_attr.nif == NULL) {
430 struct atm_pif *pip;
431
432 for (pip = atm_interface_head; pip != NULL;
433 pip = pip->pif_next) {
434 if (pip->pif_nif != NULL) {
435 atp->atp_attr.nif = pip->pif_nif;
436 break;
437 }
438 }
439 if (atp->atp_attr.nif == NULL)
440 return (ENXIO);
441 }
442
443 /*
444 * Set supplied connection attributes
445 */
446 atp->atp_attr.called.tag = T_ATM_PRESENT;
447 KM_COPY(&sapadr->address_format, &atp->atp_attr.called.addr,
448 sizeof(Atm_addr));
449
450 atp->atp_attr.blli.tag_l2 = sapl2->SVE_tag;
451 if (sapl2->SVE_tag == T_ATM_PRESENT) {
452 atp->atp_attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
453 KM_COPY(&sapl2->ID, &atp->atp_attr.blli.v.layer_2_protocol.ID,
454 sizeof(atp->atp_attr.blli.v.layer_2_protocol.ID));
455 }
456
457 atp->atp_attr.blli.tag_l3 = sapl3->SVE_tag;
458 if (sapl3->SVE_tag == T_ATM_PRESENT) {
459 atp->atp_attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
460 KM_COPY(&sapl3->ID, &atp->atp_attr.blli.v.layer_3_protocol.ID,
461 sizeof(atp->atp_attr.blli.v.layer_3_protocol.ID));
462 }
463
464 atp->atp_attr.bhli.tag = sapapl->SVE_tag;
465 if (sapapl->SVE_tag == T_ATM_PRESENT) {
466 atp->atp_attr.bhli.v.ID_type = sapapl->ID_type;
467 KM_COPY(&sapapl->ID, &atp->atp_attr.bhli.v.ID,
468 sizeof(atp->atp_attr.bhli.v.ID));
469 }
470
471 /*
472 * We're finally ready to initiate the ATM connection
473 */
474 soisconnecting(so);
475 atm_sock_stat.as_connreq[atp->atp_type]++;
476 err = atm_cm_connect(epp, atp, &atp->atp_attr, &atp->atp_conn);
477 if (err == 0) {
478 /*
479 * Connection is setup
480 */
481 atm_sock_stat.as_conncomp[atp->atp_type]++;
482 soisconnected(so);
483
484 } else if (err == EINPROGRESS) {
485 /*
486 * We've got to wait for a connected event
487 */
488 err = 0;
489
490 } else {
491 /*
492 * Call failed...
493 */
494 atm_sock_stat.as_connfail[atp->atp_type]++;
495 soisdisconnected(so);
496 }
497
498 return (err);
499 }
500
501
502 /*
503 * Disconnect connected socket
504 *
505 * Called at splnet.
506 *
507 * Arguments:
508 * so pointer to socket
509 *
510 * Returns:
511 * 0 request processed
512 * errno error processing request - reason indicated
513 *
514 */
515 int
516 atm_sock_disconnect(so)
517 struct socket *so;
518 {
519 Atm_pcb *atp = sotoatmpcb(so);
520 struct t_atm_cause *cause;
521 int err;
522
523 /*
524 * Make sure we're still attached
525 */
526 if (atp == NULL)
527 return (ENOTCONN);
528
529 /*
530 * Release the ATM connection
531 */
532 if (atp->atp_conn) {
533 if (atp->atp_attr.cause.tag == T_ATM_PRESENT)
534 cause = &atp->atp_attr.cause.v;
535 else
536 cause = &atm_sock_cause;
537 err = atm_cm_release(atp->atp_conn, cause);
538 if (err)
539 log(LOG_ERR, "atm_sock_disconnect: release fail (%d)\n",
540 err);
541 atm_sock_stat.as_connrel[atp->atp_type]++;
542 atp->atp_conn = NULL;
543 }
544
545 soisdisconnected(so);
546
547 return (0);
548 }
549
550
551 /*
552 * Retrieve local socket address
553 *
554 * Called at splnet.
555 *
556 * Arguments:
557 * so pointer to socket
558 * addr pointer to pointer to contain protocol address
559 *
560 * Returns:
561 * 0 request processed
562 * errno error processing request - reason indicated
563 *
564 */
565 int
566 atm_sock_sockaddr(so, addr)
567 struct socket *so;
568 struct sockaddr **addr;
569 {
570 struct sockaddr_atm *satm;
571 struct t_atm_sap_addr *saddr;
572 Atm_pcb *atp = sotoatmpcb(so);
573
574 /*
575 * Return local interface address, if known
576 */
577 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
578 if (satm == NULL)
579 return (ENOMEM);
580
581 KM_ZERO(satm, sizeof(*satm));
582 satm->satm_family = AF_ATM;
583 #if (defined(BSD) && (BSD >= 199103))
584 satm->satm_len = sizeof(*satm);
585 #endif
586
587 saddr = &satm->satm_addr.t_atm_sap_addr;
588 if (atp->atp_attr.nif && atp->atp_attr.nif->nif_pif->pif_siginst) {
589 saddr->SVE_tag_addr = T_ATM_PRESENT;
590 ATM_ADDR_SEL_COPY(
591 &atp->atp_attr.nif->nif_pif->pif_siginst->si_addr,
592 atp->atp_attr.nif->nif_sel, saddr);
593 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
594 saddr->SVE_tag_selector = T_ATM_PRESENT;
595 else
596 saddr->SVE_tag_selector = T_ATM_ABSENT;
597 } else {
598 saddr->SVE_tag_addr = T_ATM_ABSENT;
599 saddr->SVE_tag_selector = T_ATM_ABSENT;
600 saddr->address_format = T_ATM_ABSENT;
601 }
602 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
603 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
604 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
605
606 *addr = (struct sockaddr *)satm;
607 return (0);
608 }
609
610
611 /*
612 * Retrieve peer socket address
613 *
614 * Called at splnet.
615 *
616 * Arguments:
617 * so pointer to socket
618 * addr pointer to pointer to contain protocol address
619 *
620 * Returns:
621 * 0 request processed
622 * errno error processing request - reason indicated
623 *
624 */
625 int
626 atm_sock_peeraddr(so, addr)
627 struct socket *so;
628 struct sockaddr **addr;
629 {
630 struct sockaddr_atm *satm;
631 struct t_atm_sap_addr *saddr;
632 Atm_pcb *atp = sotoatmpcb(so);
633 Atm_connvc *cvp;
634
635 /*
636 * Return remote address, if known
637 */
638 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
639 if (satm == NULL)
640 return (ENOMEM);
641
642 KM_ZERO(satm, sizeof(*satm));
643 satm->satm_family = AF_ATM;
644 #if (defined(BSD) && (BSD >= 199103))
645 satm->satm_len = sizeof(*satm);
646 #endif
647
648 saddr = &satm->satm_addr.t_atm_sap_addr;
649 if (so->so_state & SS_ISCONNECTED) {
650 cvp = atp->atp_conn->co_connvc;
651 saddr->SVE_tag_addr = T_ATM_PRESENT;
652 if (cvp->cvc_flags & CVCF_CALLER) {
653 ATM_ADDR_COPY(&cvp->cvc_attr.called.addr, saddr);
654 } else {
655 if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
656 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
657 saddr);
658 } else {
659 saddr->SVE_tag_addr = T_ATM_ABSENT;
660 saddr->address_format = T_ATM_ABSENT;
661 }
662 }
663 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
664 saddr->SVE_tag_selector = T_ATM_PRESENT;
665 else
666 saddr->SVE_tag_selector = T_ATM_ABSENT;
667 } else {
668 saddr->SVE_tag_addr = T_ATM_ABSENT;
669 saddr->SVE_tag_selector = T_ATM_ABSENT;
670 saddr->address_format = T_ATM_ABSENT;
671 }
672 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
673 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
674 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
675
676 *addr = (struct sockaddr *)satm;
677 return (0);
678 }
679
680
681 /*
682 * Common setsockopt processing
683 *
684 * Called at splnet.
685 *
686 * Arguments:
687 * so pointer to socket
688 * sopt pointer to socket option info
689 * atp pointer to ATM PCB
690 *
691 * Returns:
692 * 0 request processed
693 * errno error processing request - reason indicated
694 *
695 */
696 int
697 atm_sock_setopt(so, sopt, atp)
698 struct socket *so;
699 struct sockopt *sopt;
700 Atm_pcb *atp;
701 {
702 int err = 0;
703 union {
704 struct t_atm_aal5 aal5;
705 struct t_atm_traffic trf;
706 struct t_atm_bearer brr;
707 struct t_atm_bhli bhl;
708 struct t_atm_blli bll;
709 Atm_addr addr;
710 struct t_atm_cause cau;
711 struct t_atm_qos qos;
712 struct t_atm_transit trn;
713 struct t_atm_net_intf nif;
714 struct t_atm_llc llc;
715 struct t_atm_app_name appn;
716 } p;
717
718 #define MAXVAL(bits) ((1 << bits) - 1)
719 #define MAXMASK(bits) (~MAXVAL(bits))
720
721 switch (sopt->sopt_name) {
722
723 case T_ATM_AAL5:
724 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
725 if (err)
726 break;
727 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
728 (p.aal5.forward_max_SDU_size & MAXMASK(16)))
729 return (EINVAL);
730 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
731 (p.aal5.backward_max_SDU_size & MAXMASK(16)))
732 return (EINVAL);
733 if ((p.aal5.SSCS_type != T_ATM_ABSENT) &&
734 (p.aal5.SSCS_type != T_ATM_NULL) &&
735 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_REL) &&
736 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_UNREL) &&
737 (p.aal5.SSCS_type != T_ATM_SSCS_FR))
738 return (EINVAL);
739
740 if ((p.aal5.forward_max_SDU_size == T_ATM_ABSENT) &&
741 (p.aal5.backward_max_SDU_size == T_ATM_ABSENT) &&
742 (p.aal5.SSCS_type == T_ATM_ABSENT))
743 atp->atp_attr.aal.tag = T_ATM_ABSENT;
744 else {
745 atp->atp_attr.aal.tag = T_ATM_PRESENT;
746 atp->atp_attr.aal.type = ATM_AAL5;
747 atp->atp_attr.aal.v.aal5 = p.aal5;
748 }
749 break;
750
751 case T_ATM_TRAFFIC:
752 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
753 if (err)
754 break;
755 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
756 (p.trf.forward.PCR_high_priority & MAXMASK(24)))
757 return (EINVAL);
758 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
759 return (EINVAL);
760 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
761 (p.trf.forward.SCR_high_priority & MAXMASK(24)))
762 return (EINVAL);
763 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
764 (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
765 return (EINVAL);
766 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
767 (p.trf.forward.MBS_high_priority & MAXMASK(24)))
768 return (EINVAL);
769 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
770 (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
771 return (EINVAL);
772 if ((p.trf.forward.tagging != T_YES) &&
773 (p.trf.forward.tagging != T_NO))
774 return (EINVAL);
775
776 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
777 (p.trf.backward.PCR_high_priority & MAXMASK(24)))
778 return (EINVAL);
779 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
780 return (EINVAL);
781 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
782 (p.trf.backward.SCR_high_priority & MAXMASK(24)))
783 return (EINVAL);
784 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
785 (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
786 return (EINVAL);
787 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
788 (p.trf.backward.MBS_high_priority & MAXMASK(24)))
789 return (EINVAL);
790 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
791 (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
792 return (EINVAL);
793 if ((p.trf.backward.tagging != T_YES) &&
794 (p.trf.backward.tagging != T_NO))
795 return (EINVAL);
796 if ((p.trf.best_effort != T_YES) &&
797 (p.trf.best_effort != T_NO))
798 return (EINVAL);
799
800 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
801 atp->atp_attr.traffic.v = p.trf;
802 break;
803
804 case T_ATM_BEARER_CAP:
805 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
806 if (err)
807 break;
808 if ((p.brr.bearer_class != T_ATM_CLASS_A) &&
809 (p.brr.bearer_class != T_ATM_CLASS_C) &&
810 (p.brr.bearer_class != T_ATM_CLASS_X))
811 return (EINVAL);
812 if ((p.brr.traffic_type != T_ATM_NULL) &&
813 (p.brr.traffic_type != T_ATM_CBR) &&
814 (p.brr.traffic_type != T_ATM_VBR) &&
815 (p.brr.traffic_type != T_ATM_ABR) &&
816 (p.brr.traffic_type != T_ATM_UBR))
817 return (EINVAL);
818 if ((p.brr.timing_requirements != T_ATM_NULL) &&
819 (p.brr.timing_requirements != T_ATM_END_TO_END) &&
820 (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
821 return (EINVAL);
822 if ((p.brr.clipping_susceptibility != T_NO) &&
823 (p.brr.clipping_susceptibility != T_YES))
824 return (EINVAL);
825 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
826 (p.brr.connection_configuration != T_ATM_1_TO_MANY))
827 return (EINVAL);
828
829 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
830 atp->atp_attr.bearer.v = p.brr;
831 break;
832
833 case T_ATM_BHLI:
834 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
835 if (err)
836 break;
837 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
838 (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
839 (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
840 (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
841 return (EINVAL);
842
843 if (p.bhl.ID_type == T_ATM_ABSENT)
844 atp->atp_attr.bhli.tag = T_ATM_ABSENT;
845 else {
846 atp->atp_attr.bhli.tag = T_ATM_PRESENT;
847 atp->atp_attr.bhli.v = p.bhl;
848 }
849 break;
850
851 case T_ATM_BLLI:
852 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
853 if (err)
854 break;
855 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
856 (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
857 (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
858 return (EINVAL);
859 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
860 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
861 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
862 return (EINVAL);
863 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
864 (p.bll.layer_2_protocol.window_size < 1))
865 return (EINVAL);
866
867 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
868 (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
869 (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
870 (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
871 (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
872 return (EINVAL);
873 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
874 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
875 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
876 return (EINVAL);
877 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
878 (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
879 return (EINVAL);
880 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
881 (p.bll.layer_3_protocol.window_size < 1))
882 return (EINVAL);
883
884 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT)
885 atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
886 else
887 atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
888
889 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT)
890 atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
891 else
892 atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
893
894 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
895 (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
896 atp->atp_attr.blli.v = p.bll;
897 break;
898
899 case T_ATM_DEST_ADDR:
900 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
901 if (err)
902 break;
903 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
904 (p.addr.address_format != T_ATM_E164_ADDR))
905 return (EINVAL);
906 if (p.addr.address_length > ATM_ADDR_LEN)
907 return (EINVAL);
908
909 atp->atp_attr.called.tag = T_ATM_PRESENT;
910 atp->atp_attr.called.addr = p.addr;
911 break;
912
913 case T_ATM_DEST_SUB:
914 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
915 if (err)
916 break;
917 if ((p.addr.address_format != T_ATM_ABSENT) &&
918 (p.addr.address_format != T_ATM_NSAP_ADDR))
919 return (EINVAL);
920 if (p.addr.address_length > ATM_ADDR_LEN)
921 return (EINVAL);
922
923 /* T_ATM_DEST_ADDR controls tag */
924 atp->atp_attr.called.subaddr = p.addr;
925 break;
926
927 case T_ATM_ORIG_ADDR:
928 return (EACCES);
929
930 case T_ATM_ORIG_SUB:
931 return (EACCES);
932
933 case T_ATM_CALLER_ID:
934 return (EACCES);
935
936 case T_ATM_CAUSE:
937 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
938 if (err)
939 break;
940 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
941 (p.cau.coding_standard != T_ATM_ITU_CODING) &&
942 (p.cau.coding_standard != T_ATM_NETWORK_CODING))
943 return (EINVAL);
944 if ((p.cau.location != T_ATM_LOC_USER) &&
945 (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
946 (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
947 (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
948 (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
949 (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
950 (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
951 (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
952 return (EINVAL);
953
954 if (p.cau.coding_standard == T_ATM_ABSENT)
955 atp->atp_attr.cause.tag = T_ATM_ABSENT;
956 else {
957 atp->atp_attr.cause.tag = T_ATM_PRESENT;
958 atp->atp_attr.cause.v = p.cau;
959 }
960 break;
961
962 case T_ATM_QOS:
963 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
964 if (err)
965 break;
966 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
967 (p.qos.coding_standard != T_ATM_ITU_CODING) &&
968 (p.qos.coding_standard != T_ATM_NETWORK_CODING))
969 return (EINVAL);
970 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
971 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
972 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
973 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
974 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
975 return (EINVAL);
976 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
977 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
978 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
979 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
980 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
981 return (EINVAL);
982
983 if (p.qos.coding_standard == T_ATM_ABSENT)
984 atp->atp_attr.qos.tag = T_ATM_ABSENT;
985 else {
986 atp->atp_attr.qos.tag = T_ATM_PRESENT;
987 atp->atp_attr.qos.v = p.qos;
988 }
989 break;
990
991 case T_ATM_TRANSIT:
992 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
993 if (err)
994 break;
995 if (p.trn.length > T_ATM_MAX_NET_ID)
996 return (EINVAL);
997
998 if (p.trn.length == 0)
999 atp->atp_attr.transit.tag = T_ATM_ABSENT;
1000 else {
1001 atp->atp_attr.transit.tag = T_ATM_PRESENT;
1002 atp->atp_attr.transit.v = p.trn;
1003 }
1004 break;
1005
1006 case T_ATM_ADD_LEAF:
1007 return (EPROTONOSUPPORT); /* XXX */
1008
1009 case T_ATM_DROP_LEAF:
1010 return (EPROTONOSUPPORT); /* XXX */
1011
1012 case T_ATM_NET_INTF:
1013 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
1014 if (err)
1015 break;
1016
1017 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
1018 if (atp->atp_attr.nif == NULL)
1019 return (ENXIO);
1020 break;
1021
1022 case T_ATM_LLC:
1023 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
1024 if (err)
1025 break;
1026 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
1027 (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
1028 return (EINVAL);
1029
1030 atp->atp_attr.llc.tag = T_ATM_PRESENT;
1031 atp->atp_attr.llc.v = p.llc;
1032 break;
1033
1034 case T_ATM_APP_NAME:
1035 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
1036 if (err)
1037 break;
1038
1039 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
1040 break;
1041
1042 default:
1043 return (ENOPROTOOPT);
1044 }
1045
1046 return (err);
1047 }
1048
1049
1050 /*
1051 * Common getsockopt processing
1052 *
1053 * Called at splnet.
1054 *
1055 * Arguments:
1056 * so pointer to socket
1057 * sopt pointer to socket option info
1058 * atp pointer to ATM PCB
1059 *
1060 * Returns:
1061 * 0 request processed
1062 * errno error processing request - reason indicated
1063 *
1064 */
1065 int
1066 atm_sock_getopt(so, sopt, atp)
1067 struct socket *so;
1068 struct sockopt *sopt;
1069 Atm_pcb *atp;
1070 {
1071 Atm_attributes *ap;
1072
1073 /*
1074 * If socket is connected, return attributes for the VCC in use,
1075 * otherwise just return what the user has setup so far.
1076 */
1077 if (so->so_state & SS_ISCONNECTED)
1078 ap = &atp->atp_conn->co_connvc->cvc_attr;
1079 else
1080 ap = &atp->atp_attr;
1081
1082 switch (sopt->sopt_name) {
1083
1084 case T_ATM_AAL5:
1085 if ((ap->aal.tag == T_ATM_PRESENT) &&
1086 (ap->aal.type == ATM_AAL5)) {
1087 return (sooptcopyout(sopt, &ap->aal.v.aal5,
1088 sizeof ap->aal.v.aal5));
1089 } else {
1090 return (ENOENT);
1091 }
1092 break;
1093
1094 case T_ATM_TRAFFIC:
1095 if (ap->traffic.tag == T_ATM_PRESENT) {
1096 return (sooptcopyout(sopt, &ap->traffic.v,
1097 sizeof ap->traffic.v));
1098 } else {
1099 return (ENOENT);
1100 }
1101 break;
1102
1103 case T_ATM_BEARER_CAP:
1104 if (ap->bearer.tag == T_ATM_PRESENT) {
1105 return (sooptcopyout(sopt, &ap->bearer.v,
1106 sizeof ap->bearer.v));
1107 } else {
1108 return (ENOENT);
1109 }
1110 break;
1111
1112 case T_ATM_BHLI:
1113 if (ap->bhli.tag == T_ATM_PRESENT) {
1114 return (sooptcopyout(sopt, &ap->bhli.v,
1115 sizeof ap->bhli.v));
1116 } else {
1117 return (ENOENT);
1118 }
1119 break;
1120
1121 case T_ATM_BLLI:
1122 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
1123 (ap->blli.tag_l3 == T_ATM_PRESENT)) {
1124 return (sooptcopyout(sopt, &ap->blli.v,
1125 sizeof ap->blli.v));
1126 } else {
1127 return (ENOENT);
1128 }
1129 break;
1130
1131 case T_ATM_DEST_ADDR:
1132 if (ap->called.tag == T_ATM_PRESENT) {
1133 return (sooptcopyout(sopt, &ap->called.addr,
1134 sizeof ap->called.addr));
1135 } else {
1136 return (ENOENT);
1137 }
1138 break;
1139
1140 case T_ATM_DEST_SUB:
1141 if (ap->called.tag == T_ATM_PRESENT) {
1142 return (sooptcopyout(sopt, &ap->called.subaddr,
1143 sizeof ap->called.subaddr));
1144 } else {
1145 return (ENOENT);
1146 }
1147 break;
1148
1149 case T_ATM_ORIG_ADDR:
1150 if (ap->calling.tag == T_ATM_PRESENT) {
1151 return (sooptcopyout(sopt, &ap->calling.addr,
1152 sizeof ap->calling.addr));
1153 } else {
1154 return (ENOENT);
1155 }
1156 break;
1157
1158 case T_ATM_ORIG_SUB:
1159 if (ap->calling.tag == T_ATM_PRESENT) {
1160 return (sooptcopyout(sopt, &ap->calling.subaddr,
1161 sizeof ap->calling.subaddr));
1162 } else {
1163 return (ENOENT);
1164 }
1165 break;
1166
1167 case T_ATM_CALLER_ID:
1168 if (ap->calling.tag == T_ATM_PRESENT) {
1169 return (sooptcopyout(sopt, &ap->calling.cid,
1170 sizeof ap->calling.cid));
1171 } else {
1172 return (ENOENT);
1173 }
1174 break;
1175
1176 case T_ATM_CAUSE:
1177 if (ap->cause.tag == T_ATM_PRESENT) {
1178 return (sooptcopyout(sopt, &ap->cause.v,
1179 sizeof ap->cause.v));
1180 } else {
1181 return (ENOENT);
1182 }
1183 break;
1184
1185 case T_ATM_QOS:
1186 if (ap->qos.tag == T_ATM_PRESENT) {
1187 return (sooptcopyout(sopt, &ap->qos.v,
1188 sizeof ap->qos.v));
1189 } else {
1190 return (ENOENT);
1191 }
1192 break;
1193
1194 case T_ATM_TRANSIT:
1195 if (ap->transit.tag == T_ATM_PRESENT) {
1196 return (sooptcopyout(sopt, &ap->transit.v,
1197 sizeof ap->transit.v));
1198 } else {
1199 return (ENOENT);
1200 }
1201 break;
1202
1203 case T_ATM_LEAF_IND:
1204 return (EPROTONOSUPPORT); /* XXX */
1205
1206 case T_ATM_NET_INTF:
1207 if (ap->nif) {
1208 struct t_atm_net_intf netif;
1209 struct ifnet *ifp;
1210
1211 ifp = &ap->nif->nif_if;
1212 (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
1213 "%s%d", ifp->if_name, ifp->if_unit);
1214 return (sooptcopyout(sopt, &netif,
1215 sizeof netif));
1216 } else {
1217 return (ENOENT);
1218 }
1219 break;
1220
1221 case T_ATM_LLC:
1222 if (ap->llc.tag == T_ATM_PRESENT) {
1223 return (sooptcopyout(sopt, &ap->llc.v,
1224 sizeof ap->llc.v));
1225 } else {
1226 return (ENOENT);
1227 }
1228 break;
1229
1230 default:
1231 return (ENOPROTOOPT);
1232 }
1233
1234 return (0);
1235 }
1236
1237
1238 /*
1239 * Process Socket VCC Connected Notification
1240 *
1241 * Arguments:
1242 * toku owner's connection token (atm_pcb protocol block)
1243 *
1244 * Returns:
1245 * none
1246 *
1247 */
1248 void
1249 atm_sock_connected(toku)
1250 void *toku;
1251 {
1252 Atm_pcb *atp = (Atm_pcb *)toku;
1253
1254 /*
1255 * Connection is setup
1256 */
1257 atm_sock_stat.as_conncomp[atp->atp_type]++;
1258 soisconnected(atp->atp_socket);
1259 }
1260
1261
1262 /*
1263 * Process Socket VCC Cleared Notification
1264 *
1265 * Arguments:
1266 * toku owner's connection token (atm_pcb protocol block)
1267 * cause pointer to cause code
1268 *
1269 * Returns:
1270 * none
1271 *
1272 */
1273 void
1274 atm_sock_cleared(toku, cause)
1275 void *toku;
1276 struct t_atm_cause *cause;
1277 {
1278 Atm_pcb *atp = (Atm_pcb *)toku;
1279 struct socket *so;
1280
1281 so = atp->atp_socket;
1282
1283 /*
1284 * Save call clearing cause
1285 */
1286 atp->atp_attr.cause.tag = T_ATM_PRESENT;
1287 atp->atp_attr.cause.v = *cause;
1288
1289 /*
1290 * Set user error code
1291 */
1292 if (so->so_state & SS_ISCONNECTED) {
1293 so->so_error = ECONNRESET;
1294 atm_sock_stat.as_connclr[atp->atp_type]++;
1295 } else {
1296 so->so_error = ECONNREFUSED;
1297 atm_sock_stat.as_connfail[atp->atp_type]++;
1298 }
1299
1300 /*
1301 * Connection is gone
1302 */
1303 atp->atp_conn = NULL;
1304 soisdisconnected(so);
1305
1306 /*
1307 * Cleanup failed incoming connection setup
1308 */
1309 if (so->so_state & SS_NOFDREF) {
1310 (void) atm_sock_detach(so);
1311 }
1312 }
1313
Cache object: 51e87cef587e24db06d0c19260de2024
|