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.7 2005/02/01 00:51:50 joerg 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 satm->satm_len = sizeof(*satm);
581 saddr = &satm->satm_addr.t_atm_sap_addr;
582 if (atp->atp_attr.nif && atp->atp_attr.nif->nif_pif->pif_siginst) {
583 saddr->SVE_tag_addr = T_ATM_PRESENT;
585 &atp->atp_attr.nif->nif_pif->pif_siginst->si_addr,
586 atp->atp_attr.nif->nif_sel, saddr);
587 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
588 saddr->SVE_tag_selector = T_ATM_PRESENT;
590 saddr->SVE_tag_selector = T_ATM_ABSENT;
592 saddr->SVE_tag_addr = T_ATM_ABSENT;
593 saddr->SVE_tag_selector = T_ATM_ABSENT;
594 saddr->address_format = T_ATM_ABSENT;
596 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
597 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
598 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
600 *addr = (struct sockaddr *)satm;
606 * Retrieve peer socket address
611 * so pointer to socket
612 * addr pointer to pointer to contain protocol address
615 * 0 request processed
616 * errno error processing request - reason indicated
620 atm_sock_peeraddr(so, addr)
622 struct sockaddr **addr;
624 struct sockaddr_atm *satm;
625 struct t_atm_sap_addr *saddr;
626 Atm_pcb *atp = sotoatmpcb(so);
630 * Return remote address, if known
632 satm = KM_ALLOC(sizeof *satm, M_SONAME, M_WAITOK);
636 KM_ZERO(satm, sizeof(*satm));
637 satm->satm_family = AF_ATM;
638 satm->satm_len = sizeof(*satm);
640 saddr = &satm->satm_addr.t_atm_sap_addr;
641 if (so->so_state & SS_ISCONNECTED) {
642 cvp = atp->atp_conn->co_connvc;
643 saddr->SVE_tag_addr = T_ATM_PRESENT;
644 if (cvp->cvc_flags & CVCF_CALLER) {
645 ATM_ADDR_COPY(&cvp->cvc_attr.called.addr, saddr);
647 if (cvp->cvc_attr.calling.tag == T_ATM_PRESENT) {
648 ATM_ADDR_COPY(&cvp->cvc_attr.calling.addr,
651 saddr->SVE_tag_addr = T_ATM_ABSENT;
652 saddr->address_format = T_ATM_ABSENT;
655 if (saddr->address_format == T_ATM_ENDSYS_ADDR)
656 saddr->SVE_tag_selector = T_ATM_PRESENT;
658 saddr->SVE_tag_selector = T_ATM_ABSENT;
660 saddr->SVE_tag_addr = T_ATM_ABSENT;
661 saddr->SVE_tag_selector = T_ATM_ABSENT;
662 saddr->address_format = T_ATM_ABSENT;
664 satm->satm_addr.t_atm_sap_layer2.SVE_tag = T_ATM_ABSENT;
665 satm->satm_addr.t_atm_sap_layer3.SVE_tag = T_ATM_ABSENT;
666 satm->satm_addr.t_atm_sap_appl.SVE_tag = T_ATM_ABSENT;
668 *addr = (struct sockaddr *)satm;
674 * Common setsockopt processing
679 * so pointer to socket
680 * sopt pointer to socket option info
681 * atp pointer to ATM PCB
684 * 0 request processed
685 * errno error processing request - reason indicated
689 atm_sock_setopt(so, sopt, atp)
691 struct sockopt *sopt;
696 struct t_atm_aal5 aal5;
697 struct t_atm_traffic trf;
698 struct t_atm_bearer brr;
699 struct t_atm_bhli bhl;
700 struct t_atm_blli bll;
702 struct t_atm_cause cau;
703 struct t_atm_qos qos;
704 struct t_atm_transit trn;
705 struct t_atm_net_intf nif;
706 struct t_atm_llc llc;
707 struct t_atm_app_name appn;
710 #define MAXVAL(bits) ((1 << bits) - 1)
711 #define MAXMASK(bits) (~MAXVAL(bits))
713 switch (sopt->sopt_name) {
716 err = sooptcopyin(sopt, &p.aal5, sizeof p.aal5, sizeof p.aal5);
719 if ((p.aal5.forward_max_SDU_size != T_ATM_ABSENT) &&
720 (p.aal5.forward_max_SDU_size & MAXMASK(16)))
722 if ((p.aal5.backward_max_SDU_size != T_ATM_ABSENT) &&
723 (p.aal5.backward_max_SDU_size & MAXMASK(16)))
725 if ((p.aal5.SSCS_type != T_ATM_ABSENT) &&
726 (p.aal5.SSCS_type != T_ATM_NULL) &&
727 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_REL) &&
728 (p.aal5.SSCS_type != T_ATM_SSCS_SSCOP_UNREL) &&
729 (p.aal5.SSCS_type != T_ATM_SSCS_FR))
732 if ((p.aal5.forward_max_SDU_size == T_ATM_ABSENT) &&
733 (p.aal5.backward_max_SDU_size == T_ATM_ABSENT) &&
734 (p.aal5.SSCS_type == T_ATM_ABSENT))
735 atp->atp_attr.aal.tag = T_ATM_ABSENT;
737 atp->atp_attr.aal.tag = T_ATM_PRESENT;
738 atp->atp_attr.aal.type = ATM_AAL5;
739 atp->atp_attr.aal.v.aal5 = p.aal5;
744 err = sooptcopyin(sopt, &p.trf, sizeof p.trf, sizeof p.trf);
747 if ((p.trf.forward.PCR_high_priority != T_ATM_ABSENT) &&
748 (p.trf.forward.PCR_high_priority & MAXMASK(24)))
750 if (p.trf.forward.PCR_all_traffic & MAXMASK(24))
752 if ((p.trf.forward.SCR_high_priority != T_ATM_ABSENT) &&
753 (p.trf.forward.SCR_high_priority & MAXMASK(24)))
755 if ((p.trf.forward.SCR_all_traffic != T_ATM_ABSENT) &&
756 (p.trf.forward.SCR_all_traffic & MAXMASK(24)))
758 if ((p.trf.forward.MBS_high_priority != T_ATM_ABSENT) &&
759 (p.trf.forward.MBS_high_priority & MAXMASK(24)))
761 if ((p.trf.forward.MBS_all_traffic != T_ATM_ABSENT) &&
762 (p.trf.forward.MBS_all_traffic & MAXMASK(24)))
764 if ((p.trf.forward.tagging != T_YES) &&
765 (p.trf.forward.tagging != T_NO))
768 if ((p.trf.backward.PCR_high_priority != T_ATM_ABSENT) &&
769 (p.trf.backward.PCR_high_priority & MAXMASK(24)))
771 if (p.trf.backward.PCR_all_traffic & MAXMASK(24))
773 if ((p.trf.backward.SCR_high_priority != T_ATM_ABSENT) &&
774 (p.trf.backward.SCR_high_priority & MAXMASK(24)))
776 if ((p.trf.backward.SCR_all_traffic != T_ATM_ABSENT) &&
777 (p.trf.backward.SCR_all_traffic & MAXMASK(24)))
779 if ((p.trf.backward.MBS_high_priority != T_ATM_ABSENT) &&
780 (p.trf.backward.MBS_high_priority & MAXMASK(24)))
782 if ((p.trf.backward.MBS_all_traffic != T_ATM_ABSENT) &&
783 (p.trf.backward.MBS_all_traffic & MAXMASK(24)))
785 if ((p.trf.backward.tagging != T_YES) &&
786 (p.trf.backward.tagging != T_NO))
788 if ((p.trf.best_effort != T_YES) &&
789 (p.trf.best_effort != T_NO))
792 atp->atp_attr.traffic.tag = T_ATM_PRESENT;
793 atp->atp_attr.traffic.v = p.trf;
796 case T_ATM_BEARER_CAP:
797 err = sooptcopyin(sopt, &p.brr, sizeof p.brr, sizeof p.brr);
800 if ((p.brr.bearer_class != T_ATM_CLASS_A) &&
801 (p.brr.bearer_class != T_ATM_CLASS_C) &&
802 (p.brr.bearer_class != T_ATM_CLASS_X))
804 if ((p.brr.traffic_type != T_ATM_NULL) &&
805 (p.brr.traffic_type != T_ATM_CBR) &&
806 (p.brr.traffic_type != T_ATM_VBR))
808 if ((p.brr.timing_requirements != T_ATM_NULL) &&
809 (p.brr.timing_requirements != T_ATM_END_TO_END) &&
810 (p.brr.timing_requirements != T_ATM_NO_END_TO_END))
812 if ((p.brr.clipping_susceptibility != T_NO) &&
813 (p.brr.clipping_susceptibility != T_YES))
815 if ((p.brr.connection_configuration != T_ATM_1_TO_1) &&
816 (p.brr.connection_configuration != T_ATM_1_TO_MANY))
819 atp->atp_attr.bearer.tag = T_ATM_PRESENT;
820 atp->atp_attr.bearer.v = p.brr;
824 err = sooptcopyin(sopt, &p.bhl, sizeof p.bhl, sizeof p.bhl);
827 if ((p.bhl.ID_type != T_ATM_ABSENT) &&
828 (p.bhl.ID_type != T_ATM_ISO_APP_ID) &&
829 (p.bhl.ID_type != T_ATM_USER_APP_ID) &&
830 (p.bhl.ID_type != T_ATM_VENDOR_APP_ID))
833 if (p.bhl.ID_type == T_ATM_ABSENT)
834 atp->atp_attr.bhli.tag = T_ATM_ABSENT;
836 atp->atp_attr.bhli.tag = T_ATM_PRESENT;
837 atp->atp_attr.bhli.v = p.bhl;
842 err = sooptcopyin(sopt, &p.bll, sizeof p.bll, sizeof p.bll);
845 if ((p.bll.layer_2_protocol.ID_type != T_ATM_ABSENT) &&
846 (p.bll.layer_2_protocol.ID_type != T_ATM_SIMPLE_ID) &&
847 (p.bll.layer_2_protocol.ID_type != T_ATM_USER_ID))
849 if ((p.bll.layer_2_protocol.mode != T_ATM_ABSENT) &&
850 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
851 (p.bll.layer_2_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
853 if ((p.bll.layer_2_protocol.window_size != T_ATM_ABSENT) &&
854 (p.bll.layer_2_protocol.window_size < 1))
857 if ((p.bll.layer_3_protocol.ID_type != T_ATM_ABSENT) &&
858 (p.bll.layer_3_protocol.ID_type != T_ATM_SIMPLE_ID) &&
859 (p.bll.layer_3_protocol.ID_type != T_ATM_IPI_ID) &&
860 (p.bll.layer_3_protocol.ID_type != T_ATM_SNAP_ID) &&
861 (p.bll.layer_3_protocol.ID_type != T_ATM_USER_ID))
863 if ((p.bll.layer_3_protocol.mode != T_ATM_ABSENT) &&
864 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_NORMAL_MODE) &&
865 (p.bll.layer_3_protocol.mode != T_ATM_BLLI_EXTENDED_MODE))
867 if ((p.bll.layer_3_protocol.packet_size != T_ATM_ABSENT) &&
868 (p.bll.layer_3_protocol.packet_size & MAXMASK(4)))
870 if ((p.bll.layer_3_protocol.window_size != T_ATM_ABSENT) &&
871 (p.bll.layer_3_protocol.window_size < 1))
874 if (p.bll.layer_2_protocol.ID_type == T_ATM_ABSENT)
875 atp->atp_attr.blli.tag_l2 = T_ATM_ABSENT;
877 atp->atp_attr.blli.tag_l2 = T_ATM_PRESENT;
879 if (p.bll.layer_3_protocol.ID_type == T_ATM_ABSENT)
880 atp->atp_attr.blli.tag_l3 = T_ATM_ABSENT;
882 atp->atp_attr.blli.tag_l3 = T_ATM_PRESENT;
884 if ((atp->atp_attr.blli.tag_l2 == T_ATM_PRESENT) ||
885 (atp->atp_attr.blli.tag_l3 == T_ATM_PRESENT))
886 atp->atp_attr.blli.v = p.bll;
889 case T_ATM_DEST_ADDR:
890 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
893 if ((p.addr.address_format != T_ATM_ENDSYS_ADDR) &&
894 (p.addr.address_format != T_ATM_E164_ADDR))
896 if (p.addr.address_length > ATM_ADDR_LEN)
899 atp->atp_attr.called.tag = T_ATM_PRESENT;
900 atp->atp_attr.called.addr = p.addr;
904 err = sooptcopyin(sopt, &p.addr, sizeof p.addr, sizeof p.addr);
907 if ((p.addr.address_format != T_ATM_ABSENT) &&
908 (p.addr.address_format != T_ATM_NSAP_ADDR))
910 if (p.addr.address_length > ATM_ADDR_LEN)
913 /* T_ATM_DEST_ADDR controls tag */
914 atp->atp_attr.called.subaddr = p.addr;
917 case T_ATM_ORIG_ADDR:
923 case T_ATM_CALLER_ID:
927 err = sooptcopyin(sopt, &p.cau, sizeof p.cau, sizeof p.cau);
930 if ((p.cau.coding_standard != T_ATM_ABSENT) &&
931 (p.cau.coding_standard != T_ATM_ITU_CODING) &&
932 (p.cau.coding_standard != T_ATM_NETWORK_CODING))
934 if ((p.cau.location != T_ATM_LOC_USER) &&
935 (p.cau.location != T_ATM_LOC_LOCAL_PRIVATE_NET) &&
936 (p.cau.location != T_ATM_LOC_LOCAL_PUBLIC_NET) &&
937 (p.cau.location != T_ATM_LOC_TRANSIT_NET) &&
938 (p.cau.location != T_ATM_LOC_REMOTE_PUBLIC_NET) &&
939 (p.cau.location != T_ATM_LOC_REMOTE_PRIVATE_NET) &&
940 (p.cau.location != T_ATM_LOC_INTERNATIONAL_NET) &&
941 (p.cau.location != T_ATM_LOC_BEYOND_INTERWORKING))
944 if (p.cau.coding_standard == T_ATM_ABSENT)
945 atp->atp_attr.cause.tag = T_ATM_ABSENT;
947 atp->atp_attr.cause.tag = T_ATM_PRESENT;
948 atp->atp_attr.cause.v = p.cau;
953 err = sooptcopyin(sopt, &p.qos, sizeof p.qos, sizeof p.qos);
956 if ((p.qos.coding_standard != T_ATM_ABSENT) &&
957 (p.qos.coding_standard != T_ATM_ITU_CODING) &&
958 (p.qos.coding_standard != T_ATM_NETWORK_CODING))
960 if ((p.qos.forward.qos_class != T_ATM_QOS_CLASS_0) &&
961 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_1) &&
962 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_2) &&
963 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_3) &&
964 (p.qos.forward.qos_class != T_ATM_QOS_CLASS_4))
966 if ((p.qos.backward.qos_class != T_ATM_QOS_CLASS_0) &&
967 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_1) &&
968 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_2) &&
969 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_3) &&
970 (p.qos.backward.qos_class != T_ATM_QOS_CLASS_4))
973 if (p.qos.coding_standard == T_ATM_ABSENT)
974 atp->atp_attr.qos.tag = T_ATM_ABSENT;
976 atp->atp_attr.qos.tag = T_ATM_PRESENT;
977 atp->atp_attr.qos.v = p.qos;
982 err = sooptcopyin(sopt, &p.trn, sizeof p.trn, sizeof p.trn);
985 if (p.trn.length > T_ATM_MAX_NET_ID)
988 if (p.trn.length == 0)
989 atp->atp_attr.transit.tag = T_ATM_ABSENT;
991 atp->atp_attr.transit.tag = T_ATM_PRESENT;
992 atp->atp_attr.transit.v = p.trn;
997 return (EPROTONOSUPPORT); /* XXX */
999 case T_ATM_DROP_LEAF:
1000 return (EPROTONOSUPPORT); /* XXX */
1002 case T_ATM_NET_INTF:
1003 err = sooptcopyin(sopt, &p.nif, sizeof p.nif, sizeof p.nif);
1007 atp->atp_attr.nif = atm_nifname(p.nif.net_intf);
1008 if (atp->atp_attr.nif == NULL)
1013 err = sooptcopyin(sopt, &p.llc, sizeof p.llc, sizeof p.llc);
1016 if ((p.llc.llc_len < T_ATM_LLC_MIN_LEN) ||
1017 (p.llc.llc_len > T_ATM_LLC_MAX_LEN))
1020 atp->atp_attr.llc.tag = T_ATM_PRESENT;
1021 atp->atp_attr.llc.v = p.llc;
1024 case T_ATM_APP_NAME:
1025 err = sooptcopyin(sopt, &p.appn, sizeof p.appn, sizeof p.appn);
1029 strncpy(atp->atp_name, p.appn.app_name, T_ATM_APP_NAME_LEN);
1033 return (ENOPROTOOPT);
1041 * Common getsockopt processing
1046 * so pointer to socket
1047 * sopt pointer to socket option info
1048 * atp pointer to ATM PCB
1051 * 0 request processed
1052 * errno error processing request - reason indicated
1056 atm_sock_getopt(so, sopt, atp)
1058 struct sockopt *sopt;
1064 * If socket is connected, return attributes for the VCC in use,
1065 * otherwise just return what the user has setup so far.
1067 if (so->so_state & SS_ISCONNECTED)
1068 ap = &atp->atp_conn->co_connvc->cvc_attr;
1070 ap = &atp->atp_attr;
1072 switch (sopt->sopt_name) {
1075 if ((ap->aal.tag == T_ATM_PRESENT) &&
1076 (ap->aal.type == ATM_AAL5)) {
1077 return (sooptcopyout(sopt, &ap->aal.v.aal5,
1078 sizeof ap->aal.v.aal5));
1085 if (ap->traffic.tag == T_ATM_PRESENT) {
1086 return (sooptcopyout(sopt, &ap->traffic.v,
1087 sizeof ap->traffic.v));
1093 case T_ATM_BEARER_CAP:
1094 if (ap->bearer.tag == T_ATM_PRESENT) {
1095 return (sooptcopyout(sopt, &ap->bearer.v,
1096 sizeof ap->bearer.v));
1103 if (ap->bhli.tag == T_ATM_PRESENT) {
1104 return (sooptcopyout(sopt, &ap->bhli.v,
1105 sizeof ap->bhli.v));
1112 if ((ap->blli.tag_l2 == T_ATM_PRESENT) ||
1113 (ap->blli.tag_l3 == T_ATM_PRESENT)) {
1114 return (sooptcopyout(sopt, &ap->blli.v,
1115 sizeof ap->blli.v));
1121 case T_ATM_DEST_ADDR:
1122 if (ap->called.tag == T_ATM_PRESENT) {
1123 return (sooptcopyout(sopt, &ap->called.addr,
1124 sizeof ap->called.addr));
1130 case T_ATM_DEST_SUB:
1131 if (ap->called.tag == T_ATM_PRESENT) {
1132 return (sooptcopyout(sopt, &ap->called.subaddr,
1133 sizeof ap->called.subaddr));
1139 case T_ATM_ORIG_ADDR:
1140 if (ap->calling.tag == T_ATM_PRESENT) {
1141 return (sooptcopyout(sopt, &ap->calling.addr,
1142 sizeof ap->calling.addr));
1148 case T_ATM_ORIG_SUB:
1149 if (ap->calling.tag == T_ATM_PRESENT) {
1150 return (sooptcopyout(sopt, &ap->calling.subaddr,
1151 sizeof ap->calling.subaddr));
1157 case T_ATM_CALLER_ID:
1158 if (ap->calling.tag == T_ATM_PRESENT) {
1159 return (sooptcopyout(sopt, &ap->calling.cid,
1160 sizeof ap->calling.cid));
1167 if (ap->cause.tag == T_ATM_PRESENT) {
1168 return (sooptcopyout(sopt, &ap->cause.v,
1169 sizeof ap->cause.v));
1176 if (ap->qos.tag == T_ATM_PRESENT) {
1177 return (sooptcopyout(sopt, &ap->qos.v,
1185 if (ap->transit.tag == T_ATM_PRESENT) {
1186 return (sooptcopyout(sopt, &ap->transit.v,
1187 sizeof ap->transit.v));
1193 case T_ATM_LEAF_IND:
1194 return (EPROTONOSUPPORT); /* XXX */
1196 case T_ATM_NET_INTF:
1198 struct t_atm_net_intf netif;
1201 ifp = &ap->nif->nif_if;
1202 (void) snprintf(netif.net_intf, sizeof(netif.net_intf),
1203 "%s", ifp->if_xname);
1204 return (sooptcopyout(sopt, &netif,
1212 if (ap->llc.tag == T_ATM_PRESENT) {
1213 return (sooptcopyout(sopt, &ap->llc.v,
1221 return (ENOPROTOOPT);
1229 * Process Socket VCC Connected Notification
1232 * toku owner's connection token (atm_pcb protocol block)
1239 atm_sock_connected(toku)
1242 Atm_pcb *atp = (Atm_pcb *)toku;
1245 * Connection is setup
1247 atm_sock_stat.as_conncomp[atp->atp_type]++;
1248 soisconnected(atp->atp_socket);
1253 * Process Socket VCC Cleared Notification
1256 * toku owner's connection token (atm_pcb protocol block)
1257 * cause pointer to cause code
1264 atm_sock_cleared(toku, cause)
1266 struct t_atm_cause *cause;
1268 Atm_pcb *atp = (Atm_pcb *)toku;
1271 so = atp->atp_socket;
1274 * Save call clearing cause
1276 atp->atp_attr.cause.tag = T_ATM_PRESENT;
1277 atp->atp_attr.cause.v = *cause;
1280 * Set user error code
1282 if (so->so_state & SS_ISCONNECTED) {
1283 so->so_error = ECONNRESET;
1284 atm_sock_stat.as_connclr[atp->atp_type]++;
1286 so->so_error = ECONNREFUSED;
1287 atm_sock_stat.as_connfail[atp->atp_type]++;
1291 * Connection is gone
1293 atp->atp_conn = NULL;
1294 soisdisconnected(so);
1297 * Cleanup failed incoming connection setup
1299 if (so->so_state & SS_NOFDREF) {
1300 (void) atm_sock_detach(so);