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.12 2008/06/21 12:30:19 aggelos 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(struct socket
*so
, u_long send
, u_long recv
, struct rlimit
*rl
)
81 Atm_pcb
*atp
= sotoatmpcb(so
);
85 * Make sure initialization has happened
91 * Make sure we're not already attached
97 * Reserve socket buffer space, if not already done
99 if ((so
->so_snd
.ssb_hiwat
== 0) || (so
->so_rcv
.ssb_hiwat
== 0)) {
100 err
= soreserve(so
, send
, recv
, rl
);
106 * Allocate and initialize our control block
108 atp
= (Atm_pcb
*)atm_allocate(&atm_pcb_pool
);
112 atp
->atp_socket
= so
;
113 so
->so_pcb
= (caddr_t
)atp
;
119 * Detach from socket and free resources
124 * so pointer to socket
127 * 0 detach successful
128 * errno detach failed - reason indicated
132 atm_sock_detach(struct socket
*so
)
134 Atm_pcb
*atp
= sotoatmpcb(so
);
137 * Make sure we're still attached
143 * Terminate any (possibly pending) connection
146 atm_sock_disconnect(so
);
150 * Break links and free control blocks
155 atm_free((caddr_t
)atp
);
162 * Bind local address to socket
167 * so pointer to socket
168 * addr pointer to protocol address
171 * 0 request processed
172 * errno error processing request - reason indicated
176 atm_sock_bind(struct socket
*so
, struct sockaddr
*addr
)
178 Atm_pcb
*atp
= sotoatmpcb(so
);
180 struct sockaddr_atm
*satm
;
181 struct t_atm_sap_addr
*sapadr
;
182 struct t_atm_sap_layer2
*sapl2
;
183 struct t_atm_sap_layer3
*sapl3
;
184 struct t_atm_sap_appl
*sapapl
;
187 * Make sure we're still attached
193 * Can't change local address once we've started connection process
195 if (atp
->atp_conn
!= NULL
)
196 return (EADDRNOTAVAIL
);
199 * Validate requested local address
201 satm
= (struct sockaddr_atm
*)addr
;
202 if (satm
->satm_family
!= AF_ATM
)
203 return (EAFNOSUPPORT
);
205 sapadr
= &satm
->satm_addr
.t_atm_sap_addr
;
206 if (sapadr
->SVE_tag_addr
== T_ATM_PRESENT
) {
207 if (sapadr
->address_format
== T_ATM_ENDSYS_ADDR
) {
208 if (sapadr
->SVE_tag_selector
!= T_ATM_PRESENT
)
210 } else if (sapadr
->address_format
== T_ATM_E164_ADDR
) {
211 if (sapadr
->SVE_tag_selector
!= T_ATM_ABSENT
)
215 } else if ((sapadr
->SVE_tag_addr
!= T_ATM_ABSENT
) &&
216 (sapadr
->SVE_tag_addr
!= T_ATM_ANY
))
218 if (sapadr
->address_length
> ATM_ADDR_LEN
)
221 sapl2
= &satm
->satm_addr
.t_atm_sap_layer2
;
222 if (sapl2
->SVE_tag
== T_ATM_PRESENT
) {
223 if ((sapl2
->ID_type
!= T_ATM_SIMPLE_ID
) &&
224 (sapl2
->ID_type
!= T_ATM_USER_ID
))
226 } else if ((sapl2
->SVE_tag
!= T_ATM_ABSENT
) &&
227 (sapl2
->SVE_tag
!= T_ATM_ANY
))
230 sapl3
= &satm
->satm_addr
.t_atm_sap_layer3
;
231 if (sapl3
->SVE_tag
== T_ATM_PRESENT
) {
232 if ((sapl3
->ID_type
!= T_ATM_SIMPLE_ID
) &&
233 (sapl3
->ID_type
!= T_ATM_IPI_ID
) &&
234 (sapl3
->ID_type
!= T_ATM_SNAP_ID
) &&
235 (sapl3
->ID_type
!= T_ATM_USER_ID
))
237 } else if ((sapl3
->SVE_tag
!= T_ATM_ABSENT
) &&
238 (sapl3
->SVE_tag
!= T_ATM_ANY
))
241 sapapl
= &satm
->satm_addr
.t_atm_sap_appl
;
242 if (sapapl
->SVE_tag
== T_ATM_PRESENT
) {
243 if ((sapapl
->ID_type
!= T_ATM_ISO_APP_ID
) &&
244 (sapapl
->ID_type
!= T_ATM_USER_APP_ID
) &&
245 (sapapl
->ID_type
!= T_ATM_VENDOR_APP_ID
))
247 } else if ((sapapl
->SVE_tag
!= T_ATM_ABSENT
) &&
248 (sapapl
->SVE_tag
!= T_ATM_ANY
))
252 * Create temporary attributes list so that we can check out the
253 * new bind parameters before we modify the socket's values;
255 attr
= atp
->atp_attr
;
256 attr
.called
.tag
= sapadr
->SVE_tag_addr
;
257 KM_COPY(&sapadr
->address_format
, &attr
.called
.addr
, sizeof(Atm_addr
));
259 attr
.blli
.tag_l2
= sapl2
->SVE_tag
;
260 if (sapl2
->SVE_tag
== T_ATM_PRESENT
) {
261 attr
.blli
.v
.layer_2_protocol
.ID_type
= sapl2
->ID_type
;
262 KM_COPY(&sapl2
->ID
, &attr
.blli
.v
.layer_2_protocol
.ID
,
263 sizeof(attr
.blli
.v
.layer_2_protocol
.ID
));
266 attr
.blli
.tag_l3
= sapl3
->SVE_tag
;
267 if (sapl3
->SVE_tag
== T_ATM_PRESENT
) {
268 attr
.blli
.v
.layer_3_protocol
.ID_type
= sapl3
->ID_type
;
269 KM_COPY(&sapl3
->ID
, &attr
.blli
.v
.layer_3_protocol
.ID
,
270 sizeof(attr
.blli
.v
.layer_3_protocol
.ID
));
273 attr
.bhli
.tag
= sapapl
->SVE_tag
;
274 if (sapapl
->SVE_tag
== T_ATM_PRESENT
) {
275 attr
.bhli
.v
.ID_type
= sapapl
->ID_type
;
276 KM_COPY(&sapapl
->ID
, &attr
.bhli
.v
.ID
,
277 sizeof(attr
.bhli
.v
.ID
));
281 * Make sure we have unique listening attributes
283 if (atm_cm_match(&attr
, NULL
) != NULL
)
287 * Looks good, save new attributes
289 atp
->atp_attr
= attr
;
296 * Listen for incoming connections
301 * so pointer to socket
302 * epp pointer to endpoint definition structure
305 * 0 request processed
306 * errno error processing request - reason indicated
310 atm_sock_listen(struct socket
*so
, Atm_endpoint
*epp
)
312 Atm_pcb
*atp
= sotoatmpcb(so
);
315 * Make sure we're still attached
321 * Start listening for incoming calls
323 return (atm_cm_listen(epp
, atp
, &atp
->atp_attr
, &atp
->atp_conn
));
328 * Connect socket to peer
333 * so pointer to socket
334 * addr pointer to protocol address
335 * epp pointer to endpoint definition structure
338 * 0 request processed
339 * errno error processing request - reason indicated
343 atm_sock_connect(struct socket
*so
, struct sockaddr
*addr
, Atm_endpoint
*epp
)
345 Atm_pcb
*atp
= sotoatmpcb(so
);
346 struct sockaddr_atm
*satm
;
347 struct t_atm_sap_addr
*sapadr
;
348 struct t_atm_sap_layer2
*sapl2
;
349 struct t_atm_sap_layer3
*sapl3
;
350 struct t_atm_sap_appl
*sapapl
;
354 * Make sure we're still attached
360 * Validate requested peer address
362 satm
= (struct sockaddr_atm
*)addr
;
363 if (satm
->satm_family
!= AF_ATM
)
364 return (EAFNOSUPPORT
);
366 sapadr
= &satm
->satm_addr
.t_atm_sap_addr
;
367 if (sapadr
->SVE_tag_addr
!= T_ATM_PRESENT
)
369 if (sapadr
->address_format
== T_ATM_ENDSYS_ADDR
) {
370 if (sapadr
->SVE_tag_selector
!= T_ATM_PRESENT
)
372 } else if (sapadr
->address_format
== T_ATM_E164_ADDR
) {
373 if (sapadr
->SVE_tag_selector
!= T_ATM_ABSENT
)
375 } else if (sapadr
->address_format
== T_ATM_PVC_ADDR
) {
376 if (sapadr
->SVE_tag_selector
!= T_ATM_ABSENT
)
380 if (sapadr
->address_length
> ATM_ADDR_LEN
)
383 sapl2
= &satm
->satm_addr
.t_atm_sap_layer2
;
384 if (sapl2
->SVE_tag
== T_ATM_PRESENT
) {
385 if ((sapl2
->ID_type
!= T_ATM_SIMPLE_ID
) &&
386 (sapl2
->ID_type
!= T_ATM_USER_ID
))
388 } else if (sapl2
->SVE_tag
!= T_ATM_ABSENT
)
391 sapl3
= &satm
->satm_addr
.t_atm_sap_layer3
;
392 if (sapl3
->SVE_tag
== T_ATM_PRESENT
) {
393 if ((sapl3
->ID_type
!= T_ATM_SIMPLE_ID
) &&
394 (sapl3
->ID_type
!= T_ATM_IPI_ID
) &&
395 (sapl3
->ID_type
!= T_ATM_SNAP_ID
) &&
396 (sapl3
->ID_type
!= T_ATM_USER_ID
))
398 } else if (sapl3
->SVE_tag
!= T_ATM_ABSENT
)
401 sapapl
= &satm
->satm_addr
.t_atm_sap_appl
;
402 if (sapapl
->SVE_tag
== T_ATM_PRESENT
) {
403 if ((sapapl
->ID_type
!= T_ATM_ISO_APP_ID
) &&
404 (sapapl
->ID_type
!= T_ATM_USER_APP_ID
) &&
405 (sapapl
->ID_type
!= T_ATM_VENDOR_APP_ID
))
407 } else if (sapapl
->SVE_tag
!= T_ATM_ABSENT
)
411 * Select an outgoing network interface
413 if (atp
->atp_attr
.nif
== NULL
) {
416 for (pip
= atm_interface_head
; pip
!= NULL
;
417 pip
= pip
->pif_next
) {
418 if (pip
->pif_nif
!= NULL
) {
419 atp
->atp_attr
.nif
= pip
->pif_nif
;
423 if (atp
->atp_attr
.nif
== NULL
)
428 * Set supplied connection attributes
430 atp
->atp_attr
.called
.tag
= T_ATM_PRESENT
;
431 KM_COPY(&sapadr
->address_format
, &atp
->atp_attr
.called
.addr
,
434 atp
->atp_attr
.blli
.tag_l2
= sapl2
->SVE_tag
;
435 if (sapl2
->SVE_tag
== T_ATM_PRESENT
) {
436 atp
->atp_attr
.blli
.v
.layer_2_protocol
.ID_type
= sapl2
->ID_type
;
437 KM_COPY(&sapl2
->ID
, &atp
->atp_attr
.blli
.v
.layer_2_protocol
.ID
,
438 sizeof(atp
->atp_attr
.blli
.v
.layer_2_protocol
.ID
));
441 atp
->atp_attr
.blli
.tag_l3
= sapl3
->SVE_tag
;
442 if (sapl3
->SVE_tag
== T_ATM_PRESENT
) {
443 atp
->atp_attr
.blli
.v
.layer_3_protocol
.ID_type
= sapl3
->ID_type
;
444 KM_COPY(&sapl3
->ID
, &atp
->atp_attr
.blli
.v
.layer_3_protocol
.ID
,
445 sizeof(atp
->atp_attr
.blli
.v
.layer_3_protocol
.ID
));
448 atp
->atp_attr
.bhli
.tag
= sapapl
->SVE_tag
;
449 if (sapapl
->SVE_tag
== T_ATM_PRESENT
) {
450 atp
->atp_attr
.bhli
.v
.ID_type
= sapapl
->ID_type
;
451 KM_COPY(&sapapl
->ID
, &atp
->atp_attr
.bhli
.v
.ID
,
452 sizeof(atp
->atp_attr
.bhli
.v
.ID
));
456 * We're finally ready to initiate the ATM connection
459 atm_sock_stat
.as_connreq
[atp
->atp_type
]++;
460 err
= atm_cm_connect(epp
, atp
, &atp
->atp_attr
, &atp
->atp_conn
);
463 * Connection is setup
465 atm_sock_stat
.as_conncomp
[atp
->atp_type
]++;
468 } else if (err
== EINPROGRESS
) {
470 * We've got to wait for a connected event
478 atm_sock_stat
.as_connfail
[atp
->atp_type
]++;
479 soisdisconnected(so
);
487 * Disconnect connected socket
492 * so pointer to socket
495 * 0 request processed
496 * errno error processing request - reason indicated
500 atm_sock_disconnect(struct socket
*so
)
502 Atm_pcb
*atp
= sotoatmpcb(so
);
503 struct t_atm_cause
*cause
;
507 * Make sure we're still attached
513 * Release the ATM connection
516 if (atp
->atp_attr
.cause
.tag
== T_ATM_PRESENT
)
517 cause
= &atp
->atp_attr
.cause
.v
;
519 cause
= &atm_sock_cause
;
520 err
= atm_cm_release(atp
->atp_conn
, cause
);
522 log(LOG_ERR
, "atm_sock_disconnect: release fail (%d)\n",
524 atm_sock_stat
.as_connrel
[atp
->atp_type
]++;
525 atp
->atp_conn
= NULL
;
528 soisdisconnected(so
);
535 * Retrieve local socket address
540 * so pointer to socket
541 * addr pointer to pointer to contain protocol address
544 * 0 request processed
545 * errno error processing request - reason indicated
549 atm_sock_sockaddr(struct socket
*so
, struct sockaddr
**addr
)
551 struct sockaddr_atm
*satm
;
552 struct t_atm_sap_addr
*saddr
;
553 Atm_pcb
*atp
= sotoatmpcb(so
);
556 * Return local interface address, if known
558 satm
= KM_ALLOC(sizeof *satm
, M_SONAME
, M_WAITOK
);
560 KM_ZERO(satm
, sizeof(*satm
));
561 satm
->satm_family
= AF_ATM
;
562 satm
->satm_len
= sizeof(*satm
);
564 saddr
= &satm
->satm_addr
.t_atm_sap_addr
;
565 if (atp
->atp_attr
.nif
&& atp
->atp_attr
.nif
->nif_pif
->pif_siginst
) {
566 saddr
->SVE_tag_addr
= T_ATM_PRESENT
;
568 &atp
->atp_attr
.nif
->nif_pif
->pif_siginst
->si_addr
,
569 atp
->atp_attr
.nif
->nif_sel
, saddr
);
570 if (saddr
->address_format
== T_ATM_ENDSYS_ADDR
)
571 saddr
->SVE_tag_selector
= T_ATM_PRESENT
;
573 saddr
->SVE_tag_selector
= T_ATM_ABSENT
;
575 saddr
->SVE_tag_addr
= T_ATM_ABSENT
;
576 saddr
->SVE_tag_selector
= T_ATM_ABSENT
;
577 saddr
->address_format
= T_ATM_ABSENT
;
579 satm
->satm_addr
.t_atm_sap_layer2
.SVE_tag
= T_ATM_ABSENT
;
580 satm
->satm_addr
.t_atm_sap_layer3
.SVE_tag
= T_ATM_ABSENT
;
581 satm
->satm_addr
.t_atm_sap_appl
.SVE_tag
= T_ATM_ABSENT
;
583 *addr
= (struct sockaddr
*)satm
;
589 * Retrieve peer socket address
594 * so pointer to socket
595 * addr pointer to pointer to contain protocol address
598 * 0 request processed
599 * errno error processing request - reason indicated
603 atm_sock_peeraddr(struct socket
*so
, struct sockaddr
**addr
)
605 struct sockaddr_atm
*satm
;
606 struct t_atm_sap_addr
*saddr
;
607 Atm_pcb
*atp
= sotoatmpcb(so
);
611 * Return remote address, if known
613 satm
= KM_ALLOC(sizeof *satm
, M_SONAME
, M_WAITOK
);
615 KM_ZERO(satm
, sizeof(*satm
));
616 satm
->satm_family
= AF_ATM
;
617 satm
->satm_len
= sizeof(*satm
);
619 saddr
= &satm
->satm_addr
.t_atm_sap_addr
;
620 if (so
->so_state
& SS_ISCONNECTED
) {
621 cvp
= atp
->atp_conn
->co_connvc
;
622 saddr
->SVE_tag_addr
= T_ATM_PRESENT
;
623 if (cvp
->cvc_flags
& CVCF_CALLER
) {
624 ATM_ADDR_COPY(&cvp
->cvc_attr
.called
.addr
, saddr
);
626 if (cvp
->cvc_attr
.calling
.tag
== T_ATM_PRESENT
) {
627 ATM_ADDR_COPY(&cvp
->cvc_attr
.calling
.addr
,
630 saddr
->SVE_tag_addr
= T_ATM_ABSENT
;
631 saddr
->address_format
= T_ATM_ABSENT
;
634 if (saddr
->address_format
== T_ATM_ENDSYS_ADDR
)
635 saddr
->SVE_tag_selector
= T_ATM_PRESENT
;
637 saddr
->SVE_tag_selector
= T_ATM_ABSENT
;
639 saddr
->SVE_tag_addr
= T_ATM_ABSENT
;
640 saddr
->SVE_tag_selector
= T_ATM_ABSENT
;
641 saddr
->address_format
= T_ATM_ABSENT
;
643 satm
->satm_addr
.t_atm_sap_layer2
.SVE_tag
= T_ATM_ABSENT
;
644 satm
->satm_addr
.t_atm_sap_layer3
.SVE_tag
= T_ATM_ABSENT
;
645 satm
->satm_addr
.t_atm_sap_appl
.SVE_tag
= T_ATM_ABSENT
;
647 *addr
= (struct sockaddr
*)satm
;
653 * Common setsockopt processing
658 * so pointer to socket
659 * sopt pointer to socket option info
660 * atp pointer to ATM PCB
663 * 0 request processed
664 * errno error processing request - reason indicated
668 atm_sock_setopt(struct socket
*so
, struct sockopt
*sopt
, Atm_pcb
*atp
)
672 struct t_atm_aal5 aal5
;
673 struct t_atm_traffic trf
;
674 struct t_atm_bearer brr
;
675 struct t_atm_bhli bhl
;
676 struct t_atm_blli bll
;
678 struct t_atm_cause cau
;
679 struct t_atm_qos qos
;
680 struct t_atm_transit trn
;
681 struct t_atm_net_intf nif
;
682 struct t_atm_llc llc
;
683 struct t_atm_app_name appn
;
686 #define MAXVAL(bits) ((1 << bits) - 1)
687 #define MAXMASK(bits) (~MAXVAL(bits))
689 switch (sopt
->sopt_name
) {
692 err
= soopt_to_kbuf(sopt
, &p
.aal5
, sizeof p
.aal5
, sizeof p
.aal5
);
695 if ((p
.aal5
.forward_max_SDU_size
!= T_ATM_ABSENT
) &&
696 (p
.aal5
.forward_max_SDU_size
& MAXMASK(16)))
698 if ((p
.aal5
.backward_max_SDU_size
!= T_ATM_ABSENT
) &&
699 (p
.aal5
.backward_max_SDU_size
& MAXMASK(16)))
701 if ((p
.aal5
.SSCS_type
!= T_ATM_ABSENT
) &&
702 (p
.aal5
.SSCS_type
!= T_ATM_NULL
) &&
703 (p
.aal5
.SSCS_type
!= T_ATM_SSCS_SSCOP_REL
) &&
704 (p
.aal5
.SSCS_type
!= T_ATM_SSCS_SSCOP_UNREL
) &&
705 (p
.aal5
.SSCS_type
!= T_ATM_SSCS_FR
))
708 if ((p
.aal5
.forward_max_SDU_size
== T_ATM_ABSENT
) &&
709 (p
.aal5
.backward_max_SDU_size
== T_ATM_ABSENT
) &&
710 (p
.aal5
.SSCS_type
== T_ATM_ABSENT
))
711 atp
->atp_attr
.aal
.tag
= T_ATM_ABSENT
;
713 atp
->atp_attr
.aal
.tag
= T_ATM_PRESENT
;
714 atp
->atp_attr
.aal
.type
= ATM_AAL5
;
715 atp
->atp_attr
.aal
.v
.aal5
= p
.aal5
;
720 err
= soopt_to_kbuf(sopt
, &p
.trf
, sizeof p
.trf
, sizeof p
.trf
);
723 if ((p
.trf
.forward
.PCR_high_priority
!= T_ATM_ABSENT
) &&
724 (p
.trf
.forward
.PCR_high_priority
& MAXMASK(24)))
726 if (p
.trf
.forward
.PCR_all_traffic
& MAXMASK(24))
728 if ((p
.trf
.forward
.SCR_high_priority
!= T_ATM_ABSENT
) &&
729 (p
.trf
.forward
.SCR_high_priority
& MAXMASK(24)))
731 if ((p
.trf
.forward
.SCR_all_traffic
!= T_ATM_ABSENT
) &&
732 (p
.trf
.forward
.SCR_all_traffic
& MAXMASK(24)))
734 if ((p
.trf
.forward
.MBS_high_priority
!= T_ATM_ABSENT
) &&
735 (p
.trf
.forward
.MBS_high_priority
& MAXMASK(24)))
737 if ((p
.trf
.forward
.MBS_all_traffic
!= T_ATM_ABSENT
) &&
738 (p
.trf
.forward
.MBS_all_traffic
& MAXMASK(24)))
740 if ((p
.trf
.forward
.tagging
!= T_YES
) &&
741 (p
.trf
.forward
.tagging
!= T_NO
))
744 if ((p
.trf
.backward
.PCR_high_priority
!= T_ATM_ABSENT
) &&
745 (p
.trf
.backward
.PCR_high_priority
& MAXMASK(24)))
747 if (p
.trf
.backward
.PCR_all_traffic
& MAXMASK(24))
749 if ((p
.trf
.backward
.SCR_high_priority
!= T_ATM_ABSENT
) &&
750 (p
.trf
.backward
.SCR_high_priority
& MAXMASK(24)))
752 if ((p
.trf
.backward
.SCR_all_traffic
!= T_ATM_ABSENT
) &&
753 (p
.trf
.backward
.SCR_all_traffic
& MAXMASK(24)))
755 if ((p
.trf
.backward
.MBS_high_priority
!= T_ATM_ABSENT
) &&
756 (p
.trf
.backward
.MBS_high_priority
& MAXMASK(24)))
758 if ((p
.trf
.backward
.MBS_all_traffic
!= T_ATM_ABSENT
) &&
759 (p
.trf
.backward
.MBS_all_traffic
& MAXMASK(24)))
761 if ((p
.trf
.backward
.tagging
!= T_YES
) &&
762 (p
.trf
.backward
.tagging
!= T_NO
))
764 if ((p
.trf
.best_effort
!= T_YES
) &&
765 (p
.trf
.best_effort
!= T_NO
))
768 atp
->atp_attr
.traffic
.tag
= T_ATM_PRESENT
;
769 atp
->atp_attr
.traffic
.v
= p
.trf
;
772 case T_ATM_BEARER_CAP
:
773 err
= soopt_to_kbuf(sopt
, &p
.brr
, sizeof p
.brr
, sizeof p
.brr
);
776 if ((p
.brr
.bearer_class
!= T_ATM_CLASS_A
) &&
777 (p
.brr
.bearer_class
!= T_ATM_CLASS_C
) &&
778 (p
.brr
.bearer_class
!= T_ATM_CLASS_X
))
780 if ((p
.brr
.traffic_type
!= T_ATM_NULL
) &&
781 (p
.brr
.traffic_type
!= T_ATM_CBR
) &&
782 (p
.brr
.traffic_type
!= T_ATM_VBR
))
784 if ((p
.brr
.timing_requirements
!= T_ATM_NULL
) &&
785 (p
.brr
.timing_requirements
!= T_ATM_END_TO_END
) &&
786 (p
.brr
.timing_requirements
!= T_ATM_NO_END_TO_END
))
788 if ((p
.brr
.clipping_susceptibility
!= T_NO
) &&
789 (p
.brr
.clipping_susceptibility
!= T_YES
))
791 if ((p
.brr
.connection_configuration
!= T_ATM_1_TO_1
) &&
792 (p
.brr
.connection_configuration
!= T_ATM_1_TO_MANY
))
795 atp
->atp_attr
.bearer
.tag
= T_ATM_PRESENT
;
796 atp
->atp_attr
.bearer
.v
= p
.brr
;
800 err
= soopt_to_kbuf(sopt
, &p
.bhl
, sizeof p
.bhl
, sizeof p
.bhl
);
803 if ((p
.bhl
.ID_type
!= T_ATM_ABSENT
) &&
804 (p
.bhl
.ID_type
!= T_ATM_ISO_APP_ID
) &&
805 (p
.bhl
.ID_type
!= T_ATM_USER_APP_ID
) &&
806 (p
.bhl
.ID_type
!= T_ATM_VENDOR_APP_ID
))
809 if (p
.bhl
.ID_type
== T_ATM_ABSENT
)
810 atp
->atp_attr
.bhli
.tag
= T_ATM_ABSENT
;
812 atp
->atp_attr
.bhli
.tag
= T_ATM_PRESENT
;
813 atp
->atp_attr
.bhli
.v
= p
.bhl
;
818 err
= soopt_to_kbuf(sopt
, &p
.bll
, sizeof p
.bll
, sizeof p
.bll
);
821 if ((p
.bll
.layer_2_protocol
.ID_type
!= T_ATM_ABSENT
) &&
822 (p
.bll
.layer_2_protocol
.ID_type
!= T_ATM_SIMPLE_ID
) &&
823 (p
.bll
.layer_2_protocol
.ID_type
!= T_ATM_USER_ID
))
825 if ((p
.bll
.layer_2_protocol
.mode
!= T_ATM_ABSENT
) &&
826 (p
.bll
.layer_2_protocol
.mode
!= T_ATM_BLLI_NORMAL_MODE
) &&
827 (p
.bll
.layer_2_protocol
.mode
!= T_ATM_BLLI_EXTENDED_MODE
))
829 if ((p
.bll
.layer_2_protocol
.window_size
!= T_ATM_ABSENT
) &&
830 (p
.bll
.layer_2_protocol
.window_size
< 1))
833 if ((p
.bll
.layer_3_protocol
.ID_type
!= T_ATM_ABSENT
) &&
834 (p
.bll
.layer_3_protocol
.ID_type
!= T_ATM_SIMPLE_ID
) &&
835 (p
.bll
.layer_3_protocol
.ID_type
!= T_ATM_IPI_ID
) &&
836 (p
.bll
.layer_3_protocol
.ID_type
!= T_ATM_SNAP_ID
) &&
837 (p
.bll
.layer_3_protocol
.ID_type
!= T_ATM_USER_ID
))
839 if ((p
.bll
.layer_3_protocol
.mode
!= T_ATM_ABSENT
) &&
840 (p
.bll
.layer_3_protocol
.mode
!= T_ATM_BLLI_NORMAL_MODE
) &&
841 (p
.bll
.layer_3_protocol
.mode
!= T_ATM_BLLI_EXTENDED_MODE
))
843 if ((p
.bll
.layer_3_protocol
.packet_size
!= T_ATM_ABSENT
) &&
844 (p
.bll
.layer_3_protocol
.packet_size
& MAXMASK(4)))
846 if ((p
.bll
.layer_3_protocol
.window_size
!= T_ATM_ABSENT
) &&
847 (p
.bll
.layer_3_protocol
.window_size
< 1))
850 if (p
.bll
.layer_2_protocol
.ID_type
== T_ATM_ABSENT
)
851 atp
->atp_attr
.blli
.tag_l2
= T_ATM_ABSENT
;
853 atp
->atp_attr
.blli
.tag_l2
= T_ATM_PRESENT
;
855 if (p
.bll
.layer_3_protocol
.ID_type
== T_ATM_ABSENT
)
856 atp
->atp_attr
.blli
.tag_l3
= T_ATM_ABSENT
;
858 atp
->atp_attr
.blli
.tag_l3
= T_ATM_PRESENT
;
860 if ((atp
->atp_attr
.blli
.tag_l2
== T_ATM_PRESENT
) ||
861 (atp
->atp_attr
.blli
.tag_l3
== T_ATM_PRESENT
))
862 atp
->atp_attr
.blli
.v
= p
.bll
;
865 case T_ATM_DEST_ADDR
:
866 err
= soopt_to_kbuf(sopt
, &p
.addr
, sizeof p
.addr
, sizeof p
.addr
);
869 if ((p
.addr
.address_format
!= T_ATM_ENDSYS_ADDR
) &&
870 (p
.addr
.address_format
!= T_ATM_E164_ADDR
))
872 if (p
.addr
.address_length
> ATM_ADDR_LEN
)
875 atp
->atp_attr
.called
.tag
= T_ATM_PRESENT
;
876 atp
->atp_attr
.called
.addr
= p
.addr
;
880 err
= soopt_to_kbuf(sopt
, &p
.addr
, sizeof p
.addr
, sizeof p
.addr
);
883 if ((p
.addr
.address_format
!= T_ATM_ABSENT
) &&
884 (p
.addr
.address_format
!= T_ATM_NSAP_ADDR
))
886 if (p
.addr
.address_length
> ATM_ADDR_LEN
)
889 /* T_ATM_DEST_ADDR controls tag */
890 atp
->atp_attr
.called
.subaddr
= p
.addr
;
893 case T_ATM_ORIG_ADDR
:
899 case T_ATM_CALLER_ID
:
903 err
= soopt_to_kbuf(sopt
, &p
.cau
, sizeof p
.cau
, sizeof p
.cau
);
906 if ((p
.cau
.coding_standard
!= T_ATM_ABSENT
) &&
907 (p
.cau
.coding_standard
!= T_ATM_ITU_CODING
) &&
908 (p
.cau
.coding_standard
!= T_ATM_NETWORK_CODING
))
910 if ((p
.cau
.location
!= T_ATM_LOC_USER
) &&
911 (p
.cau
.location
!= T_ATM_LOC_LOCAL_PRIVATE_NET
) &&
912 (p
.cau
.location
!= T_ATM_LOC_LOCAL_PUBLIC_NET
) &&
913 (p
.cau
.location
!= T_ATM_LOC_TRANSIT_NET
) &&
914 (p
.cau
.location
!= T_ATM_LOC_REMOTE_PUBLIC_NET
) &&
915 (p
.cau
.location
!= T_ATM_LOC_REMOTE_PRIVATE_NET
) &&
916 (p
.cau
.location
!= T_ATM_LOC_INTERNATIONAL_NET
) &&
917 (p
.cau
.location
!= T_ATM_LOC_BEYOND_INTERWORKING
))
920 if (p
.cau
.coding_standard
== T_ATM_ABSENT
)
921 atp
->atp_attr
.cause
.tag
= T_ATM_ABSENT
;
923 atp
->atp_attr
.cause
.tag
= T_ATM_PRESENT
;
924 atp
->atp_attr
.cause
.v
= p
.cau
;
929 err
= soopt_to_kbuf(sopt
, &p
.qos
, sizeof p
.qos
, sizeof p
.qos
);
932 if ((p
.qos
.coding_standard
!= T_ATM_ABSENT
) &&
933 (p
.qos
.coding_standard
!= T_ATM_ITU_CODING
) &&
934 (p
.qos
.coding_standard
!= T_ATM_NETWORK_CODING
))
936 if ((p
.qos
.forward
.qos_class
!= T_ATM_QOS_CLASS_0
) &&
937 (p
.qos
.forward
.qos_class
!= T_ATM_QOS_CLASS_1
) &&
938 (p
.qos
.forward
.qos_class
!= T_ATM_QOS_CLASS_2
) &&
939 (p
.qos
.forward
.qos_class
!= T_ATM_QOS_CLASS_3
) &&
940 (p
.qos
.forward
.qos_class
!= T_ATM_QOS_CLASS_4
))
942 if ((p
.qos
.backward
.qos_class
!= T_ATM_QOS_CLASS_0
) &&
943 (p
.qos
.backward
.qos_class
!= T_ATM_QOS_CLASS_1
) &&
944 (p
.qos
.backward
.qos_class
!= T_ATM_QOS_CLASS_2
) &&
945 (p
.qos
.backward
.qos_class
!= T_ATM_QOS_CLASS_3
) &&
946 (p
.qos
.backward
.qos_class
!= T_ATM_QOS_CLASS_4
))
949 if (p
.qos
.coding_standard
== T_ATM_ABSENT
)
950 atp
->atp_attr
.qos
.tag
= T_ATM_ABSENT
;
952 atp
->atp_attr
.qos
.tag
= T_ATM_PRESENT
;
953 atp
->atp_attr
.qos
.v
= p
.qos
;
958 err
= soopt_to_kbuf(sopt
, &p
.trn
, sizeof p
.trn
, sizeof p
.trn
);
961 if (p
.trn
.length
> T_ATM_MAX_NET_ID
)
964 if (p
.trn
.length
== 0)
965 atp
->atp_attr
.transit
.tag
= T_ATM_ABSENT
;
967 atp
->atp_attr
.transit
.tag
= T_ATM_PRESENT
;
968 atp
->atp_attr
.transit
.v
= p
.trn
;
973 return (EPROTONOSUPPORT
); /* XXX */
975 case T_ATM_DROP_LEAF
:
976 return (EPROTONOSUPPORT
); /* XXX */
979 err
= soopt_to_kbuf(sopt
, &p
.nif
, sizeof p
.nif
, sizeof p
.nif
);
983 atp
->atp_attr
.nif
= atm_nifname(p
.nif
.net_intf
);
984 if (atp
->atp_attr
.nif
== NULL
)
989 err
= soopt_to_kbuf(sopt
, &p
.llc
, sizeof p
.llc
, sizeof p
.llc
);
992 if ((p
.llc
.llc_len
< T_ATM_LLC_MIN_LEN
) ||
993 (p
.llc
.llc_len
> T_ATM_LLC_MAX_LEN
))
996 atp
->atp_attr
.llc
.tag
= T_ATM_PRESENT
;
997 atp
->atp_attr
.llc
.v
= p
.llc
;
1000 case T_ATM_APP_NAME
:
1001 err
= soopt_to_kbuf(sopt
, &p
.appn
, sizeof p
.appn
, sizeof p
.appn
);
1005 strncpy(atp
->atp_name
, p
.appn
.app_name
, T_ATM_APP_NAME_LEN
);
1009 return (ENOPROTOOPT
);
1017 * Common getsockopt processing
1022 * so pointer to socket
1023 * sopt pointer to socket option info
1024 * atp pointer to ATM PCB
1027 * 0 request processed
1028 * errno error processing request - reason indicated
1032 atm_sock_getopt(struct socket
*so
, struct sockopt
*sopt
, Atm_pcb
*atp
)
1037 * If socket is connected, return attributes for the VCC in use,
1038 * otherwise just return what the user has setup so far.
1040 if (so
->so_state
& SS_ISCONNECTED
)
1041 ap
= &atp
->atp_conn
->co_connvc
->cvc_attr
;
1043 ap
= &atp
->atp_attr
;
1045 switch (sopt
->sopt_name
) {
1048 if ((ap
->aal
.tag
== T_ATM_PRESENT
) &&
1049 (ap
->aal
.type
== ATM_AAL5
)) {
1050 soopt_from_kbuf(sopt
, &ap
->aal
.v
.aal5
,
1051 sizeof ap
->aal
.v
.aal5
);
1059 if (ap
->traffic
.tag
== T_ATM_PRESENT
) {
1060 soopt_from_kbuf(sopt
, &ap
->traffic
.v
,
1061 sizeof ap
->traffic
.v
);
1068 case T_ATM_BEARER_CAP
:
1069 if (ap
->bearer
.tag
== T_ATM_PRESENT
) {
1070 soopt_from_kbuf(sopt
, &ap
->bearer
.v
,
1071 sizeof ap
->bearer
.v
);
1079 if (ap
->bhli
.tag
== T_ATM_PRESENT
) {
1080 soopt_from_kbuf(sopt
, &ap
->bhli
.v
,
1089 if ((ap
->blli
.tag_l2
== T_ATM_PRESENT
) ||
1090 (ap
->blli
.tag_l3
== T_ATM_PRESENT
)) {
1091 soopt_from_kbuf(sopt
, &ap
->blli
.v
,
1099 case T_ATM_DEST_ADDR
:
1100 if (ap
->called
.tag
== T_ATM_PRESENT
) {
1101 soopt_from_kbuf(sopt
, &ap
->called
.addr
,
1102 sizeof ap
->called
.addr
);
1109 case T_ATM_DEST_SUB
:
1110 if (ap
->called
.tag
== T_ATM_PRESENT
) {
1111 soopt_from_kbuf(sopt
, &ap
->called
.subaddr
,
1112 sizeof ap
->called
.subaddr
);
1119 case T_ATM_ORIG_ADDR
:
1120 if (ap
->calling
.tag
== T_ATM_PRESENT
) {
1121 soopt_from_kbuf(sopt
, &ap
->calling
.addr
,
1122 sizeof ap
->calling
.addr
);
1129 case T_ATM_ORIG_SUB
:
1130 if (ap
->calling
.tag
== T_ATM_PRESENT
) {
1131 soopt_from_kbuf(sopt
, &ap
->calling
.subaddr
,
1132 sizeof ap
->calling
.subaddr
);
1139 case T_ATM_CALLER_ID
:
1140 if (ap
->calling
.tag
== T_ATM_PRESENT
) {
1141 soopt_from_kbuf(sopt
, &ap
->calling
.cid
,
1142 sizeof ap
->calling
.cid
);
1150 if (ap
->cause
.tag
== T_ATM_PRESENT
) {
1151 soopt_from_kbuf(sopt
, &ap
->cause
.v
,
1152 sizeof ap
->cause
.v
);
1160 if (ap
->qos
.tag
== T_ATM_PRESENT
) {
1161 soopt_from_kbuf(sopt
, &ap
->qos
.v
,
1170 if (ap
->transit
.tag
== T_ATM_PRESENT
) {
1171 soopt_from_kbuf(sopt
, &ap
->transit
.v
,
1172 sizeof ap
->transit
.v
);
1179 case T_ATM_LEAF_IND
:
1180 return (EPROTONOSUPPORT
); /* XXX */
1182 case T_ATM_NET_INTF
:
1184 struct t_atm_net_intf netif
;
1187 ifp
= &ap
->nif
->nif_if
;
1188 ksnprintf(netif
.net_intf
, sizeof(netif
.net_intf
),
1189 "%s", ifp
->if_xname
);
1190 soopt_from_kbuf(sopt
, &netif
,
1199 if (ap
->llc
.tag
== T_ATM_PRESENT
) {
1200 soopt_from_kbuf(sopt
, &ap
->llc
.v
,
1209 return (ENOPROTOOPT
);
1217 * Process Socket VCC Connected Notification
1220 * toku owner's connection token (atm_pcb protocol block)
1227 atm_sock_connected(void *toku
)
1229 Atm_pcb
*atp
= (Atm_pcb
*)toku
;
1232 * Connection is setup
1234 atm_sock_stat
.as_conncomp
[atp
->atp_type
]++;
1235 soisconnected(atp
->atp_socket
);
1240 * Process Socket VCC Cleared Notification
1243 * toku owner's connection token (atm_pcb protocol block)
1244 * cause pointer to cause code
1251 atm_sock_cleared(void *toku
, struct t_atm_cause
*cause
)
1253 Atm_pcb
*atp
= (Atm_pcb
*)toku
;
1256 so
= atp
->atp_socket
;
1259 * Save call clearing cause
1261 atp
->atp_attr
.cause
.tag
= T_ATM_PRESENT
;
1262 atp
->atp_attr
.cause
.v
= *cause
;
1265 * Set user error code
1267 if (so
->so_state
& SS_ISCONNECTED
) {
1268 so
->so_error
= ECONNRESET
;
1269 atm_sock_stat
.as_connclr
[atp
->atp_type
]++;
1271 so
->so_error
= ECONNREFUSED
;
1272 atm_sock_stat
.as_connfail
[atp
->atp_type
]++;
1276 * Connection is gone
1278 atp
->atp_conn
= NULL
;
1279 soisdisconnected(so
);
1282 * Cleanup failed incoming connection setup
1284 if (so
->so_state
& SS_NOFDREF
) {
1285 atm_sock_detach(so
);