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 $
27 * @(#) $DragonFly: src/sys/netproto/atm/atm_socket.c,v 1.6 2004/03/05 19:17:25 hsu Exp $
34 * ATM common socket protocol processing
38 #include "kern_include.h"
48 static struct sp_info atm_pcb_pool = {
49 "atm pcb pool", /* si_name */
50 sizeof(Atm_pcb), /* si_blksiz */
55 static struct t_atm_cause atm_sock_cause = {
58 T_ATM_CAUSE_UNSPECIFIED_NORMAL,
64 * Allocate resources for a new ATM socket
69 * so pointer to socket
70 * send socket send buffer maximum
71 * recv socket receive buffer maximum
75 * errno attach failed - reason indicated
79 atm_sock_attach(so, send, recv, rl)
85 Atm_pcb *atp = sotoatmpcb(so);
89 * Make sure initialization has happened
95 * Make sure we're not already attached
101 * Reserve socket buffer space, if not already done
103 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
104 err = soreserve(so, send, recv, rl);
110 * Allocate and initialize our control block
112 atp = (Atm_pcb *)atm_allocate(&atm_pcb_pool);
116 atp->atp_socket = so;
117 so->so_pcb = (caddr_t)atp;
123 * Detach from socket and free resources
128 * so pointer to socket
131 * 0 detach successful
132 * errno detach failed - reason indicated
139 Atm_pcb *atp = sotoatmpcb(so);
142 * Make sure we're still attached
148 * Terminate any (possibly pending) connection
151 (void) atm_sock_disconnect(so);
155 * Break links and free control blocks
160 atm_free((caddr_t)atp);
167 * Bind local address to socket
172 * so pointer to socket
173 * addr pointer to protocol address
176 * 0 request processed
177 * errno error processing request - reason indicated
181 atm_sock_bind(so, addr)
183 struct sockaddr *addr;
185 Atm_pcb *atp = sotoatmpcb(so);
187 struct sockaddr_atm *satm;
188 struct t_atm_sap_addr *sapadr;
189 struct t_atm_sap_layer2 *sapl2;
190 struct t_atm_sap_layer3 *sapl3;
191 struct t_atm_sap_appl *sapapl;
194 * Make sure we're still attached
200 * Can't change local address once we've started connection process
202 if (atp->atp_conn != NULL)
203 return (EADDRNOTAVAIL);
206 * Validate requested local address
208 satm = (struct sockaddr_atm *)addr;
209 if (satm->satm_family != AF_ATM)
210 return (EAFNOSUPPORT);
212 sapadr = &satm->satm_addr.t_atm_sap_addr;
213 if (sapadr->SVE_tag_addr == T_ATM_PRESENT) {
214 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
215 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
217 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
218 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
222 } else if ((sapadr->SVE_tag_addr != T_ATM_ABSENT) &&
223 (sapadr->SVE_tag_addr != T_ATM_ANY))
225 if (sapadr->address_length > ATM_ADDR_LEN)
228 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
229 if (sapl2->SVE_tag == T_ATM_PRESENT) {
230 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
231 (sapl2->ID_type != T_ATM_USER_ID))
233 } else if ((sapl2->SVE_tag != T_ATM_ABSENT) &&
234 (sapl2->SVE_tag != T_ATM_ANY))
237 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
238 if (sapl3->SVE_tag == T_ATM_PRESENT) {
239 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
240 (sapl3->ID_type != T_ATM_IPI_ID) &&
241 (sapl3->ID_type != T_ATM_SNAP_ID) &&
242 (sapl3->ID_type != T_ATM_USER_ID))
244 } else if ((sapl3->SVE_tag != T_ATM_ABSENT) &&
245 (sapl3->SVE_tag != T_ATM_ANY))
248 sapapl = &satm->satm_addr.t_atm_sap_appl;
249 if (sapapl->SVE_tag == T_ATM_PRESENT) {
250 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
251 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
252 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
254 } else if ((sapapl->SVE_tag != T_ATM_ABSENT) &&
255 (sapapl->SVE_tag != T_ATM_ANY))
259 * Create temporary attributes list so that we can check out the
260 * new bind parameters before we modify the socket's values;
262 attr = atp->atp_attr;
263 attr.called.tag = sapadr->SVE_tag_addr;
264 KM_COPY(&sapadr->address_format, &attr.called.addr, sizeof(Atm_addr));
266 attr.blli.tag_l2 = sapl2->SVE_tag;
267 if (sapl2->SVE_tag == T_ATM_PRESENT) {
268 attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
269 KM_COPY(&sapl2->ID, &attr.blli.v.layer_2_protocol.ID,
270 sizeof(attr.blli.v.layer_2_protocol.ID));
273 attr.blli.tag_l3 = sapl3->SVE_tag;
274 if (sapl3->SVE_tag == T_ATM_PRESENT) {
275 attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
276 KM_COPY(&sapl3->ID, &attr.blli.v.layer_3_protocol.ID,
277 sizeof(attr.blli.v.layer_3_protocol.ID));
280 attr.bhli.tag = sapapl->SVE_tag;
281 if (sapapl->SVE_tag == T_ATM_PRESENT) {
282 attr.bhli.v.ID_type = sapapl->ID_type;
283 KM_COPY(&sapapl->ID, &attr.bhli.v.ID,
284 sizeof(attr.bhli.v.ID));
288 * Make sure we have unique listening attributes
290 if (atm_cm_match(&attr, NULL) != NULL)
294 * Looks good, save new attributes
296 atp->atp_attr = attr;
303 * Listen for incoming connections
308 * so pointer to socket
309 * epp pointer to endpoint definition structure
312 * 0 request processed
313 * errno error processing request - reason indicated
317 atm_sock_listen(so, epp)
321 Atm_pcb *atp = sotoatmpcb(so);
324 * Make sure we're still attached
330 * Start listening for incoming calls
332 return (atm_cm_listen(epp, atp, &atp->atp_attr, &atp->atp_conn));
337 * Connect socket to peer
342 * so pointer to socket
343 * addr pointer to protocol address
344 * epp pointer to endpoint definition structure
347 * 0 request processed
348 * errno error processing request - reason indicated
352 atm_sock_connect(so, addr, epp)
354 struct sockaddr *addr;
357 Atm_pcb *atp = sotoatmpcb(so);
358 struct sockaddr_atm *satm;
359 struct t_atm_sap_addr *sapadr;
360 struct t_atm_sap_layer2 *sapl2;
361 struct t_atm_sap_layer3 *sapl3;
362 struct t_atm_sap_appl *sapapl;
366 * Make sure we're still attached
372 * Validate requested peer address
374 satm = (struct sockaddr_atm *)addr;
375 if (satm->satm_family != AF_ATM)
376 return (EAFNOSUPPORT);
378 sapadr = &satm->satm_addr.t_atm_sap_addr;
379 if (sapadr->SVE_tag_addr != T_ATM_PRESENT)
381 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
382 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
384 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
385 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
387 } else if (sapadr->address_format == T_ATM_PVC_ADDR) {
388 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
392 if (sapadr->address_length > ATM_ADDR_LEN)
395 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
396 if (sapl2->SVE_tag == T_ATM_PRESENT) {
397 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
398 (sapl2->ID_type != T_ATM_USER_ID))
400 } else if (sapl2->SVE_tag != T_ATM_ABSENT)
403 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
404 if (sapl3->SVE_tag == T_ATM_PRESENT) {
405 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
406 (sapl3->ID_type != T_ATM_IPI_ID) &&
407 (sapl3->ID_type != T_ATM_SNAP_ID) &&
408 (sapl3->ID_type != T_ATM_USER_ID))
410 } else if (sapl3->SVE_tag != T_ATM_ABSENT)
413 sapapl = &satm->satm_addr.t_atm_sap_appl;
414 if (sapapl->SVE_tag == T_ATM_PRESENT) {
415 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
416 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
417 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
419 } else if (sapapl->SVE_tag != T_ATM_ABSENT)
423 * Select an outgoing network interface
425 if (atp->atp_attr.nif == NULL) {
428 for (pip = atm_interface_head; pip != NULL;
429 pip = pip->pif_next) {
430 if (pip->pif_nif != NULL) {
431 atp->atp_attr.nif = pip->pif_nif;
435 if (atp->atp_attr.nif == NULL)
440 * Set supplied connection attributes
442 atp->atp_attr.called.tag = T_ATM_PRESENT;
443 KM_COPY(&sapadr->address_format, &atp->atp_attr.called.addr,
446 atp->atp_attr.blli.tag_l2 = sapl2->SVE_tag;
447 if (sapl2->SVE_tag == T_ATM_PRESENT) {
448 atp->atp_attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
449 KM_COPY(&sapl2->ID, &atp->atp_attr.blli.v.layer_2_protocol.ID,
450 sizeof(atp->atp_attr.blli.v.layer_2_protocol.ID));
453 atp->atp_attr.blli.tag_l3 = sapl3->SVE_tag;
454 if (sapl3->SVE_tag == T_ATM_PRESENT) {
455 atp->atp_attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
456 KM_COPY(&sapl3->ID, &atp->atp_attr.blli.v.layer_3_protocol.ID,
457 sizeof(atp->atp_attr.blli.v.layer_3_protocol.ID));
460 atp->atp_attr.bhli.tag = sapapl->SVE_tag;
461 if (sapapl->SVE_tag == T_ATM_PRESENT) {
462 atp->atp_attr.bhli.v.ID_type = sapapl->ID_type;
463 KM_COPY(&sapapl->ID, &atp->atp_attr.bhli.v.ID,
464 sizeof(atp->atp_attr.bhli.v.ID));
468 * We're finally ready to initiate the ATM connection
471 atm_sock_stat.as_connreq[atp->atp_type]++;
472 err = atm_cm_connect(epp, atp, &atp->atp_attr, &atp->atp_conn);
475 * Connection is setup
477 atm_sock_stat.as_conncomp[atp->atp_type]++;
480 } else if (err == EINPROGRESS) {
482 * We've got to wait for a connected event
490 atm_sock_stat.as_connfail[atp->atp_type]++;
491 soisdisconnected(so);
499 * Disconnect connected socket
504 * so pointer to socket
507 * 0 request processed
508 * errno error processing request - reason indicated
512 atm_sock_disconnect(so)
515 Atm_pcb *atp = sotoatmpcb(so);
516 struct t_atm_cause *cause;
520 * Make sure we're still attached
526 * Release the ATM connection
529 if (atp->atp_attr.cause.tag == T_ATM_PRESENT)
530 cause = &atp->atp_attr.cause.v;
532 cause = &atm_sock_cause;
533 err = atm_cm_release(atp->atp_conn, cause);
535 log(LOG_ERR, "atm_sock_disconnect: release fail (%d)\n",
537 atm_sock_stat.as_connrel[atp->atp_type]++;
538 atp->atp_conn = NULL;
541 soisdisconnected(so);
548 * Retrieve local socket address
553 * so pointer to socket
554 * addr pointer to pointer to contain protocol address
557 * 0 request processed
558 * errno error processing request - reason indicated
562 atm_sock_sockaddr(so, addr)
564 struct sockaddr **addr;
566 struct sockaddr_atm *satm;
567 struct t_atm_sap_addr *saddr;
568 Atm_pcb *atp = sotoatmpcb(so);
571 * Return local interface address, if known
573 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
577 KM_ZERO(satm, sizeof(*satm));
578 satm->satm_family = AF_ATM;
579 #if (defined(BSD) && (BSD >= 199103))
580 satm->satm_len = sizeof(*satm);
583 saddr = &satm->satm_addr.t_atm_sap_addr;
584 if (atp->atp_attr.nif && atp->atp_attr.nif->nif_pif->pif_siginst) {
585 saddr->SVE_tag_addr = T_ATM_PRESENT;
587 &atp->atp_attr.nif->nif_pif->pif_siginst->si_addr,
588 atp->atp_attr.nif->nif_sel, saddr);
589 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
590 saddr->SVE_tag_selector = T_ATM_PRESENT;
592 saddr->SVE_tag_selector = T_ATM_ABSENT;
594 saddr->SVE_tag_addr = T_ATM_ABSENT;
595 saddr->SVE_tag_selector = T_ATM_ABSENT;
596 saddr->address_format = T_ATM_ABSENT;
598 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
599 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
600 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
602 *addr = (struct sockaddr *)satm;
608 * Retrieve peer socket address
613 * so pointer to socket
614 * addr pointer to pointer to contain protocol address
617 * 0 request processed
618 * errno error processing request - reason indicated
622 atm_sock_peeraddr(so, addr)
624 struct sockaddr **addr;
626 struct sockaddr_atm *satm;
627 struct t_atm_sap_addr *saddr;
628 Atm_pcb *atp = sotoatmpcb(so);
632 * Return remote address, if known
634 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
638 KM_ZERO(satm, sizeof(*satm));
639 satm->satm_family = AF_ATM;
640 #if (defined(BSD) && (BSD >= 199103))
641 satm->satm_len = sizeof(*satm);
644 saddr = &satm->satm_addr.t_atm_sap_addr;
645 if (so->so_state & SS_ISCONNECTED) {
646 cvp = atp->atp_conn->co_connvc;
647 saddr->SVE_tag_addr = T_ATM_PRESENT;
648 if (cvp->cvc_flags & CVCF_CALLER) {
649 ATM_ADDR_COPY(&cvp->cvc_attr.called.addr, saddr);
651 if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
652 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
655 saddr->SVE_tag_addr = T_ATM_ABSENT;
656 saddr->address_format = T_ATM_ABSENT;
659 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
660 saddr->SVE_tag_selector = T_ATM_PRESENT;
662 saddr->SVE_tag_selector = T_ATM_ABSENT;
664 saddr->SVE_tag_addr = T_ATM_ABSENT;
665 saddr->SVE_tag_selector = T_ATM_ABSENT;
666 saddr->address_format = T_ATM_ABSENT;
668 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
669 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
670 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
672 *addr = (struct sockaddr *)satm;
678 * Common setsockopt processing
683 * so pointer to socket
684 * sopt pointer to socket option info
685 * atp pointer to ATM PCB
688 * 0 request processed
689 * errno error processing request - reason indicated
693 atm_sock_setopt(so, sopt, atp)
695 struct sockopt *sopt;
700 struct t_atm_aal5 aal5;
701 struct t_atm_traffic trf;
702 struct t_atm_bearer brr;
703 struct t_atm_bhli bhl;
704 struct t_atm_blli bll;
706 struct t_atm_cause cau;
707 struct t_atm_qos qos;
708 struct t_atm_transit trn;
709 struct t_atm_net_intf nif;
710 struct t_atm_llc llc;
711 struct t_atm_app_name appn;
714 #define MAXVAL(bits) ((1 << bits) - 1)
715 #define MAXMASK(bits) (~MAXVAL(bits))
717 switch (sopt->sopt_name) {
720 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
723 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
724 (p.aal5.forward_max_SDU_size & MAXMASK(16)))
726 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
727 (p.aal5.backward_max_SDU_size & MAXMASK(16)))
729 if ((p.aal5.SSCS_type != T_ATM_ABSENT) &&
730 (p.aal5.SSCS_type != T_ATM_NULL) &&
731 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_REL) &&
732 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_UNREL) &&
733 (p.aal5.SSCS_type != T_ATM_SSCS_FR))
736 if ((p.aal5.forward_max_SDU_size == T_ATM_ABSENT) &&
737 (p.aal5.backward_max_SDU_size == T_ATM_ABSENT) &&
738 (p.aal5.SSCS_type == T_ATM_ABSENT))
739 atp->atp_attr.aal.tag = T_ATM_ABSENT;
741 atp->atp_attr.aal.tag = T_ATM_PRESENT;
742 atp->atp_attr.aal.type = ATM_AAL5;
743 atp->atp_attr.aal.v.aal5 = p.aal5;
748 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
751 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
752 (p.trf.forward.PCR_high_priority & MAXMASK(24)))
754 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
756 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
757 (p.trf.forward.SCR_high_priority & MAXMASK(24)))
759 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
760 (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
762 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
763 (p.trf.forward.MBS_high_priority & MAXMASK(24)))
765 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
766 (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
768 if ((p.trf.forward.tagging != T_YES) &&
769 (p.trf.forward.tagging != T_NO))
772 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
773 (p.trf.backward.PCR_high_priority & MAXMASK(24)))
775 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
777 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
778 (p.trf.backward.SCR_high_priority & MAXMASK(24)))
780 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
781 (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
783 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
784 (p.trf.backward.MBS_high_priority & MAXMASK(24)))
786 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
787 (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
789 if ((p.trf.backward.tagging != T_YES) &&
790 (p.trf.backward.tagging != T_NO))
792 if ((p.trf.best_effort != T_YES) &&
793 (p.trf.best_effort != T_NO))
796 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
797 atp->atp_attr.traffic.v = p.trf;
800 case T_ATM_BEARER_CAP:
801 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
804 if ((p.brr.bearer_class != T_ATM_CLASS_A) &&
805 (p.brr.bearer_class != T_ATM_CLASS_C) &&
806 (p.brr.bearer_class != T_ATM_CLASS_X))
808 if ((p.brr.traffic_type != T_ATM_NULL) &&
809 (p.brr.traffic_type != T_ATM_CBR) &&
810 (p.brr.traffic_type != T_ATM_VBR))
812 if ((p.brr.timing_requirements != T_ATM_NULL) &&
813 (p.brr.timing_requirements != T_ATM_END_TO_END) &&
814 (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
816 if ((p.brr.clipping_susceptibility != T_NO) &&
817 (p.brr.clipping_susceptibility != T_YES))
819 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
820 (p.brr.connection_configuration != T_ATM_1_TO_MANY))
823 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
824 atp->atp_attr.bearer.v = p.brr;
828 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
831 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
832 (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
833 (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
834 (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
837 if (p.bhl.ID_type == T_ATM_ABSENT)
838 atp->atp_attr.bhli.tag = T_ATM_ABSENT;
840 atp->atp_attr.bhli.tag = T_ATM_PRESENT;
841 atp->atp_attr.bhli.v = p.bhl;
846 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
849 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
850 (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
851 (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
853 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
854 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
855 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
857 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
858 (p.bll.layer_2_protocol.window_size < 1))
861 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
862 (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
863 (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
864 (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
865 (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
867 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
868 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
869 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
871 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
872 (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
874 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
875 (p.bll.layer_3_protocol.window_size < 1))
878 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT)
879 atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
881 atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
883 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT)
884 atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
886 atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
888 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
889 (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
890 atp->atp_attr.blli.v = p.bll;
893 case T_ATM_DEST_ADDR:
894 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
897 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
898 (p.addr.address_format != T_ATM_E164_ADDR))
900 if (p.addr.address_length > ATM_ADDR_LEN)
903 atp->atp_attr.called.tag = T_ATM_PRESENT;
904 atp->atp_attr.called.addr = p.addr;
908 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
911 if ((p.addr.address_format != T_ATM_ABSENT) &&
912 (p.addr.address_format != T_ATM_NSAP_ADDR))
914 if (p.addr.address_length > ATM_ADDR_LEN)
917 /* T_ATM_DEST_ADDR controls tag */
918 atp->atp_attr.called.subaddr = p.addr;
921 case T_ATM_ORIG_ADDR:
927 case T_ATM_CALLER_ID:
931 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
934 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
935 (p.cau.coding_standard != T_ATM_ITU_CODING) &&
936 (p.cau.coding_standard != T_ATM_NETWORK_CODING))
938 if ((p.cau.location != T_ATM_LOC_USER) &&
939 (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
940 (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
941 (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
942 (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
943 (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
944 (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
945 (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
948 if (p.cau.coding_standard == T_ATM_ABSENT)
949 atp->atp_attr.cause.tag = T_ATM_ABSENT;
951 atp->atp_attr.cause.tag = T_ATM_PRESENT;
952 atp->atp_attr.cause.v = p.cau;
957 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
960 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
961 (p.qos.coding_standard != T_ATM_ITU_CODING) &&
962 (p.qos.coding_standard != T_ATM_NETWORK_CODING))
964 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
965 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
966 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
967 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
968 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
970 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
971 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
972 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
973 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
974 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
977 if (p.qos.coding_standard == T_ATM_ABSENT)
978 atp->atp_attr.qos.tag = T_ATM_ABSENT;
980 atp->atp_attr.qos.tag = T_ATM_PRESENT;
981 atp->atp_attr.qos.v = p.qos;
986 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
989 if (p.trn.length > T_ATM_MAX_NET_ID)
992 if (p.trn.length == 0)
993 atp->atp_attr.transit.tag = T_ATM_ABSENT;
995 atp->atp_attr.transit.tag = T_ATM_PRESENT;
996 atp->atp_attr.transit.v = p.trn;
1000 case T_ATM_ADD_LEAF:
1001 return (EPROTONOSUPPORT); /* XXX */
1003 case T_ATM_DROP_LEAF:
1004 return (EPROTONOSUPPORT); /* XXX */
1006 case T_ATM_NET_INTF:
1007 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
1011 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
1012 if (atp->atp_attr.nif == NULL)
1017 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
1020 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
1021 (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
1024 atp->atp_attr.llc.tag = T_ATM_PRESENT;
1025 atp->atp_attr.llc.v = p.llc;
1028 case T_ATM_APP_NAME:
1029 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
1033 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
1037 return (ENOPROTOOPT);
1045 * Common getsockopt processing
1050 * so pointer to socket
1051 * sopt pointer to socket option info
1052 * atp pointer to ATM PCB
1055 * 0 request processed
1056 * errno error processing request - reason indicated
1060 atm_sock_getopt(so, sopt, atp)
1062 struct sockopt *sopt;
1068 * If socket is connected, return attributes for the VCC in use,
1069 * otherwise just return what the user has setup so far.
1071 if (so->so_state & SS_ISCONNECTED)
1072 ap = &atp->atp_conn->co_connvc->cvc_attr;
1074 ap = &atp->atp_attr;
1076 switch (sopt->sopt_name) {
1079 if ((ap->aal.tag == T_ATM_PRESENT) &&
1080 (ap->aal.type == ATM_AAL5)) {
1081 return (sooptcopyout(sopt, &ap->aal.v.aal5,
1082 sizeof ap->aal.v.aal5));
1089 if (ap->traffic.tag == T_ATM_PRESENT) {
1090 return (sooptcopyout(sopt, &ap->traffic.v,
1091 sizeof ap->traffic.v));
1097 case T_ATM_BEARER_CAP:
1098 if (ap->bearer.tag == T_ATM_PRESENT) {
1099 return (sooptcopyout(sopt, &ap->bearer.v,
1100 sizeof ap->bearer.v));
1107 if (ap->bhli.tag == T_ATM_PRESENT) {
1108 return (sooptcopyout(sopt, &ap->bhli.v,
1109 sizeof ap->bhli.v));
1116 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
1117 (ap->blli.tag_l3 == T_ATM_PRESENT)) {
1118 return (sooptcopyout(sopt, &ap->blli.v,
1119 sizeof ap->blli.v));
1125 case T_ATM_DEST_ADDR:
1126 if (ap->called.tag == T_ATM_PRESENT) {
1127 return (sooptcopyout(sopt, &ap->called.addr,
1128 sizeof ap->called.addr));
1134 case T_ATM_DEST_SUB:
1135 if (ap->called.tag == T_ATM_PRESENT) {
1136 return (sooptcopyout(sopt, &ap->called.subaddr,
1137 sizeof ap->called.subaddr));
1143 case T_ATM_ORIG_ADDR:
1144 if (ap->calling.tag == T_ATM_PRESENT) {
1145 return (sooptcopyout(sopt, &ap->calling.addr,
1146 sizeof ap->calling.addr));
1152 case T_ATM_ORIG_SUB:
1153 if (ap->calling.tag == T_ATM_PRESENT) {
1154 return (sooptcopyout(sopt, &ap->calling.subaddr,
1155 sizeof ap->calling.subaddr));
1161 case T_ATM_CALLER_ID:
1162 if (ap->calling.tag == T_ATM_PRESENT) {
1163 return (sooptcopyout(sopt, &ap->calling.cid,
1164 sizeof ap->calling.cid));
1171 if (ap->cause.tag == T_ATM_PRESENT) {
1172 return (sooptcopyout(sopt, &ap->cause.v,
1173 sizeof ap->cause.v));
1180 if (ap->qos.tag == T_ATM_PRESENT) {
1181 return (sooptcopyout(sopt, &ap->qos.v,
1189 if (ap->transit.tag == T_ATM_PRESENT) {
1190 return (sooptcopyout(sopt, &ap->transit.v,
1191 sizeof ap->transit.v));
1197 case T_ATM_LEAF_IND:
1198 return (EPROTONOSUPPORT); /* XXX */
1200 case T_ATM_NET_INTF:
1202 struct t_atm_net_intf netif;
1205 ifp = &ap->nif->nif_if;
1206 (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
1207 "%s", ifp->if_xname);
1208 return (sooptcopyout(sopt, &netif,
1216 if (ap->llc.tag == T_ATM_PRESENT) {
1217 return (sooptcopyout(sopt, &ap->llc.v,
1225 return (ENOPROTOOPT);
1233 * Process Socket VCC Connected Notification
1236 * toku owner's connection token (atm_pcb protocol block)
1243 atm_sock_connected(toku)
1246 Atm_pcb *atp = (Atm_pcb *)toku;
1249 * Connection is setup
1251 atm_sock_stat.as_conncomp[atp->atp_type]++;
1252 soisconnected(atp->atp_socket);
1257 * Process Socket VCC Cleared Notification
1260 * toku owner's connection token (atm_pcb protocol block)
1261 * cause pointer to cause code
1268 atm_sock_cleared(toku, cause)
1270 struct t_atm_cause *cause;
1272 Atm_pcb *atp = (Atm_pcb *)toku;
1275 so = atp->atp_socket;
1278 * Save call clearing cause
1280 atp->atp_attr.cause.tag = T_ATM_PRESENT;
1281 atp->atp_attr.cause.v = *cause;
1284 * Set user error code
1286 if (so->so_state & SS_ISCONNECTED) {
1287 so->so_error = ECONNRESET;
1288 atm_sock_stat.as_connclr[atp->atp_type]++;
1290 so->so_error = ECONNREFUSED;
1291 atm_sock_stat.as_connfail[atp->atp_type]++;
1295 * Connection is gone
1297 atp->atp_conn = NULL;
1298 soisdisconnected(so);
1301 * Cleanup failed incoming connection setup
1303 if (so->so_state & SS_NOFDREF) {
1304 (void) atm_sock_detach(so);