2 * ===================================
3 * HARP | Host ATM Research Platform
4 * ===================================
7 * This Host ATM Research Platform ("HARP") file (the "Software") is
8 * made available by Network Computing Services, Inc. ("NetworkCS")
9 * "AS IS". NetworkCS does not provide maintenance, improvements or
10 * support of any kind.
12 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16 * In no event shall NetworkCS be responsible for any damages, including
17 * but not limited to consequential damages, arising from or relating to
18 * any use of the Software or related support.
20 * Copyright 1994-1998 Network Computing Services, Inc.
22 * Copies of this Software may be made, however, the above copyright
23 * notice must be reproduced on all copies.
30 * ATM common socket protocol processing
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/socket.h>
40 #include <sys/socketvar.h>
41 #include <sys/syslog.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_sys.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_cm.h>
49 #include <netatm/atm_if.h>
50 #include <netatm/atm_sigmgr.h>
51 #include <netatm/atm_stack.h>
52 #include <netatm/atm_pcb.h>
53 #include <netatm/atm_var.h>
64 static uma_zone_t atm_pcb_zone;
66 static struct t_atm_cause atm_sock_cause = {
69 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
77 atm_pcb_zone = uma_zcreate("atm pcb", sizeof(Atm_pcb), NULL, NULL,
78 NULL, NULL, UMA_ALIGN_PTR, 0);
79 if (atm_pcb_zone == NULL)
80 panic("atm_sock_init: unable to initialize atm_pcb_zone");
84 * Allocate resources for a new ATM socket
89 * so pointer to socket
90 * send socket send buffer maximum
91 * recv socket receive buffer maximum
95 * errno attach failed - reason indicated
99 atm_sock_attach(so, send, recv)
104 Atm_pcb *atp = sotoatmpcb(so);
108 * Make sure initialization has happened
114 * Make sure we're not already attached
120 * Reserve socket buffer space, if not already done
122 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
123 err = soreserve(so, send, recv);
129 * Allocate and initialize our control block
131 atp = uma_zalloc(atm_pcb_zone, M_ZERO | M_NOWAIT);
135 atp->atp_socket = so;
136 so->so_pcb = (caddr_t)atp;
142 * Detach from socket and free resources
147 * so pointer to socket
150 * 0 detach successful
151 * errno detach failed - reason indicated
158 Atm_pcb *atp = sotoatmpcb(so);
161 * Make sure we're still attached
167 * Terminate any (possibly pending) connection
170 (void) atm_sock_disconnect(so);
174 * Break links and free control blocks
181 uma_zfree(atm_pcb_zone, atp);
188 * Bind local address to socket
193 * so pointer to socket
194 * addr pointer to protocol address
197 * 0 request processed
198 * errno error processing request - reason indicated
202 atm_sock_bind(so, addr)
204 struct sockaddr *addr;
206 Atm_pcb *atp = sotoatmpcb(so);
208 struct sockaddr_atm *satm;
209 struct t_atm_sap_addr *sapadr;
210 struct t_atm_sap_layer2 *sapl2;
211 struct t_atm_sap_layer3 *sapl3;
212 struct t_atm_sap_appl *sapapl;
215 * Make sure we're still attached
221 * Can't change local address once we've started connection process
223 if (atp->atp_conn != NULL)
224 return (EADDRNOTAVAIL);
227 * Validate requested local address
229 satm = (struct sockaddr_atm *)addr;
230 if (satm->satm_family != AF_ATM)
231 return (EAFNOSUPPORT);
233 sapadr = &satm->satm_addr.t_atm_sap_addr;
234 if (sapadr->SVE_tag_addr == T_ATM_PRESENT) {
235 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
236 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
238 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
239 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
243 } else if ((sapadr->SVE_tag_addr != T_ATM_ABSENT) &&
244 (sapadr->SVE_tag_addr != T_ATM_ANY))
246 if (sapadr->address_length > ATM_ADDR_LEN)
249 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
250 if (sapl2->SVE_tag == T_ATM_PRESENT) {
251 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
252 (sapl2->ID_type != T_ATM_USER_ID))
254 } else if ((sapl2->SVE_tag != T_ATM_ABSENT) &&
255 (sapl2->SVE_tag != T_ATM_ANY))
258 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
259 if (sapl3->SVE_tag == T_ATM_PRESENT) {
260 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
261 (sapl3->ID_type != T_ATM_IPI_ID) &&
262 (sapl3->ID_type != T_ATM_SNAP_ID) &&
263 (sapl3->ID_type != T_ATM_USER_ID))
265 } else if ((sapl3->SVE_tag != T_ATM_ABSENT) &&
266 (sapl3->SVE_tag != T_ATM_ANY))
269 sapapl = &satm->satm_addr.t_atm_sap_appl;
270 if (sapapl->SVE_tag == T_ATM_PRESENT) {
271 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
272 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
273 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
275 } else if ((sapapl->SVE_tag != T_ATM_ABSENT) &&
276 (sapapl->SVE_tag != T_ATM_ANY))
280 * Create temporary attributes list so that we can check out the
281 * new bind parameters before we modify the socket's values;
283 attr = atp->atp_attr;
284 attr.called.tag = sapadr->SVE_tag_addr;
285 bcopy(&sapadr->address_format, &attr.called.addr, sizeof(Atm_addr));
287 attr.blli.tag_l2 = sapl2->SVE_tag;
288 if (sapl2->SVE_tag == T_ATM_PRESENT) {
289 attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
290 bcopy(&sapl2->ID, &attr.blli.v.layer_2_protocol.ID,
291 sizeof(attr.blli.v.layer_2_protocol.ID));
294 attr.blli.tag_l3 = sapl3->SVE_tag;
295 if (sapl3->SVE_tag == T_ATM_PRESENT) {
296 attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
297 bcopy(&sapl3->ID, &attr.blli.v.layer_3_protocol.ID,
298 sizeof(attr.blli.v.layer_3_protocol.ID));
301 attr.bhli.tag = sapapl->SVE_tag;
302 if (sapapl->SVE_tag == T_ATM_PRESENT) {
303 attr.bhli.v.ID_type = sapapl->ID_type;
304 bcopy(&sapapl->ID, &attr.bhli.v.ID,
305 sizeof(attr.bhli.v.ID));
309 * Make sure we have unique listening attributes
311 if (atm_cm_match(&attr, NULL) != NULL)
315 * Looks good, save new attributes
317 atp->atp_attr = attr;
324 * Listen for incoming connections
329 * so pointer to socket
330 * epp pointer to endpoint definition structure
333 * 0 request processed
334 * errno error processing request - reason indicated
338 atm_sock_listen(so, epp, backlog)
343 Atm_pcb *atp = sotoatmpcb(so);
346 * Make sure we're still attached
352 * Start listening for incoming calls
354 return (atm_cm_listen(so, epp, atp, &atp->atp_attr, &atp->atp_conn,
360 * Connect socket to peer
365 * so pointer to socket
366 * addr pointer to protocol address
367 * epp pointer to endpoint definition structure
370 * 0 request processed
371 * errno error processing request - reason indicated
375 atm_sock_connect(so, addr, epp)
377 struct sockaddr *addr;
380 Atm_pcb *atp = sotoatmpcb(so);
381 struct sockaddr_atm *satm;
382 struct t_atm_sap_addr *sapadr;
383 struct t_atm_sap_layer2 *sapl2;
384 struct t_atm_sap_layer3 *sapl3;
385 struct t_atm_sap_appl *sapapl;
389 * Make sure we're still attached
395 * Validate requested peer address
397 satm = (struct sockaddr_atm *)addr;
398 if (satm->satm_family != AF_ATM)
399 return (EAFNOSUPPORT);
401 sapadr = &satm->satm_addr.t_atm_sap_addr;
402 if (sapadr->SVE_tag_addr != T_ATM_PRESENT)
404 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
405 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
407 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
408 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
410 } else if (sapadr->address_format == T_ATM_PVC_ADDR) {
411 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
415 if (sapadr->address_length > ATM_ADDR_LEN)
418 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
419 if (sapl2->SVE_tag == T_ATM_PRESENT) {
420 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
421 (sapl2->ID_type != T_ATM_USER_ID))
423 } else if (sapl2->SVE_tag != T_ATM_ABSENT)
426 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
427 if (sapl3->SVE_tag == T_ATM_PRESENT) {
428 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
429 (sapl3->ID_type != T_ATM_IPI_ID) &&
430 (sapl3->ID_type != T_ATM_SNAP_ID) &&
431 (sapl3->ID_type != T_ATM_USER_ID))
433 } else if (sapl3->SVE_tag != T_ATM_ABSENT)
436 sapapl = &satm->satm_addr.t_atm_sap_appl;
437 if (sapapl->SVE_tag == T_ATM_PRESENT) {
438 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
439 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
440 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
442 } else if (sapapl->SVE_tag != T_ATM_ABSENT)
446 * Select an outgoing network interface
448 if (atp->atp_attr.nif == NULL) {
451 for (pip = atm_interface_head; pip != NULL;
452 pip = pip->pif_next) {
453 if (pip->pif_nif != NULL) {
454 atp->atp_attr.nif = pip->pif_nif;
458 if (atp->atp_attr.nif == NULL)
463 * Set supplied connection attributes
465 atp->atp_attr.called.tag = T_ATM_PRESENT;
466 bcopy(&sapadr->address_format, &atp->atp_attr.called.addr,
469 atp->atp_attr.blli.tag_l2 = sapl2->SVE_tag;
470 if (sapl2->SVE_tag == T_ATM_PRESENT) {
471 atp->atp_attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
472 bcopy(&sapl2->ID, &atp->atp_attr.blli.v.layer_2_protocol.ID,
473 sizeof(atp->atp_attr.blli.v.layer_2_protocol.ID));
476 atp->atp_attr.blli.tag_l3 = sapl3->SVE_tag;
477 if (sapl3->SVE_tag == T_ATM_PRESENT) {
478 atp->atp_attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
479 bcopy(&sapl3->ID, &atp->atp_attr.blli.v.layer_3_protocol.ID,
480 sizeof(atp->atp_attr.blli.v.layer_3_protocol.ID));
483 atp->atp_attr.bhli.tag = sapapl->SVE_tag;
484 if (sapapl->SVE_tag == T_ATM_PRESENT) {
485 atp->atp_attr.bhli.v.ID_type = sapapl->ID_type;
486 bcopy(&sapapl->ID, &atp->atp_attr.bhli.v.ID,
487 sizeof(atp->atp_attr.bhli.v.ID));
491 * We're finally ready to initiate the ATM connection
494 atm_sock_stat.as_connreq[atp->atp_type]++;
495 err = atm_cm_connect(epp, atp, &atp->atp_attr, &atp->atp_conn);
498 * Connection is setup
500 atm_sock_stat.as_conncomp[atp->atp_type]++;
503 } else if (err == EINPROGRESS) {
505 * We've got to wait for a connected event
513 atm_sock_stat.as_connfail[atp->atp_type]++;
514 soisdisconnected(so);
522 * Disconnect connected socket
527 * so pointer to socket
530 * 0 request processed
531 * errno error processing request - reason indicated
535 atm_sock_disconnect(so)
538 Atm_pcb *atp = sotoatmpcb(so);
539 struct t_atm_cause *cause;
543 * Make sure we're still attached
549 * Release the ATM connection
552 if (atp->atp_attr.cause.tag == T_ATM_PRESENT)
553 cause = &atp->atp_attr.cause.v;
555 cause = &atm_sock_cause;
556 err = atm_cm_release(atp->atp_conn, cause);
558 log(LOG_ERR, "atm_sock_disconnect: release fail (%d)\n",
560 atm_sock_stat.as_connrel[atp->atp_type]++;
561 atp->atp_conn = NULL;
564 soisdisconnected(so);
571 * Retrieve local socket address
576 * so pointer to socket
577 * addr pointer to pointer to contain protocol address
580 * 0 request processed
581 * errno error processing request - reason indicated
585 atm_sock_sockaddr(so, addr)
587 struct sockaddr **addr;
589 struct sockaddr_atm *satm;
590 struct t_atm_sap_addr *saddr;
591 Atm_pcb *atp = sotoatmpcb(so);
594 * Return local interface address, if known
596 satm = malloc(sizeof(*satm), M_SONAME, M_WAITOK | M_ZERO);
600 satm->satm_family = AF_ATM;
601 satm->satm_len = sizeof(*satm);
603 saddr = &satm->satm_addr.t_atm_sap_addr;
604 if (atp->atp_attr.nif && atp->atp_attr.nif->nif_pif->pif_siginst) {
605 saddr->SVE_tag_addr = T_ATM_PRESENT;
607 &atp->atp_attr.nif->nif_pif->pif_siginst->si_addr,
608 atp->atp_attr.nif->nif_sel, saddr);
609 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
610 saddr->SVE_tag_selector = T_ATM_PRESENT;
612 saddr->SVE_tag_selector = T_ATM_ABSENT;
614 saddr->SVE_tag_addr = T_ATM_ABSENT;
615 saddr->SVE_tag_selector = T_ATM_ABSENT;
616 saddr->address_format = T_ATM_ABSENT;
618 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
619 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
620 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
622 *addr = (struct sockaddr *)satm;
628 * Retrieve peer socket address
633 * so pointer to socket
634 * addr pointer to pointer to contain protocol address
637 * 0 request processed
638 * errno error processing request - reason indicated
642 atm_sock_peeraddr(so, addr)
644 struct sockaddr **addr;
646 struct sockaddr_atm *satm;
647 struct t_atm_sap_addr *saddr;
648 Atm_pcb *atp = sotoatmpcb(so);
652 * Return remote address, if known
654 satm = malloc(sizeof(*satm), M_SONAME, M_WAITOK | M_ZERO);
658 satm->satm_family = AF_ATM;
659 satm->satm_len = sizeof(*satm);
660 saddr = &satm->satm_addr.t_atm_sap_addr;
661 if (so->so_state & SS_ISCONNECTED) {
662 cvp = atp->atp_conn->co_connvc;
663 saddr->SVE_tag_addr = T_ATM_PRESENT;
664 if (cvp->cvc_flags & CVCF_CALLER) {
665 ATM_ADDR_COPY(&cvp->cvc_attr.called.addr, saddr);
667 if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
668 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
671 saddr->SVE_tag_addr = T_ATM_ABSENT;
672 saddr->address_format = T_ATM_ABSENT;
675 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
676 saddr->SVE_tag_selector = T_ATM_PRESENT;
678 saddr->SVE_tag_selector = T_ATM_ABSENT;
680 saddr->SVE_tag_addr = T_ATM_ABSENT;
681 saddr->SVE_tag_selector = T_ATM_ABSENT;
682 saddr->address_format = T_ATM_ABSENT;
684 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
685 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
686 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
688 *addr = (struct sockaddr *)satm;
694 * Common setsockopt processing
699 * so pointer to socket
700 * sopt pointer to socket option info
701 * atp pointer to ATM PCB
704 * 0 request processed
705 * errno error processing request - reason indicated
709 atm_sock_setopt(so, sopt, atp)
711 struct sockopt *sopt;
716 struct t_atm_aal5 aal5;
717 struct t_atm_traffic trf;
718 struct t_atm_bearer brr;
719 struct t_atm_bhli bhl;
720 struct t_atm_blli bll;
722 struct t_atm_cause cau;
723 struct t_atm_qos qos;
724 struct t_atm_transit trn;
725 struct t_atm_net_intf nif;
726 struct t_atm_llc llc;
727 struct t_atm_app_name appn;
730 #define MAXVAL(bits) ((1 << bits) - 1)
731 #define MAXMASK(bits) (~MAXVAL(bits))
733 switch (sopt->sopt_name) {
736 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
739 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
740 (p.aal5.forward_max_SDU_size & MAXMASK(16)))
742 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
743 (p.aal5.backward_max_SDU_size & MAXMASK(16)))
745 if ((p.aal5.SSCS_type != T_ATM_ABSENT) &&
746 (p.aal5.SSCS_type != T_ATM_NULL) &&
747 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_REL) &&
748 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_UNREL) &&
749 (p.aal5.SSCS_type != T_ATM_SSCS_FR))
752 if ((p.aal5.forward_max_SDU_size == T_ATM_ABSENT) &&
753 (p.aal5.backward_max_SDU_size == T_ATM_ABSENT) &&
754 (p.aal5.SSCS_type == T_ATM_ABSENT))
755 atp->atp_attr.aal.tag = T_ATM_ABSENT;
757 atp->atp_attr.aal.tag = T_ATM_PRESENT;
758 atp->atp_attr.aal.type = ATM_AAL5;
759 atp->atp_attr.aal.v.aal5 = p.aal5;
764 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
767 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
768 (p.trf.forward.PCR_high_priority & MAXMASK(24)))
770 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
772 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
773 (p.trf.forward.SCR_high_priority & MAXMASK(24)))
775 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
776 (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
778 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
779 (p.trf.forward.MBS_high_priority & MAXMASK(24)))
781 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
782 (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
784 if ((p.trf.forward.tagging != T_YES) &&
785 (p.trf.forward.tagging != T_NO))
788 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
789 (p.trf.backward.PCR_high_priority & MAXMASK(24)))
791 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
793 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
794 (p.trf.backward.SCR_high_priority & MAXMASK(24)))
796 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
797 (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
799 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
800 (p.trf.backward.MBS_high_priority & MAXMASK(24)))
802 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
803 (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
805 if ((p.trf.backward.tagging != T_YES) &&
806 (p.trf.backward.tagging != T_NO))
808 if ((p.trf.best_effort != T_YES) &&
809 (p.trf.best_effort != T_NO))
812 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
813 atp->atp_attr.traffic.v = p.trf;
816 case T_ATM_BEARER_CAP:
817 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
820 if ((p.brr.bearer_class != T_ATM_CLASS_A) &&
821 (p.brr.bearer_class != T_ATM_CLASS_C) &&
822 (p.brr.bearer_class != T_ATM_CLASS_X))
824 if ((p.brr.traffic_type != T_ATM_NULL) &&
825 (p.brr.traffic_type != T_ATM_CBR) &&
826 (p.brr.traffic_type != T_ATM_VBR) &&
827 (p.brr.traffic_type != T_ATM_ABR) &&
828 (p.brr.traffic_type != T_ATM_UBR))
830 if ((p.brr.timing_requirements != T_ATM_NULL) &&
831 (p.brr.timing_requirements != T_ATM_END_TO_END) &&
832 (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
834 if ((p.brr.clipping_susceptibility != T_NO) &&
835 (p.brr.clipping_susceptibility != T_YES))
837 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
838 (p.brr.connection_configuration != T_ATM_1_TO_MANY))
841 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
842 atp->atp_attr.bearer.v = p.brr;
846 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
849 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
850 (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
851 (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
852 (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
855 if (p.bhl.ID_type == T_ATM_ABSENT)
856 atp->atp_attr.bhli.tag = T_ATM_ABSENT;
858 atp->atp_attr.bhli.tag = T_ATM_PRESENT;
859 atp->atp_attr.bhli.v = p.bhl;
864 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
867 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
868 (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
869 (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
871 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
872 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
873 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
875 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
876 (p.bll.layer_2_protocol.window_size < 1))
879 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
880 (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
881 (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
882 (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
883 (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
885 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
886 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
887 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
889 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
890 (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
892 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
893 (p.bll.layer_3_protocol.window_size < 1))
896 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT)
897 atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
899 atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
901 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT)
902 atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
904 atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
906 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
907 (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
908 atp->atp_attr.blli.v = p.bll;
911 case T_ATM_DEST_ADDR:
912 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
915 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
916 (p.addr.address_format != T_ATM_E164_ADDR))
918 if (p.addr.address_length > ATM_ADDR_LEN)
921 atp->atp_attr.called.tag = T_ATM_PRESENT;
922 atp->atp_attr.called.addr = p.addr;
926 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
929 if ((p.addr.address_format != T_ATM_ABSENT) &&
930 (p.addr.address_format != T_ATM_NSAP_ADDR))
932 if (p.addr.address_length > ATM_ADDR_LEN)
935 /* T_ATM_DEST_ADDR controls tag */
936 atp->atp_attr.called.subaddr = p.addr;
939 case T_ATM_ORIG_ADDR:
945 case T_ATM_CALLER_ID:
949 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
952 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
953 (p.cau.coding_standard != T_ATM_ITU_CODING) &&
954 (p.cau.coding_standard != T_ATM_NETWORK_CODING))
956 if ((p.cau.location != T_ATM_LOC_USER) &&
957 (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
958 (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
959 (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
960 (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
961 (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
962 (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
963 (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
966 if (p.cau.coding_standard == T_ATM_ABSENT)
967 atp->atp_attr.cause.tag = T_ATM_ABSENT;
969 atp->atp_attr.cause.tag = T_ATM_PRESENT;
970 atp->atp_attr.cause.v = p.cau;
975 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
978 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
979 (p.qos.coding_standard != T_ATM_ITU_CODING) &&
980 (p.qos.coding_standard != T_ATM_NETWORK_CODING))
982 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
983 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
984 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
985 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
986 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
988 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
989 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
990 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
991 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
992 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
995 if (p.qos.coding_standard == T_ATM_ABSENT)
996 atp->atp_attr.qos.tag = T_ATM_ABSENT;
998 atp->atp_attr.qos.tag = T_ATM_PRESENT;
999 atp->atp_attr.qos.v = p.qos;
1004 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
1007 if (p.trn.length > T_ATM_MAX_NET_ID)
1010 if (p.trn.length == 0)
1011 atp->atp_attr.transit.tag = T_ATM_ABSENT;
1013 atp->atp_attr.transit.tag = T_ATM_PRESENT;
1014 atp->atp_attr.transit.v = p.trn;
1018 case T_ATM_ADD_LEAF:
1019 return (EPROTONOSUPPORT); /* XXX */
1021 case T_ATM_DROP_LEAF:
1022 return (EPROTONOSUPPORT); /* XXX */
1024 case T_ATM_NET_INTF:
1025 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
1029 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
1030 if (atp->atp_attr.nif == NULL)
1035 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
1038 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
1039 (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
1042 atp->atp_attr.llc.tag = T_ATM_PRESENT;
1043 atp->atp_attr.llc.v = p.llc;
1046 case T_ATM_APP_NAME:
1047 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
1051 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
1055 return (ENOPROTOOPT);
1063 * Common getsockopt processing
1068 * so pointer to socket
1069 * sopt pointer to socket option info
1070 * atp pointer to ATM PCB
1073 * 0 request processed
1074 * errno error processing request - reason indicated
1078 atm_sock_getopt(so, sopt, atp)
1080 struct sockopt *sopt;
1086 * If socket is connected, return attributes for the VCC in use,
1087 * otherwise just return what the user has setup so far.
1089 if (so->so_state & SS_ISCONNECTED)
1090 ap = &atp->atp_conn->co_connvc->cvc_attr;
1092 ap = &atp->atp_attr;
1094 switch (sopt->sopt_name) {
1097 if ((ap->aal.tag == T_ATM_PRESENT) &&
1098 (ap->aal.type == ATM_AAL5)) {
1099 return (sooptcopyout(sopt, &ap->aal.v.aal5,
1100 sizeof ap->aal.v.aal5));
1107 if (ap->traffic.tag == T_ATM_PRESENT) {
1108 return (sooptcopyout(sopt, &ap->traffic.v,
1109 sizeof ap->traffic.v));
1115 case T_ATM_BEARER_CAP:
1116 if (ap->bearer.tag == T_ATM_PRESENT) {
1117 return (sooptcopyout(sopt, &ap->bearer.v,
1118 sizeof ap->bearer.v));
1125 if (ap->bhli.tag == T_ATM_PRESENT) {
1126 return (sooptcopyout(sopt, &ap->bhli.v,
1127 sizeof ap->bhli.v));
1134 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
1135 (ap->blli.tag_l3 == T_ATM_PRESENT)) {
1136 return (sooptcopyout(sopt, &ap->blli.v,
1137 sizeof ap->blli.v));
1143 case T_ATM_DEST_ADDR:
1144 if (ap->called.tag == T_ATM_PRESENT) {
1145 return (sooptcopyout(sopt, &ap->called.addr,
1146 sizeof ap->called.addr));
1152 case T_ATM_DEST_SUB:
1153 if (ap->called.tag == T_ATM_PRESENT) {
1154 return (sooptcopyout(sopt, &ap->called.subaddr,
1155 sizeof ap->called.subaddr));
1161 case T_ATM_ORIG_ADDR:
1162 if (ap->calling.tag == T_ATM_PRESENT) {
1163 return (sooptcopyout(sopt, &ap->calling.addr,
1164 sizeof ap->calling.addr));
1170 case T_ATM_ORIG_SUB:
1171 if (ap->calling.tag == T_ATM_PRESENT) {
1172 return (sooptcopyout(sopt, &ap->calling.subaddr,
1173 sizeof ap->calling.subaddr));
1179 case T_ATM_CALLER_ID:
1180 if (ap->calling.tag == T_ATM_PRESENT) {
1181 return (sooptcopyout(sopt, &ap->calling.cid,
1182 sizeof ap->calling.cid));
1189 if (ap->cause.tag == T_ATM_PRESENT) {
1190 return (sooptcopyout(sopt, &ap->cause.v,
1191 sizeof ap->cause.v));
1198 if (ap->qos.tag == T_ATM_PRESENT) {
1199 return (sooptcopyout(sopt, &ap->qos.v,
1207 if (ap->transit.tag == T_ATM_PRESENT) {
1208 return (sooptcopyout(sopt, &ap->transit.v,
1209 sizeof ap->transit.v));
1215 case T_ATM_LEAF_IND:
1216 return (EPROTONOSUPPORT); /* XXX */
1218 case T_ATM_NET_INTF:
1220 struct t_atm_net_intf netif;
1223 ifp = ANIF2IFP(ap->nif);
1224 (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
1225 "%s", ifp->if_xname);
1226 return (sooptcopyout(sopt, &netif,
1234 if (ap->llc.tag == T_ATM_PRESENT) {
1235 return (sooptcopyout(sopt, &ap->llc.v,
1243 return (ENOPROTOOPT);
1251 * Process Socket VCC Connected Notification
1254 * toku owner's connection token (atm_pcb protocol block)
1261 atm_sock_connected(toku)
1264 Atm_pcb *atp = (Atm_pcb *)toku;
1267 * Connection is setup
1269 atm_sock_stat.as_conncomp[atp->atp_type]++;
1270 soisconnected(atp->atp_socket);
1275 * Process Socket VCC Cleared Notification
1278 * toku owner's connection token (atm_pcb protocol block)
1279 * cause pointer to cause code
1286 atm_sock_cleared(toku, cause)
1288 struct t_atm_cause *cause;
1290 Atm_pcb *atp = (Atm_pcb *)toku;
1293 so = atp->atp_socket;
1296 * Save call clearing cause
1298 atp->atp_attr.cause.tag = T_ATM_PRESENT;
1299 atp->atp_attr.cause.v = *cause;
1302 * Set user error code
1304 if (so->so_state & SS_ISCONNECTED) {
1305 so->so_error = ECONNRESET;
1306 atm_sock_stat.as_connclr[atp->atp_type]++;
1308 so->so_error = ECONNREFUSED;
1309 atm_sock_stat.as_connfail[atp->atp_type]++;
1313 * Connection is gone
1315 atp->atp_conn = NULL;
1316 soisdisconnected(so);
1319 * Cleanup failed incoming connection setup
1321 if (so->so_state & SS_NOFDREF) {
1322 (void) atm_sock_detach(so);