3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
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.
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.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/atm_socket.c,v 1.4 1999/08/28 00:48:37 peter Exp $
34 * ATM common socket protocol processing
38 #include <netatm/kern_include.h>
41 __RCSID("@(#) $FreeBSD: src/sys/netatm/atm_socket.c,v 1.4 1999/08/28 00:48:37 peter Exp $");
53 static struct sp_info atm_pcb_pool = {
54 "atm pcb pool", /* si_name */
55 sizeof(Atm_pcb), /* si_blksiz */
60 static struct t_atm_cause atm_sock_cause = {
63 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
69 * Allocate resources for a new ATM socket
74 * so pointer to socket
75 * send socket send buffer maximum
76 * recv socket receive buffer maximum
80 * errno attach failed - reason indicated
84 atm_sock_attach(so, send, recv)
89 Atm_pcb *atp = sotoatmpcb(so);
93 * Make sure initialization has happened
99 * Make sure we're not already attached
105 * Reserve socket buffer space, if not already done
107 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
108 err = soreserve(so, send, recv);
114 * Allocate and initialize our control block
116 atp = (Atm_pcb *)atm_allocate(&atm_pcb_pool);
120 atp->atp_socket = so;
121 so->so_pcb = (caddr_t)atp;
127 * Detach from socket and free resources
132 * so pointer to socket
135 * 0 detach successful
136 * errno detach failed - reason indicated
143 Atm_pcb *atp = sotoatmpcb(so);
146 * Make sure we're still attached
152 * Terminate any (possibly pending) connection
155 (void) atm_sock_disconnect(so);
159 * Break links and free control blocks
164 atm_free((caddr_t)atp);
171 * Bind local address to socket
176 * so pointer to socket
177 * addr pointer to protocol address
180 * 0 request processed
181 * errno error processing request - reason indicated
185 atm_sock_bind(so, addr)
187 struct sockaddr *addr;
189 Atm_pcb *atp = sotoatmpcb(so);
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;
198 * Make sure we're still attached
204 * Can't change local address once we've started connection process
206 if (atp->atp_conn != NULL)
207 return (EADDRNOTAVAIL);
210 * Validate requested local address
212 satm = (struct sockaddr_atm *)addr;
213 if (satm->satm_family != AF_ATM)
214 return (EAFNOSUPPORT);
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)
221 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
222 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
226 } else if ((sapadr->SVE_tag_addr != T_ATM_ABSENT) &&
227 (sapadr->SVE_tag_addr != T_ATM_ANY))
229 if (sapadr->address_length > ATM_ADDR_LEN)
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))
237 } else if ((sapl2->SVE_tag != T_ATM_ABSENT) &&
238 (sapl2->SVE_tag != T_ATM_ANY))
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))
248 } else if ((sapl3->SVE_tag != T_ATM_ABSENT) &&
249 (sapl3->SVE_tag != T_ATM_ANY))
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))
258 } else if ((sapapl->SVE_tag != T_ATM_ABSENT) &&
259 (sapapl->SVE_tag != T_ATM_ANY))
263 * Create temporary attributes list so that we can check out the
264 * new bind parameters before we modify the socket's values;
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));
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));
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));
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));
292 * Make sure we have unique listening attributes
294 if (atm_cm_match(&attr, NULL) != NULL)
298 * Looks good, save new attributes
300 atp->atp_attr = attr;
307 * Listen for incoming connections
312 * so pointer to socket
313 * epp pointer to endpoint definition structure
316 * 0 request processed
317 * errno error processing request - reason indicated
321 atm_sock_listen(so, epp)
325 Atm_pcb *atp = sotoatmpcb(so);
328 * Make sure we're still attached
334 * Start listening for incoming calls
336 return (atm_cm_listen(epp, atp, &atp->atp_attr, &atp->atp_conn));
341 * Connect socket to peer
346 * so pointer to socket
347 * addr pointer to protocol address
348 * epp pointer to endpoint definition structure
351 * 0 request processed
352 * errno error processing request - reason indicated
356 atm_sock_connect(so, addr, epp)
358 struct sockaddr *addr;
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;
370 * Make sure we're still attached
376 * Validate requested peer address
378 satm = (struct sockaddr_atm *)addr;
379 if (satm->satm_family != AF_ATM)
380 return (EAFNOSUPPORT);
382 sapadr = &satm->satm_addr.t_atm_sap_addr;
383 if (sapadr->SVE_tag_addr != T_ATM_PRESENT)
385 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
386 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
388 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
389 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
391 } else if (sapadr->address_format == T_ATM_PVC_ADDR) {
392 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
396 if (sapadr->address_length > ATM_ADDR_LEN)
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))
404 } else if (sapl2->SVE_tag != T_ATM_ABSENT)
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))
414 } else if (sapl3->SVE_tag != T_ATM_ABSENT)
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))
423 } else if (sapapl->SVE_tag != T_ATM_ABSENT)
427 * Select an outgoing network interface
429 if (atp->atp_attr.nif == NULL) {
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;
439 if (atp->atp_attr.nif == NULL)
444 * Set supplied connection attributes
446 atp->atp_attr.called.tag = T_ATM_PRESENT;
447 KM_COPY(&sapadr->address_format, &atp->atp_attr.called.addr,
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));
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));
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));
472 * We're finally ready to initiate the ATM connection
475 atm_sock_stat.as_connreq[atp->atp_type]++;
476 err = atm_cm_connect(epp, atp, &atp->atp_attr, &atp->atp_conn);
479 * Connection is setup
481 atm_sock_stat.as_conncomp[atp->atp_type]++;
484 } else if (err == EINPROGRESS) {
486 * We've got to wait for a connected event
494 atm_sock_stat.as_connfail[atp->atp_type]++;
495 soisdisconnected(so);
503 * Disconnect connected socket
508 * so pointer to socket
511 * 0 request processed
512 * errno error processing request - reason indicated
516 atm_sock_disconnect(so)
519 Atm_pcb *atp = sotoatmpcb(so);
520 struct t_atm_cause *cause;
524 * Make sure we're still attached
530 * Release the ATM connection
533 if (atp->atp_attr.cause.tag == T_ATM_PRESENT)
534 cause = &atp->atp_attr.cause.v;
536 cause = &atm_sock_cause;
537 err = atm_cm_release(atp->atp_conn, cause);
539 log(LOG_ERR, "atm_sock_disconnect: release fail (%d)\n",
541 atm_sock_stat.as_connrel[atp->atp_type]++;
542 atp->atp_conn = NULL;
545 soisdisconnected(so);
552 * Retrieve local socket address
557 * so pointer to socket
558 * addr pointer to pointer to contain protocol address
561 * 0 request processed
562 * errno error processing request - reason indicated
566 atm_sock_sockaddr(so, addr)
568 struct sockaddr **addr;
570 struct sockaddr_atm *satm;
571 struct t_atm_sap_addr *saddr;
572 Atm_pcb *atp = sotoatmpcb(so);
575 * Return local interface address, if known
577 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
581 KM_ZERO(satm, sizeof(*satm));
582 satm->satm_family = AF_ATM;
583 #if (defined(BSD) && (BSD >= 199103))
584 satm->satm_len = sizeof(*satm);
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;
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;
596 saddr->SVE_tag_selector = T_ATM_ABSENT;
598 saddr->SVE_tag_addr = T_ATM_ABSENT;
599 saddr->SVE_tag_selector = T_ATM_ABSENT;
600 saddr->address_format = T_ATM_ABSENT;
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;
606 *addr = (struct sockaddr *)satm;
612 * Retrieve peer socket address
617 * so pointer to socket
618 * addr pointer to pointer to contain protocol address
621 * 0 request processed
622 * errno error processing request - reason indicated
626 atm_sock_peeraddr(so, addr)
628 struct sockaddr **addr;
630 struct sockaddr_atm *satm;
631 struct t_atm_sap_addr *saddr;
632 Atm_pcb *atp = sotoatmpcb(so);
636 * Return remote address, if known
638 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
642 KM_ZERO(satm, sizeof(*satm));
643 satm->satm_family = AF_ATM;
644 #if (defined(BSD) && (BSD >= 199103))
645 satm->satm_len = sizeof(*satm);
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);
655 if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
656 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
659 saddr->SVE_tag_addr = T_ATM_ABSENT;
660 saddr->address_format = T_ATM_ABSENT;
663 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
664 saddr->SVE_tag_selector = T_ATM_PRESENT;
666 saddr->SVE_tag_selector = T_ATM_ABSENT;
668 saddr->SVE_tag_addr = T_ATM_ABSENT;
669 saddr->SVE_tag_selector = T_ATM_ABSENT;
670 saddr->address_format = T_ATM_ABSENT;
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;
676 *addr = (struct sockaddr *)satm;
682 * Common setsockopt processing
687 * so pointer to socket
688 * sopt pointer to socket option info
689 * atp pointer to ATM PCB
692 * 0 request processed
693 * errno error processing request - reason indicated
697 atm_sock_setopt(so, sopt, atp)
699 struct sockopt *sopt;
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;
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;
718 #define MAXVAL(bits) ((1 << bits) - 1)
719 #define MAXMASK(bits) (~MAXVAL(bits))
721 switch (sopt->sopt_name) {
724 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
727 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
728 (p.aal5.forward_max_SDU_size & MAXMASK(16)))
730 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
731 (p.aal5.backward_max_SDU_size & MAXMASK(16)))
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))
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;
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;
752 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
755 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
756 (p.trf.forward.PCR_high_priority & MAXMASK(24)))
758 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
760 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
761 (p.trf.forward.SCR_high_priority & MAXMASK(24)))
763 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
764 (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
766 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
767 (p.trf.forward.MBS_high_priority & MAXMASK(24)))
769 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
770 (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
772 if ((p.trf.forward.tagging != T_YES) &&
773 (p.trf.forward.tagging != T_NO))
776 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
777 (p.trf.backward.PCR_high_priority & MAXMASK(24)))
779 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
781 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
782 (p.trf.backward.SCR_high_priority & MAXMASK(24)))
784 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
785 (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
787 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
788 (p.trf.backward.MBS_high_priority & MAXMASK(24)))
790 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
791 (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
793 if ((p.trf.backward.tagging != T_YES) &&
794 (p.trf.backward.tagging != T_NO))
796 if ((p.trf.best_effort != T_YES) &&
797 (p.trf.best_effort != T_NO))
800 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
801 atp->atp_attr.traffic.v = p.trf;
804 case T_ATM_BEARER_CAP:
805 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
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))
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))
816 if ((p.brr.timing_requirements != T_ATM_NULL) &&
817 (p.brr.timing_requirements != T_ATM_END_TO_END) &&
818 (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
820 if ((p.brr.clipping_susceptibility != T_NO) &&
821 (p.brr.clipping_susceptibility != T_YES))
823 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
824 (p.brr.connection_configuration != T_ATM_1_TO_MANY))
827 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
828 atp->atp_attr.bearer.v = p.brr;
832 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
835 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
836 (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
837 (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
838 (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
841 if (p.bhl.ID_type == T_ATM_ABSENT)
842 atp->atp_attr.bhli.tag = T_ATM_ABSENT;
844 atp->atp_attr.bhli.tag = T_ATM_PRESENT;
845 atp->atp_attr.bhli.v = p.bhl;
850 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
853 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
854 (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
855 (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
857 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
858 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
859 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
861 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
862 (p.bll.layer_2_protocol.window_size < 1))
865 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
866 (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
867 (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
868 (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
869 (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
871 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
872 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
873 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
875 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
876 (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
878 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
879 (p.bll.layer_3_protocol.window_size < 1))
882 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT)
883 atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
885 atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
887 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT)
888 atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
890 atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
892 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
893 (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
894 atp->atp_attr.blli.v = p.bll;
897 case T_ATM_DEST_ADDR:
898 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
901 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
902 (p.addr.address_format != T_ATM_E164_ADDR))
904 if (p.addr.address_length > ATM_ADDR_LEN)
907 atp->atp_attr.called.tag = T_ATM_PRESENT;
908 atp->atp_attr.called.addr = p.addr;
912 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
915 if ((p.addr.address_format != T_ATM_ABSENT) &&
916 (p.addr.address_format != T_ATM_NSAP_ADDR))
918 if (p.addr.address_length > ATM_ADDR_LEN)
921 /* T_ATM_DEST_ADDR controls tag */
922 atp->atp_attr.called.subaddr = p.addr;
925 case T_ATM_ORIG_ADDR:
931 case T_ATM_CALLER_ID:
935 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
938 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
939 (p.cau.coding_standard != T_ATM_ITU_CODING) &&
940 (p.cau.coding_standard != T_ATM_NETWORK_CODING))
942 if ((p.cau.location != T_ATM_LOC_USER) &&
943 (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
944 (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
945 (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
946 (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
947 (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
948 (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
949 (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
952 if (p.cau.coding_standard == T_ATM_ABSENT)
953 atp->atp_attr.cause.tag = T_ATM_ABSENT;
955 atp->atp_attr.cause.tag = T_ATM_PRESENT;
956 atp->atp_attr.cause.v = p.cau;
961 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
964 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
965 (p.qos.coding_standard != T_ATM_ITU_CODING) &&
966 (p.qos.coding_standard != T_ATM_NETWORK_CODING))
968 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
969 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
970 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
971 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
972 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
974 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
975 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
976 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
977 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
978 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
981 if (p.qos.coding_standard == T_ATM_ABSENT)
982 atp->atp_attr.qos.tag = T_ATM_ABSENT;
984 atp->atp_attr.qos.tag = T_ATM_PRESENT;
985 atp->atp_attr.qos.v = p.qos;
990 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
993 if (p.trn.length > T_ATM_MAX_NET_ID)
996 if (p.trn.length == 0)
997 atp->atp_attr.transit.tag = T_ATM_ABSENT;
999 atp->atp_attr.transit.tag = T_ATM_PRESENT;
1000 atp->atp_attr.transit.v = p.trn;
1004 case T_ATM_ADD_LEAF:
1005 return (EPROTONOSUPPORT); /* XXX */
1007 case T_ATM_DROP_LEAF:
1008 return (EPROTONOSUPPORT); /* XXX */
1010 case T_ATM_NET_INTF:
1011 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
1015 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
1016 if (atp->atp_attr.nif == NULL)
1021 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
1024 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
1025 (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
1028 atp->atp_attr.llc.tag = T_ATM_PRESENT;
1029 atp->atp_attr.llc.v = p.llc;
1032 case T_ATM_APP_NAME:
1033 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
1037 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
1041 return (ENOPROTOOPT);
1049 * Common getsockopt processing
1054 * so pointer to socket
1055 * sopt pointer to socket option info
1056 * atp pointer to ATM PCB
1059 * 0 request processed
1060 * errno error processing request - reason indicated
1064 atm_sock_getopt(so, sopt, atp)
1066 struct sockopt *sopt;
1072 * If socket is connected, return attributes for the VCC in use,
1073 * otherwise just return what the user has setup so far.
1075 if (so->so_state & SS_ISCONNECTED)
1076 ap = &atp->atp_conn->co_connvc->cvc_attr;
1078 ap = &atp->atp_attr;
1080 switch (sopt->sopt_name) {
1083 if ((ap->aal.tag == T_ATM_PRESENT) &&
1084 (ap->aal.type == ATM_AAL5)) {
1085 return (sooptcopyout(sopt, &ap->aal.v.aal5,
1086 sizeof ap->aal.v.aal5));
1093 if (ap->traffic.tag == T_ATM_PRESENT) {
1094 return (sooptcopyout(sopt, &ap->traffic.v,
1095 sizeof ap->traffic.v));
1101 case T_ATM_BEARER_CAP:
1102 if (ap->bearer.tag == T_ATM_PRESENT) {
1103 return (sooptcopyout(sopt, &ap->bearer.v,
1104 sizeof ap->bearer.v));
1111 if (ap->bhli.tag == T_ATM_PRESENT) {
1112 return (sooptcopyout(sopt, &ap->bhli.v,
1113 sizeof ap->bhli.v));
1120 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
1121 (ap->blli.tag_l3 == T_ATM_PRESENT)) {
1122 return (sooptcopyout(sopt, &ap->blli.v,
1123 sizeof ap->blli.v));
1129 case T_ATM_DEST_ADDR:
1130 if (ap->called.tag == T_ATM_PRESENT) {
1131 return (sooptcopyout(sopt, &ap->called.addr,
1132 sizeof ap->called.addr));
1138 case T_ATM_DEST_SUB:
1139 if (ap->called.tag == T_ATM_PRESENT) {
1140 return (sooptcopyout(sopt, &ap->called.subaddr,
1141 sizeof ap->called.subaddr));
1147 case T_ATM_ORIG_ADDR:
1148 if (ap->calling.tag == T_ATM_PRESENT) {
1149 return (sooptcopyout(sopt, &ap->calling.addr,
1150 sizeof ap->calling.addr));
1156 case T_ATM_ORIG_SUB:
1157 if (ap->calling.tag == T_ATM_PRESENT) {
1158 return (sooptcopyout(sopt, &ap->calling.subaddr,
1159 sizeof ap->calling.subaddr));
1165 case T_ATM_CALLER_ID:
1166 if (ap->calling.tag == T_ATM_PRESENT) {
1167 return (sooptcopyout(sopt, &ap->calling.cid,
1168 sizeof ap->calling.cid));
1175 if (ap->cause.tag == T_ATM_PRESENT) {
1176 return (sooptcopyout(sopt, &ap->cause.v,
1177 sizeof ap->cause.v));
1184 if (ap->qos.tag == T_ATM_PRESENT) {
1185 return (sooptcopyout(sopt, &ap->qos.v,
1193 if (ap->transit.tag == T_ATM_PRESENT) {
1194 return (sooptcopyout(sopt, &ap->transit.v,
1195 sizeof ap->transit.v));
1201 case T_ATM_LEAF_IND:
1202 return (EPROTONOSUPPORT); /* XXX */
1204 case T_ATM_NET_INTF:
1206 struct t_atm_net_intf netif;
1209 ifp = &ap->nif->nif_if;
1210 (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
1211 "%s%d", ifp->if_name, ifp->if_unit);
1212 return (sooptcopyout(sopt, &netif,
1220 if (ap->llc.tag == T_ATM_PRESENT) {
1221 return (sooptcopyout(sopt, &ap->llc.v,
1229 return (ENOPROTOOPT);
1237 * Process Socket VCC Connected Notification
1240 * toku owner's connection token (atm_pcb protocol block)
1247 atm_sock_connected(toku)
1250 Atm_pcb *atp = (Atm_pcb *)toku;
1253 * Connection is setup
1255 atm_sock_stat.as_conncomp[atp->atp_type]++;
1256 soisconnected(atp->atp_socket);
1261 * Process Socket VCC Cleared Notification
1264 * toku owner's connection token (atm_pcb protocol block)
1265 * cause pointer to cause code
1272 atm_sock_cleared(toku, cause)
1274 struct t_atm_cause *cause;
1276 Atm_pcb *atp = (Atm_pcb *)toku;
1279 so = atp->atp_socket;
1282 * Save call clearing cause
1284 atp->atp_attr.cause.tag = T_ATM_PRESENT;
1285 atp->atp_attr.cause.v = *cause;
1288 * Set user error code
1290 if (so->so_state & SS_ISCONNECTED) {
1291 so->so_error = ECONNRESET;
1292 atm_sock_stat.as_connclr[atp->atp_type]++;
1294 so->so_error = ECONNREFUSED;
1295 atm_sock_stat.as_connfail[atp->atp_type]++;
1299 * Connection is gone
1301 atp->atp_conn = NULL;
1302 soisdisconnected(so);
1305 * Cleanup failed incoming connection setup
1307 if (so->so_state & SS_NOFDREF) {
1308 (void) atm_sock_detach(so);