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.4 2004/01/06 03:17:28 dillon 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)
84 Atm_pcb *atp = sotoatmpcb(so);
88 * Make sure initialization has happened
94 * Make sure we're not already attached
100 * Reserve socket buffer space, if not already done
102 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
103 err = soreserve(so, send, recv);
109 * Allocate and initialize our control block
111 atp = (Atm_pcb *)atm_allocate(&atm_pcb_pool);
115 atp->atp_socket = so;
116 so->so_pcb = (caddr_t)atp;
122 * Detach from socket and free resources
127 * so pointer to socket
130 * 0 detach successful
131 * errno detach failed - reason indicated
138 Atm_pcb *atp = sotoatmpcb(so);
141 * Make sure we're still attached
147 * Terminate any (possibly pending) connection
150 (void) atm_sock_disconnect(so);
154 * Break links and free control blocks
159 atm_free((caddr_t)atp);
166 * Bind local address to socket
171 * so pointer to socket
172 * addr pointer to protocol address
175 * 0 request processed
176 * errno error processing request - reason indicated
180 atm_sock_bind(so, addr)
182 struct sockaddr *addr;
184 Atm_pcb *atp = sotoatmpcb(so);
186 struct sockaddr_atm *satm;
187 struct t_atm_sap_addr *sapadr;
188 struct t_atm_sap_layer2 *sapl2;
189 struct t_atm_sap_layer3 *sapl3;
190 struct t_atm_sap_appl *sapapl;
193 * Make sure we're still attached
199 * Can't change local address once we've started connection process
201 if (atp->atp_conn != NULL)
202 return (EADDRNOTAVAIL);
205 * Validate requested local address
207 satm = (struct sockaddr_atm *)addr;
208 if (satm->satm_family != AF_ATM)
209 return (EAFNOSUPPORT);
211 sapadr = &satm->satm_addr.t_atm_sap_addr;
212 if (sapadr->SVE_tag_addr == T_ATM_PRESENT) {
213 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
214 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
216 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
217 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
221 } else if ((sapadr->SVE_tag_addr != T_ATM_ABSENT) &&
222 (sapadr->SVE_tag_addr != T_ATM_ANY))
224 if (sapadr->address_length > ATM_ADDR_LEN)
227 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
228 if (sapl2->SVE_tag == T_ATM_PRESENT) {
229 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
230 (sapl2->ID_type != T_ATM_USER_ID))
232 } else if ((sapl2->SVE_tag != T_ATM_ABSENT) &&
233 (sapl2->SVE_tag != T_ATM_ANY))
236 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
237 if (sapl3->SVE_tag == T_ATM_PRESENT) {
238 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
239 (sapl3->ID_type != T_ATM_IPI_ID) &&
240 (sapl3->ID_type != T_ATM_SNAP_ID) &&
241 (sapl3->ID_type != T_ATM_USER_ID))
243 } else if ((sapl3->SVE_tag != T_ATM_ABSENT) &&
244 (sapl3->SVE_tag != T_ATM_ANY))
247 sapapl = &satm->satm_addr.t_atm_sap_appl;
248 if (sapapl->SVE_tag == T_ATM_PRESENT) {
249 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
250 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
251 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
253 } else if ((sapapl->SVE_tag != T_ATM_ABSENT) &&
254 (sapapl->SVE_tag != T_ATM_ANY))
258 * Create temporary attributes list so that we can check out the
259 * new bind parameters before we modify the socket's values;
261 attr = atp->atp_attr;
262 attr.called.tag = sapadr->SVE_tag_addr;
263 KM_COPY(&sapadr->address_format, &attr.called.addr, sizeof(Atm_addr));
265 attr.blli.tag_l2 = sapl2->SVE_tag;
266 if (sapl2->SVE_tag == T_ATM_PRESENT) {
267 attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
268 KM_COPY(&sapl2->ID, &attr.blli.v.layer_2_protocol.ID,
269 sizeof(attr.blli.v.layer_2_protocol.ID));
272 attr.blli.tag_l3 = sapl3->SVE_tag;
273 if (sapl3->SVE_tag == T_ATM_PRESENT) {
274 attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
275 KM_COPY(&sapl3->ID, &attr.blli.v.layer_3_protocol.ID,
276 sizeof(attr.blli.v.layer_3_protocol.ID));
279 attr.bhli.tag = sapapl->SVE_tag;
280 if (sapapl->SVE_tag == T_ATM_PRESENT) {
281 attr.bhli.v.ID_type = sapapl->ID_type;
282 KM_COPY(&sapapl->ID, &attr.bhli.v.ID,
283 sizeof(attr.bhli.v.ID));
287 * Make sure we have unique listening attributes
289 if (atm_cm_match(&attr, NULL) != NULL)
293 * Looks good, save new attributes
295 atp->atp_attr = attr;
302 * Listen for incoming connections
307 * so pointer to socket
308 * epp pointer to endpoint definition structure
311 * 0 request processed
312 * errno error processing request - reason indicated
316 atm_sock_listen(so, epp)
320 Atm_pcb *atp = sotoatmpcb(so);
323 * Make sure we're still attached
329 * Start listening for incoming calls
331 return (atm_cm_listen(epp, atp, &atp->atp_attr, &atp->atp_conn));
336 * Connect socket to peer
341 * so pointer to socket
342 * addr pointer to protocol address
343 * epp pointer to endpoint definition structure
346 * 0 request processed
347 * errno error processing request - reason indicated
351 atm_sock_connect(so, addr, epp)
353 struct sockaddr *addr;
356 Atm_pcb *atp = sotoatmpcb(so);
357 struct sockaddr_atm *satm;
358 struct t_atm_sap_addr *sapadr;
359 struct t_atm_sap_layer2 *sapl2;
360 struct t_atm_sap_layer3 *sapl3;
361 struct t_atm_sap_appl *sapapl;
365 * Make sure we're still attached
371 * Validate requested peer address
373 satm = (struct sockaddr_atm *)addr;
374 if (satm->satm_family != AF_ATM)
375 return (EAFNOSUPPORT);
377 sapadr = &satm->satm_addr.t_atm_sap_addr;
378 if (sapadr->SVE_tag_addr != T_ATM_PRESENT)
380 if (sapadr->address_format == T_ATM_ENDSYS_ADDR) {
381 if (sapadr->SVE_tag_selector != T_ATM_PRESENT)
383 } else if (sapadr->address_format == T_ATM_E164_ADDR) {
384 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
386 } else if (sapadr->address_format == T_ATM_PVC_ADDR) {
387 if (sapadr->SVE_tag_selector != T_ATM_ABSENT)
391 if (sapadr->address_length > ATM_ADDR_LEN)
394 sapl2 = &satm->satm_addr.t_atm_sap_layer2;
395 if (sapl2->SVE_tag == T_ATM_PRESENT) {
396 if ((sapl2->ID_type != T_ATM_SIMPLE_ID) &&
397 (sapl2->ID_type != T_ATM_USER_ID))
399 } else if (sapl2->SVE_tag != T_ATM_ABSENT)
402 sapl3 = &satm->satm_addr.t_atm_sap_layer3;
403 if (sapl3->SVE_tag == T_ATM_PRESENT) {
404 if ((sapl3->ID_type != T_ATM_SIMPLE_ID) &&
405 (sapl3->ID_type != T_ATM_IPI_ID) &&
406 (sapl3->ID_type != T_ATM_SNAP_ID) &&
407 (sapl3->ID_type != T_ATM_USER_ID))
409 } else if (sapl3->SVE_tag != T_ATM_ABSENT)
412 sapapl = &satm->satm_addr.t_atm_sap_appl;
413 if (sapapl->SVE_tag == T_ATM_PRESENT) {
414 if ((sapapl->ID_type != T_ATM_ISO_APP_ID) &&
415 (sapapl->ID_type != T_ATM_USER_APP_ID) &&
416 (sapapl->ID_type != T_ATM_VENDOR_APP_ID))
418 } else if (sapapl->SVE_tag != T_ATM_ABSENT)
422 * Select an outgoing network interface
424 if (atp->atp_attr.nif == NULL) {
427 for (pip = atm_interface_head; pip != NULL;
428 pip = pip->pif_next) {
429 if (pip->pif_nif != NULL) {
430 atp->atp_attr.nif = pip->pif_nif;
434 if (atp->atp_attr.nif == NULL)
439 * Set supplied connection attributes
441 atp->atp_attr.called.tag = T_ATM_PRESENT;
442 KM_COPY(&sapadr->address_format, &atp->atp_attr.called.addr,
445 atp->atp_attr.blli.tag_l2 = sapl2->SVE_tag;
446 if (sapl2->SVE_tag == T_ATM_PRESENT) {
447 atp->atp_attr.blli.v.layer_2_protocol.ID_type = sapl2->ID_type;
448 KM_COPY(&sapl2->ID, &atp->atp_attr.blli.v.layer_2_protocol.ID,
449 sizeof(atp->atp_attr.blli.v.layer_2_protocol.ID));
452 atp->atp_attr.blli.tag_l3 = sapl3->SVE_tag;
453 if (sapl3->SVE_tag == T_ATM_PRESENT) {
454 atp->atp_attr.blli.v.layer_3_protocol.ID_type = sapl3->ID_type;
455 KM_COPY(&sapl3->ID, &atp->atp_attr.blli.v.layer_3_protocol.ID,
456 sizeof(atp->atp_attr.blli.v.layer_3_protocol.ID));
459 atp->atp_attr.bhli.tag = sapapl->SVE_tag;
460 if (sapapl->SVE_tag == T_ATM_PRESENT) {
461 atp->atp_attr.bhli.v.ID_type = sapapl->ID_type;
462 KM_COPY(&sapapl->ID, &atp->atp_attr.bhli.v.ID,
463 sizeof(atp->atp_attr.bhli.v.ID));
467 * We're finally ready to initiate the ATM connection
470 atm_sock_stat.as_connreq[atp->atp_type]++;
471 err = atm_cm_connect(epp, atp, &atp->atp_attr, &atp->atp_conn);
474 * Connection is setup
476 atm_sock_stat.as_conncomp[atp->atp_type]++;
479 } else if (err == EINPROGRESS) {
481 * We've got to wait for a connected event
489 atm_sock_stat.as_connfail[atp->atp_type]++;
490 soisdisconnected(so);
498 * Disconnect connected socket
503 * so pointer to socket
506 * 0 request processed
507 * errno error processing request - reason indicated
511 atm_sock_disconnect(so)
514 Atm_pcb *atp = sotoatmpcb(so);
515 struct t_atm_cause *cause;
519 * Make sure we're still attached
525 * Release the ATM connection
528 if (atp->atp_attr.cause.tag == T_ATM_PRESENT)
529 cause = &atp->atp_attr.cause.v;
531 cause = &atm_sock_cause;
532 err = atm_cm_release(atp->atp_conn, cause);
534 log(LOG_ERR, "atm_sock_disconnect: release fail (%d)\n",
536 atm_sock_stat.as_connrel[atp->atp_type]++;
537 atp->atp_conn = NULL;
540 soisdisconnected(so);
547 * Retrieve local socket address
552 * so pointer to socket
553 * addr pointer to pointer to contain protocol address
556 * 0 request processed
557 * errno error processing request - reason indicated
561 atm_sock_sockaddr(so, addr)
563 struct sockaddr **addr;
565 struct sockaddr_atm *satm;
566 struct t_atm_sap_addr *saddr;
567 Atm_pcb *atp = sotoatmpcb(so);
570 * Return local interface address, if known
572 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
576 KM_ZERO(satm, sizeof(*satm));
577 satm->satm_family = AF_ATM;
578 #if (defined(BSD) && (BSD >= 199103))
579 satm->satm_len = sizeof(*satm);
582 saddr = &satm->satm_addr.t_atm_sap_addr;
583 if (atp->atp_attr.nif && atp->atp_attr.nif->nif_pif->pif_siginst) {
584 saddr->SVE_tag_addr = T_ATM_PRESENT;
586 &atp->atp_attr.nif->nif_pif->pif_siginst->si_addr,
587 atp->atp_attr.nif->nif_sel, saddr);
588 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
589 saddr->SVE_tag_selector = T_ATM_PRESENT;
591 saddr->SVE_tag_selector = T_ATM_ABSENT;
593 saddr->SVE_tag_addr = T_ATM_ABSENT;
594 saddr->SVE_tag_selector = T_ATM_ABSENT;
595 saddr->address_format = T_ATM_ABSENT;
597 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
598 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
599 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
601 *addr = (struct sockaddr *)satm;
607 * Retrieve peer socket address
612 * so pointer to socket
613 * addr pointer to pointer to contain protocol address
616 * 0 request processed
617 * errno error processing request - reason indicated
621 atm_sock_peeraddr(so, addr)
623 struct sockaddr **addr;
625 struct sockaddr_atm *satm;
626 struct t_atm_sap_addr *saddr;
627 Atm_pcb *atp = sotoatmpcb(so);
631 * Return remote address, if known
633 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
637 KM_ZERO(satm, sizeof(*satm));
638 satm->satm_family = AF_ATM;
639 #if (defined(BSD) && (BSD >= 199103))
640 satm->satm_len = sizeof(*satm);
643 saddr = &satm->satm_addr.t_atm_sap_addr;
644 if (so->so_state & SS_ISCONNECTED) {
645 cvp = atp->atp_conn->co_connvc;
646 saddr->SVE_tag_addr = T_ATM_PRESENT;
647 if (cvp->cvc_flags & CVCF_CALLER) {
648 ATM_ADDR_COPY(&cvp->cvc_attr.called.addr, saddr);
650 if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
651 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
654 saddr->SVE_tag_addr = T_ATM_ABSENT;
655 saddr->address_format = T_ATM_ABSENT;
658 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
659 saddr->SVE_tag_selector = T_ATM_PRESENT;
661 saddr->SVE_tag_selector = T_ATM_ABSENT;
663 saddr->SVE_tag_addr = T_ATM_ABSENT;
664 saddr->SVE_tag_selector = T_ATM_ABSENT;
665 saddr->address_format = T_ATM_ABSENT;
667 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
668 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
669 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
671 *addr = (struct sockaddr *)satm;
677 * Common setsockopt processing
682 * so pointer to socket
683 * sopt pointer to socket option info
684 * atp pointer to ATM PCB
687 * 0 request processed
688 * errno error processing request - reason indicated
692 atm_sock_setopt(so, sopt, atp)
694 struct sockopt *sopt;
699 struct t_atm_aal5 aal5;
700 struct t_atm_traffic trf;
701 struct t_atm_bearer brr;
702 struct t_atm_bhli bhl;
703 struct t_atm_blli bll;
705 struct t_atm_cause cau;
706 struct t_atm_qos qos;
707 struct t_atm_transit trn;
708 struct t_atm_net_intf nif;
709 struct t_atm_llc llc;
710 struct t_atm_app_name appn;
713 #define MAXVAL(bits) ((1 << bits) - 1)
714 #define MAXMASK(bits) (~MAXVAL(bits))
716 switch (sopt->sopt_name) {
719 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
722 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
723 (p.aal5.forward_max_SDU_size & MAXMASK(16)))
725 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
726 (p.aal5.backward_max_SDU_size & MAXMASK(16)))
728 if ((p.aal5.SSCS_type != T_ATM_ABSENT) &&
729 (p.aal5.SSCS_type != T_ATM_NULL) &&
730 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_REL) &&
731 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_UNREL) &&
732 (p.aal5.SSCS_type != T_ATM_SSCS_FR))
735 if ((p.aal5.forward_max_SDU_size == T_ATM_ABSENT) &&
736 (p.aal5.backward_max_SDU_size == T_ATM_ABSENT) &&
737 (p.aal5.SSCS_type == T_ATM_ABSENT))
738 atp->atp_attr.aal.tag = T_ATM_ABSENT;
740 atp->atp_attr.aal.tag = T_ATM_PRESENT;
741 atp->atp_attr.aal.type = ATM_AAL5;
742 atp->atp_attr.aal.v.aal5 = p.aal5;
747 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
750 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
751 (p.trf.forward.PCR_high_priority & MAXMASK(24)))
753 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
755 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
756 (p.trf.forward.SCR_high_priority & MAXMASK(24)))
758 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
759 (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
761 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
762 (p.trf.forward.MBS_high_priority & MAXMASK(24)))
764 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
765 (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
767 if ((p.trf.forward.tagging != T_YES) &&
768 (p.trf.forward.tagging != T_NO))
771 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
772 (p.trf.backward.PCR_high_priority & MAXMASK(24)))
774 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
776 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
777 (p.trf.backward.SCR_high_priority & MAXMASK(24)))
779 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
780 (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
782 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
783 (p.trf.backward.MBS_high_priority & MAXMASK(24)))
785 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
786 (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
788 if ((p.trf.backward.tagging != T_YES) &&
789 (p.trf.backward.tagging != T_NO))
791 if ((p.trf.best_effort != T_YES) &&
792 (p.trf.best_effort != T_NO))
795 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
796 atp->atp_attr.traffic.v = p.trf;
799 case T_ATM_BEARER_CAP:
800 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
803 if ((p.brr.bearer_class != T_ATM_CLASS_A) &&
804 (p.brr.bearer_class != T_ATM_CLASS_C) &&
805 (p.brr.bearer_class != T_ATM_CLASS_X))
807 if ((p.brr.traffic_type != T_ATM_NULL) &&
808 (p.brr.traffic_type != T_ATM_CBR) &&
809 (p.brr.traffic_type != T_ATM_VBR))
811 if ((p.brr.timing_requirements != T_ATM_NULL) &&
812 (p.brr.timing_requirements != T_ATM_END_TO_END) &&
813 (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
815 if ((p.brr.clipping_susceptibility != T_NO) &&
816 (p.brr.clipping_susceptibility != T_YES))
818 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
819 (p.brr.connection_configuration != T_ATM_1_TO_MANY))
822 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
823 atp->atp_attr.bearer.v = p.brr;
827 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
830 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
831 (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
832 (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
833 (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
836 if (p.bhl.ID_type == T_ATM_ABSENT)
837 atp->atp_attr.bhli.tag = T_ATM_ABSENT;
839 atp->atp_attr.bhli.tag = T_ATM_PRESENT;
840 atp->atp_attr.bhli.v = p.bhl;
845 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
848 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
849 (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
850 (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
852 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
853 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
854 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
856 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
857 (p.bll.layer_2_protocol.window_size < 1))
860 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
861 (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
862 (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
863 (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
864 (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
866 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
867 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
868 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
870 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
871 (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
873 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
874 (p.bll.layer_3_protocol.window_size < 1))
877 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT)
878 atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
880 atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
882 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT)
883 atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
885 atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
887 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
888 (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
889 atp->atp_attr.blli.v = p.bll;
892 case T_ATM_DEST_ADDR:
893 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
896 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
897 (p.addr.address_format != T_ATM_E164_ADDR))
899 if (p.addr.address_length > ATM_ADDR_LEN)
902 atp->atp_attr.called.tag = T_ATM_PRESENT;
903 atp->atp_attr.called.addr = p.addr;
907 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
910 if ((p.addr.address_format != T_ATM_ABSENT) &&
911 (p.addr.address_format != T_ATM_NSAP_ADDR))
913 if (p.addr.address_length > ATM_ADDR_LEN)
916 /* T_ATM_DEST_ADDR controls tag */
917 atp->atp_attr.called.subaddr = p.addr;
920 case T_ATM_ORIG_ADDR:
926 case T_ATM_CALLER_ID:
930 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
933 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
934 (p.cau.coding_standard != T_ATM_ITU_CODING) &&
935 (p.cau.coding_standard != T_ATM_NETWORK_CODING))
937 if ((p.cau.location != T_ATM_LOC_USER) &&
938 (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
939 (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
940 (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
941 (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
942 (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
943 (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
944 (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
947 if (p.cau.coding_standard == T_ATM_ABSENT)
948 atp->atp_attr.cause.tag = T_ATM_ABSENT;
950 atp->atp_attr.cause.tag = T_ATM_PRESENT;
951 atp->atp_attr.cause.v = p.cau;
956 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
959 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
960 (p.qos.coding_standard != T_ATM_ITU_CODING) &&
961 (p.qos.coding_standard != T_ATM_NETWORK_CODING))
963 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
964 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
965 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
966 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
967 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
969 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
970 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
971 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
972 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
973 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
976 if (p.qos.coding_standard == T_ATM_ABSENT)
977 atp->atp_attr.qos.tag = T_ATM_ABSENT;
979 atp->atp_attr.qos.tag = T_ATM_PRESENT;
980 atp->atp_attr.qos.v = p.qos;
985 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
988 if (p.trn.length > T_ATM_MAX_NET_ID)
991 if (p.trn.length == 0)
992 atp->atp_attr.transit.tag = T_ATM_ABSENT;
994 atp->atp_attr.transit.tag = T_ATM_PRESENT;
995 atp->atp_attr.transit.v = p.trn;
1000 return (EPROTONOSUPPORT); /* XXX */
1002 case T_ATM_DROP_LEAF:
1003 return (EPROTONOSUPPORT); /* XXX */
1005 case T_ATM_NET_INTF:
1006 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
1010 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
1011 if (atp->atp_attr.nif == NULL)
1016 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
1019 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
1020 (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
1023 atp->atp_attr.llc.tag = T_ATM_PRESENT;
1024 atp->atp_attr.llc.v = p.llc;
1027 case T_ATM_APP_NAME:
1028 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
1032 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
1036 return (ENOPROTOOPT);
1044 * Common getsockopt processing
1049 * so pointer to socket
1050 * sopt pointer to socket option info
1051 * atp pointer to ATM PCB
1054 * 0 request processed
1055 * errno error processing request - reason indicated
1059 atm_sock_getopt(so, sopt, atp)
1061 struct sockopt *sopt;
1067 * If socket is connected, return attributes for the VCC in use,
1068 * otherwise just return what the user has setup so far.
1070 if (so->so_state & SS_ISCONNECTED)
1071 ap = &atp->atp_conn->co_connvc->cvc_attr;
1073 ap = &atp->atp_attr;
1075 switch (sopt->sopt_name) {
1078 if ((ap->aal.tag == T_ATM_PRESENT) &&
1079 (ap->aal.type == ATM_AAL5)) {
1080 return (sooptcopyout(sopt, &ap->aal.v.aal5,
1081 sizeof ap->aal.v.aal5));
1088 if (ap->traffic.tag == T_ATM_PRESENT) {
1089 return (sooptcopyout(sopt, &ap->traffic.v,
1090 sizeof ap->traffic.v));
1096 case T_ATM_BEARER_CAP:
1097 if (ap->bearer.tag == T_ATM_PRESENT) {
1098 return (sooptcopyout(sopt, &ap->bearer.v,
1099 sizeof ap->bearer.v));
1106 if (ap->bhli.tag == T_ATM_PRESENT) {
1107 return (sooptcopyout(sopt, &ap->bhli.v,
1108 sizeof ap->bhli.v));
1115 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
1116 (ap->blli.tag_l3 == T_ATM_PRESENT)) {
1117 return (sooptcopyout(sopt, &ap->blli.v,
1118 sizeof ap->blli.v));
1124 case T_ATM_DEST_ADDR:
1125 if (ap->called.tag == T_ATM_PRESENT) {
1126 return (sooptcopyout(sopt, &ap->called.addr,
1127 sizeof ap->called.addr));
1133 case T_ATM_DEST_SUB:
1134 if (ap->called.tag == T_ATM_PRESENT) {
1135 return (sooptcopyout(sopt, &ap->called.subaddr,
1136 sizeof ap->called.subaddr));
1142 case T_ATM_ORIG_ADDR:
1143 if (ap->calling.tag == T_ATM_PRESENT) {
1144 return (sooptcopyout(sopt, &ap->calling.addr,
1145 sizeof ap->calling.addr));
1151 case T_ATM_ORIG_SUB:
1152 if (ap->calling.tag == T_ATM_PRESENT) {
1153 return (sooptcopyout(sopt, &ap->calling.subaddr,
1154 sizeof ap->calling.subaddr));
1160 case T_ATM_CALLER_ID:
1161 if (ap->calling.tag == T_ATM_PRESENT) {
1162 return (sooptcopyout(sopt, &ap->calling.cid,
1163 sizeof ap->calling.cid));
1170 if (ap->cause.tag == T_ATM_PRESENT) {
1171 return (sooptcopyout(sopt, &ap->cause.v,
1172 sizeof ap->cause.v));
1179 if (ap->qos.tag == T_ATM_PRESENT) {
1180 return (sooptcopyout(sopt, &ap->qos.v,
1188 if (ap->transit.tag == T_ATM_PRESENT) {
1189 return (sooptcopyout(sopt, &ap->transit.v,
1190 sizeof ap->transit.v));
1196 case T_ATM_LEAF_IND:
1197 return (EPROTONOSUPPORT); /* XXX */
1199 case T_ATM_NET_INTF:
1201 struct t_atm_net_intf netif;
1204 ifp = &ap->nif->nif_if;
1205 (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
1206 "%s", if_name(ifp));
1207 return (sooptcopyout(sopt, &netif,
1215 if (ap->llc.tag == T_ATM_PRESENT) {
1216 return (sooptcopyout(sopt, &ap->llc.v,
1224 return (ENOPROTOOPT);
1232 * Process Socket VCC Connected Notification
1235 * toku owner's connection token (atm_pcb protocol block)
1242 atm_sock_connected(toku)
1245 Atm_pcb *atp = (Atm_pcb *)toku;
1248 * Connection is setup
1250 atm_sock_stat.as_conncomp[atp->atp_type]++;
1251 soisconnected(atp->atp_socket);
1256 * Process Socket VCC Cleared Notification
1259 * toku owner's connection token (atm_pcb protocol block)
1260 * cause pointer to cause code
1267 atm_sock_cleared(toku, cause)
1269 struct t_atm_cause *cause;
1271 Atm_pcb *atp = (Atm_pcb *)toku;
1274 so = atp->atp_socket;
1277 * Save call clearing cause
1279 atp->atp_attr.cause.tag = T_ATM_PRESENT;
1280 atp->atp_attr.cause.v = *cause;
1283 * Set user error code
1285 if (so->so_state & SS_ISCONNECTED) {
1286 so->so_error = ECONNRESET;
1287 atm_sock_stat.as_connclr[atp->atp_type]++;
1289 so->so_error = ECONNREFUSED;
1290 atm_sock_stat.as_connfail[atp->atp_type]++;
1294 * Connection is gone
1296 atp->atp_conn = NULL;
1297 soisdisconnected(so);
1300 * Cleanup failed incoming connection setup
1302 if (so->so_state & SS_NOFDREF) {
1303 (void) atm_sock_detach(so);