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_aal5.c,v 1.6 1999/10/09 23:24:59 green Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/atm_aal5.c,v 1.2 2003/06/17 04:28:48 dillon Exp $
34 * ATM AAL5 socket protocol processing
38 #include <netatm/kern_include.h>
44 u_long atm_aal5_sendspace = 64 * 1024; /* XXX */
45 u_long atm_aal5_recvspace = 64 * 1024; /* XXX */
51 static int atm_aal5_attach __P((struct socket *, int, struct proc *));
52 static int atm_aal5_detach __P((struct socket *));
53 static int atm_aal5_bind __P((struct socket *, struct sockaddr *,
55 static int atm_aal5_listen __P((struct socket *, struct proc *));
56 static int atm_aal5_connect __P((struct socket *, struct sockaddr *,
58 static int atm_aal5_accept __P((struct socket *, struct sockaddr **));
59 static int atm_aal5_disconnect __P((struct socket *));
60 static int atm_aal5_shutdown __P((struct socket *));
61 static int atm_aal5_send __P((struct socket *, int, KBuffer *,
62 struct sockaddr *, KBuffer *, struct proc *));
63 static int atm_aal5_abort __P((struct socket *));
64 static int atm_aal5_control __P((struct socket *, u_long, caddr_t,
65 struct ifnet *, struct proc *));
66 static int atm_aal5_sense __P((struct socket *, struct stat *));
67 static int atm_aal5_sockaddr __P((struct socket *, struct sockaddr **));
68 static int atm_aal5_peeraddr __P((struct socket *, struct sockaddr **));
69 static int atm_aal5_incoming __P((void *, Atm_connection *,
70 Atm_attributes *, void **));
71 static void atm_aal5_cpcs_data __P((void *, KBuffer *));
72 static caddr_t atm_aal5_getname __P((void *));
75 #if (defined(__FreeBSD__) && (BSD >= 199506))
77 * New-style socket request routines
79 struct pr_usrreqs atm_aal5_usrreqs = {
80 atm_aal5_abort, /* pru_abort */
81 atm_aal5_accept, /* pru_accept */
82 atm_aal5_attach, /* pru_attach */
83 atm_aal5_bind, /* pru_bind */
84 atm_aal5_connect, /* pru_connect */
85 pru_connect2_notsupp, /* pru_connect2 */
86 atm_aal5_control, /* pru_control */
87 atm_aal5_detach, /* pru_detach */
88 atm_aal5_disconnect, /* pru_disconnect */
89 atm_aal5_listen, /* pru_listen */
90 atm_aal5_peeraddr, /* pru_peeraddr */
91 pru_rcvd_notsupp, /* pru_rcvd */
92 pru_rcvoob_notsupp, /* pru_rcvoob */
93 atm_aal5_send, /* pru_send */
94 atm_aal5_sense, /* pru_sense */
95 atm_aal5_shutdown, /* pru_shutdown */
96 atm_aal5_sockaddr, /* pru_sockaddr */
97 sosend, /* pru_sosend */
98 soreceive, /* pru_soreceive */
99 sopoll /* pru_sopoll */
107 static Atm_endpoint atm_aal5_endpt = {
125 static Atm_attributes atm_aal5_defattr = {
127 CMAPI_CPCS, /* api */
178 * Handy common code macros
181 #define ATM_INTRO(f) \
184 ATM_DEBUG2("aal5 socket %s (%p)\n", f, so); \
186 * Stack queue should have been drained \
188 if (atm_stackq_head != NULL) \
189 panic("atm_aal5: stack queue not empty"); \
191 #else /* !DIAGNOSTIC */
192 #define ATM_INTRO(f) \
196 #endif /* DIAGNOSTIC */
198 #define ATM_OUTRO() \
200 * Drain any deferred calls \
207 #define ATM_RETERR(errno) { \
214 * Attach protocol to socket
217 * so pointer to socket
218 * proto protocol identifier
219 * p pointer to process
222 * 0 request processed
223 * errno error processing request - reason indicated
227 atm_aal5_attach(so, proto, p)
237 * Do general attach stuff
239 err = atm_sock_attach(so, atm_aal5_sendspace, atm_aal5_recvspace);
244 * Finish up any protocol specific stuff
246 atp = sotoatmpcb(so);
247 atp->atp_type = ATPT_AAL5;
250 * Set default connection attributes
252 atp->atp_attr = atm_aal5_defattr;
253 strncpy(atp->atp_name, "(AAL5)", T_ATM_APP_NAME_LEN);
261 * Detach protocol from socket
264 * so pointer to socket
267 * 0 request processed
268 * errno error processing request - reason indicated
277 err = atm_sock_detach(so);
284 * Bind address to socket
287 * so pointer to socket
288 * addr pointer to protocol address
289 * p pointer to process
292 * 0 request processed
293 * errno error processing request - reason indicated
297 atm_aal5_bind(so, addr, p)
299 struct sockaddr *addr;
304 err = atm_sock_bind(so, addr);
311 * Listen for incoming connections
314 * so pointer to socket
315 * p pointer to process
318 * 0 request processed
319 * errno error processing request - reason indicated
323 atm_aal5_listen(so, p)
329 err = atm_sock_listen(so, &atm_aal5_endpt);
336 * Connect socket to peer
339 * so pointer to socket
340 * addr pointer to protocol address
341 * p pointer to process
344 * 0 request processed
345 * errno error processing request - reason indicated
349 atm_aal5_connect(so, addr, p)
351 struct sockaddr *addr;
356 ATM_INTRO("connect");
358 atp = sotoatmpcb(so);
361 * Resize send socket buffer to maximum sdu size
363 if (atp->atp_attr.aal.tag == T_ATM_PRESENT) {
366 size = atp->atp_attr.aal.v.aal5.forward_max_SDU_size;
367 if (size != T_ATM_ABSENT)
368 if (!sbreserve(&so->so_snd, size, so, p)) {
376 * Now get the socket connected
378 err = atm_sock_connect(so, addr, &atm_aal5_endpt);
385 * Accept pending connection
388 * so pointer to socket
389 * addr pointer to pointer to contain protocol address
392 * 0 request processed
393 * errno error processing request - reason indicated
397 atm_aal5_accept(so, addr)
399 struct sockaddr **addr;
404 * Everything is pretty much done already, we just need to
405 * return the caller's address to the user.
407 err = atm_sock_peeraddr(so, addr);
414 * Disconnect connected socket
417 * so pointer to socket
420 * 0 request processed
421 * errno error processing request - reason indicated
425 atm_aal5_disconnect(so)
428 ATM_INTRO("disconnect");
430 err = atm_sock_disconnect(so);
437 * Shut down socket data transmission
440 * so pointer to socket
443 * 0 request processed
444 * errno error processing request - reason indicated
448 atm_aal5_shutdown(so)
451 ATM_INTRO("shutdown");
463 * so pointer to socket
464 * flags send data flags
465 * m pointer to buffer containing user data
466 * addr pointer to protocol address
467 * control pointer to buffer containing protocol control data
468 * p pointer to process
471 * 0 request processed
472 * errno error processing request - reason indicated
476 atm_aal5_send(so, flags, m, addr, control, p)
480 struct sockaddr *addr;
489 * We don't support any control functions
494 clen = KB_LEN(control);
503 * We also don't support any flags or send-level addressing
511 * All we've got left is the data, so push it out
513 atp = sotoatmpcb(so);
514 err = atm_cm_cpcs_data(atp->atp_conn, m);
517 * Output problem, drop packet
519 atm_sock_stat.as_outdrop[atp->atp_type]++;
529 * Abnormally terminate service
532 * so pointer to socket
535 * 0 request processed
536 * errno error processing request - reason indicated
545 so->so_error = ECONNABORTED;
546 err = atm_sock_detach(so);
553 * Do control operation - ioctl system call
556 * so pointer to socket
558 * data pointer to code specific parameter data area
559 * ifp pointer to ifnet structure if it's an interface ioctl
560 * p pointer to process
563 * 0 request processed
564 * errno error processing request - reason indicated
568 atm_aal5_control(so, cmd, data, ifp, p)
575 ATM_INTRO("control");
587 * Sense socket status - fstat system call
590 * so pointer to socket
591 * st pointer to file status structure
594 * 0 request processed
595 * errno error processing request - reason indicated
599 atm_aal5_sense(so, st)
606 * Just return the max sdu size for the connection
608 st->st_blksize = so->so_snd.sb_hiwat;
615 * Retrieve local socket address
618 * so pointer to socket
619 * addr pointer to pointer to contain protocol address
622 * 0 request processed
623 * errno error processing request - reason indicated
627 atm_aal5_sockaddr(so, addr)
629 struct sockaddr **addr;
631 ATM_INTRO("sockaddr");
633 err = atm_sock_sockaddr(so, addr);
640 * Retrieve peer socket address
643 * so pointer to socket
644 * addr pointer to pointer to contain protocol address
647 * 0 request processed
648 * errno error processing request - reason indicated
652 atm_aal5_peeraddr(so, addr)
654 struct sockaddr **addr;
656 ATM_INTRO("peeraddr");
658 err = atm_sock_peeraddr(so, addr);
665 * Process Incoming Calls
667 * This function will receive control when an incoming call has been matched
668 * to one of our registered listen parameter blocks. Assuming the call passes
669 * acceptance criteria and all required resources are available, we will
670 * create a new protocol control block and socket association. We must
671 * then await notification of the final SVC setup results. If any
672 * problems are encountered, we will just tell the connection manager to
678 * tok owner's matched listening token
679 * cop pointer to incoming call's connection block
680 * ap pointer to incoming call's attributes
681 * tokp pointer to location to store our connection token
685 * errno call rejected - reason indicated
689 atm_aal5_incoming(tok, cop, ap, tokp)
695 Atm_pcb *atp0 = tok, *atp;
700 * Allocate a new socket and pcb for this connection.
702 * Note that our attach function will be called via sonewconn
703 * and it will allocate and setup most of the pcb.
705 atm_sock_stat.as_inconn[atp0->atp_type]++;
706 #if (defined(BSD) && (BSD >= 199103))
707 so = sonewconn(atp0->atp_socket, 0);
709 so = sonewconn(atp0->atp_socket);
714 * Finish pcb setup and pass pcb back to CM
716 atp = sotoatmpcb(so);
718 atp->atp_attr = *atp0->atp_conn->co_lattr;
719 strncpy(atp->atp_name, atp0->atp_name, T_ATM_APP_NAME_LEN);
723 atm_sock_stat.as_connfail[atp0->atp_type]++;
731 * Process Socket VCC Input Data
734 * tok owner's connection token (atm_pcb)
735 * m pointer to input packet buffer chain
742 atm_aal5_cpcs_data(tok, m)
750 so = atp->atp_socket;
755 * Ensure that the socket is able to receive data and
756 * that there's room in the socket buffer
758 if (((so->so_state & SS_ISCONNECTED) == 0) ||
759 (so->so_state & SS_CANTRCVMORE) ||
760 (len > sbspace(&so->so_rcv))) {
761 atm_sock_stat.as_indrop[atp->atp_type]++;
767 * Queue the data and notify the user
769 sbappendrecord(&so->so_rcv, m);
777 * Process getsockopt/setsockopt system calls
780 * so pointer to socket
781 * sopt pointer to socket option info
784 * 0 request processed
785 * errno error processing request - reason indicated
789 atm_aal5_ctloutput(so, sopt)
791 struct sockopt *sopt;
795 ATM_INTRO("ctloutput");
798 * Make sure this is for us
800 if (sopt->sopt_level != T_ATM_SIGNALING) {
803 atp = sotoatmpcb(so);
805 ATM_RETERR(ENOTCONN);
808 switch (sopt->sopt_dir) {
816 * Validate socket state
818 switch (sopt->sopt_name) {
821 case T_ATM_DROP_LEAF:
822 if ((so->so_state & SS_ISCONNECTED) == 0) {
823 ATM_RETERR(ENOTCONN);
832 if (so->so_state & SS_ISCONNECTED) {
839 * Validate and save user-supplied option data
841 err = atm_sock_setopt(so, sopt, atp);
853 err = atm_sock_getopt(so, sopt, atp);
864 * Initialize AAL5 Sockets
877 * Register our endpoint
879 if (atm_endpoint_register(&atm_aal5_endpt))
880 panic("atm_aal5_init: register");
883 * Set default connection attributes
885 atm_aal5_defattr.aal.v.aal5.forward_max_SDU_size = T_ATM_ABSENT;
886 atm_aal5_defattr.aal.v.aal5.backward_max_SDU_size = T_ATM_ABSENT;
887 atm_aal5_defattr.aal.v.aal5.SSCS_type = T_ATM_NULL;
892 * Get Connection's Application/Owner Name
895 * tok owner's connection token (atm_pcb)
898 * addr pointer to string containing our name
902 atm_aal5_getname(tok)
907 return (atp->atp_name);