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.9 2005/06/02 22:37:45 dillon Exp $
34 * ATM AAL5 socket protocol processing
38 #include "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 (struct socket
*, int,
52 struct pru_attach_info
*);
53 static int atm_aal5_detach (struct socket
*);
54 static int atm_aal5_bind (struct socket
*, struct sockaddr
*,
56 static int atm_aal5_listen (struct socket
*, struct thread
*);
57 static int atm_aal5_connect (struct socket
*, struct sockaddr
*,
59 static int atm_aal5_accept (struct socket
*, struct sockaddr
**);
60 static int atm_aal5_disconnect (struct socket
*);
61 static int atm_aal5_shutdown (struct socket
*);
62 static int atm_aal5_send (struct socket
*, int, KBuffer
*,
63 struct sockaddr
*, KBuffer
*, struct thread
*);
64 static int atm_aal5_abort (struct socket
*);
65 static int atm_aal5_control (struct socket
*, u_long
, caddr_t
,
66 struct ifnet
*, struct thread
*);
67 static int atm_aal5_sense (struct socket
*, struct stat
*);
68 static int atm_aal5_sockaddr (struct socket
*, struct sockaddr
**);
69 static int atm_aal5_peeraddr (struct socket
*, struct sockaddr
**);
70 static int atm_aal5_incoming (void *, Atm_connection
*,
71 Atm_attributes
*, void **);
72 static void atm_aal5_cpcs_data (void *, KBuffer
*);
73 static caddr_t
atm_aal5_getname (void *);
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 */
105 static Atm_endpoint atm_aal5_endpt
= {
123 static Atm_attributes atm_aal5_defattr
= {
125 CMAPI_CPCS
, /* api */
176 * Handy common code macros
179 #define ATM_INTRO(f) \
182 ATM_DEBUG2("aal5 socket %s (%p)\n", f, so); \
184 * Stack queue should have been drained \
186 if (atm_stackq_head != NULL) \
187 panic("atm_aal5: stack queue not empty"); \
189 #else /* !DIAGNOSTIC */
190 #define ATM_INTRO(f) \
194 #endif /* DIAGNOSTIC */
196 #define ATM_OUTRO() \
198 * Drain any deferred calls \
205 #define ATM_RETERR(errno) { \
212 * Attach protocol to socket
215 * so pointer to socket
216 * proto protocol identifier
217 * p pointer to process
220 * 0 request processed
221 * errno error processing request - reason indicated
225 atm_aal5_attach(so
, proto
, ai
)
228 struct pru_attach_info
*ai
;
235 * Do general attach stuff
237 err
= atm_sock_attach(so
, atm_aal5_sendspace
, atm_aal5_recvspace
,
243 * Finish up any protocol specific stuff
245 atp
= sotoatmpcb(so
);
246 atp
->atp_type
= ATPT_AAL5
;
249 * Set default connection attributes
251 atp
->atp_attr
= atm_aal5_defattr
;
252 strncpy(atp
->atp_name
, "(AAL5)", T_ATM_APP_NAME_LEN
);
260 * Detach protocol from socket
263 * so pointer to socket
266 * 0 request processed
267 * errno error processing request - reason indicated
276 err
= atm_sock_detach(so
);
283 * Bind address to socket
286 * so pointer to socket
287 * addr pointer to protocol address
288 * p pointer to process
291 * 0 request processed
292 * errno error processing request - reason indicated
296 atm_aal5_bind(so
, addr
, td
)
298 struct sockaddr
*addr
;
303 err
= atm_sock_bind(so
, addr
);
310 * Listen for incoming connections
313 * so pointer to socket
314 * p pointer to process
317 * 0 request processed
318 * errno error processing request - reason indicated
322 atm_aal5_listen(struct socket
*so
, struct thread
*td
)
326 err
= atm_sock_listen(so
, &atm_aal5_endpt
);
333 * Connect socket to peer
336 * so pointer to socket
337 * addr pointer to protocol address
338 * p pointer to process
341 * 0 request processed
342 * errno error processing request - reason indicated
346 atm_aal5_connect(struct socket
*so
, struct sockaddr
*addr
, thread_t td
)
350 ATM_INTRO("connect");
352 atp
= sotoatmpcb(so
);
355 * Resize send socket buffer to maximum sdu size
357 if (atp
->atp_attr
.aal
.tag
== T_ATM_PRESENT
) {
360 size
= atp
->atp_attr
.aal
.v
.aal5
.forward_max_SDU_size
;
361 if (size
!= T_ATM_ABSENT
)
362 if (!sbreserve(&so
->so_snd
, size
, so
,
363 &td
->td_proc
->p_rlimit
[RLIMIT_SBSIZE
])) {
371 * Now get the socket connected
373 err
= atm_sock_connect(so
, addr
, &atm_aal5_endpt
);
380 * Accept pending connection
383 * so pointer to socket
384 * addr pointer to pointer to contain protocol address
387 * 0 request processed
388 * errno error processing request - reason indicated
392 atm_aal5_accept(struct socket
*so
, struct sockaddr
**addr
)
397 * Everything is pretty much done already, we just need to
398 * return the caller's address to the user.
400 err
= atm_sock_peeraddr(so
, addr
);
407 * Disconnect connected socket
410 * so pointer to socket
413 * 0 request processed
414 * errno error processing request - reason indicated
418 atm_aal5_disconnect(struct socket
*so
)
420 ATM_INTRO("disconnect");
422 err
= atm_sock_disconnect(so
);
429 * Shut down socket data transmission
432 * so pointer to socket
435 * 0 request processed
436 * errno error processing request - reason indicated
440 atm_aal5_shutdown(struct socket
*so
)
442 ATM_INTRO("shutdown");
454 * so pointer to socket
455 * flags send data flags
456 * m pointer to buffer containing user data
457 * addr pointer to protocol address
458 * control pointer to buffer containing protocol control data
459 * p pointer to process
462 * 0 request processed
463 * errno error processing request - reason indicated
471 struct sockaddr
*addr
,
480 * We don't support any control functions
485 clen
= KB_LEN(control
);
494 * We also don't support any flags or send-level addressing
502 * All we've got left is the data, so push it out
504 atp
= sotoatmpcb(so
);
505 err
= atm_cm_cpcs_data(atp
->atp_conn
, m
);
508 * Output problem, drop packet
510 atm_sock_stat
.as_outdrop
[atp
->atp_type
]++;
520 * Abnormally terminate service
523 * so pointer to socket
526 * 0 request processed
527 * errno error processing request - reason indicated
531 atm_aal5_abort(struct socket
*so
)
535 so
->so_error
= ECONNABORTED
;
536 err
= atm_sock_detach(so
);
543 * Do control operation - ioctl system call
546 * so pointer to socket
548 * data pointer to code specific parameter data area
549 * ifp pointer to ifnet structure if it's an interface ioctl
550 * p pointer to process
553 * 0 request processed
554 * errno error processing request - reason indicated
565 ATM_INTRO("control");
577 * Sense socket status - fstat system call
580 * so pointer to socket
581 * st pointer to file status structure
584 * 0 request processed
585 * errno error processing request - reason indicated
589 atm_aal5_sense(struct socket
*so
, struct stat
*st
)
594 * Just return the max sdu size for the connection
596 st
->st_blksize
= so
->so_snd
.sb_hiwat
;
603 * Retrieve local socket address
606 * so pointer to socket
607 * addr pointer to pointer to contain protocol address
610 * 0 request processed
611 * errno error processing request - reason indicated
615 atm_aal5_sockaddr(struct socket
*so
, struct sockaddr
**addr
)
617 ATM_INTRO("sockaddr");
619 err
= atm_sock_sockaddr(so
, addr
);
626 * Retrieve peer socket address
629 * so pointer to socket
630 * addr pointer to pointer to contain protocol address
633 * 0 request processed
634 * errno error processing request - reason indicated
638 atm_aal5_peeraddr(struct socket
*so
, struct sockaddr
**addr
)
640 ATM_INTRO("peeraddr");
642 err
= atm_sock_peeraddr(so
, addr
);
649 * Process Incoming Calls
651 * This function will receive control when an incoming call has been matched
652 * to one of our registered listen parameter blocks. Assuming the call passes
653 * acceptance criteria and all required resources are available, we will
654 * create a new protocol control block and socket association. We must
655 * then await notification of the final SVC setup results. If any
656 * problems are encountered, we will just tell the connection manager to
659 * Called from a critical section.
662 * tok owner's matched listening token
663 * cop pointer to incoming call's connection block
664 * ap pointer to incoming call's attributes
665 * tokp pointer to location to store our connection token
669 * errno call rejected - reason indicated
673 atm_aal5_incoming(tok
, cop
, ap
, tokp
)
679 Atm_pcb
*atp0
= tok
, *atp
;
684 * Allocate a new socket and pcb for this connection.
686 * Note that our attach function will be called via sonewconn
687 * and it will allocate and setup most of the pcb.
689 atm_sock_stat
.as_inconn
[atp0
->atp_type
]++;
690 so
= sonewconn(atp0
->atp_socket
, 0);
694 * Finish pcb setup and pass pcb back to CM
696 atp
= sotoatmpcb(so
);
698 atp
->atp_attr
= *atp0
->atp_conn
->co_lattr
;
699 strncpy(atp
->atp_name
, atp0
->atp_name
, T_ATM_APP_NAME_LEN
);
703 atm_sock_stat
.as_connfail
[atp0
->atp_type
]++;
711 * Process Socket VCC Input Data
714 * tok owner's connection token (atm_pcb)
715 * m pointer to input packet buffer chain
722 atm_aal5_cpcs_data(tok
, m
)
730 so
= atp
->atp_socket
;
735 * Ensure that the socket is able to receive data and
736 * that there's room in the socket buffer
738 if (((so
->so_state
& SS_ISCONNECTED
) == 0) ||
739 (so
->so_state
& SS_CANTRCVMORE
) ||
740 (len
> sbspace(&so
->so_rcv
))) {
741 atm_sock_stat
.as_indrop
[atp
->atp_type
]++;
747 * Queue the data and notify the user
749 sbappendrecord(&so
->so_rcv
, m
);
757 * Process getsockopt/setsockopt system calls
760 * so pointer to socket
761 * sopt pointer to socket option info
764 * 0 request processed
765 * errno error processing request - reason indicated
769 atm_aal5_ctloutput(struct socket
*so
, struct sockopt
*sopt
)
773 ATM_INTRO("ctloutput");
776 * Make sure this is for us
778 if (sopt
->sopt_level
!= T_ATM_SIGNALING
) {
781 atp
= sotoatmpcb(so
);
783 ATM_RETERR(ENOTCONN
);
786 switch (sopt
->sopt_dir
) {
794 * Validate socket state
796 switch (sopt
->sopt_name
) {
799 case T_ATM_DROP_LEAF
:
800 if ((so
->so_state
& SS_ISCONNECTED
) == 0) {
801 ATM_RETERR(ENOTCONN
);
810 if (so
->so_state
& SS_ISCONNECTED
) {
817 * Validate and save user-supplied option data
819 err
= atm_sock_setopt(so
, sopt
, atp
);
831 err
= atm_sock_getopt(so
, sopt
, atp
);
842 * Initialize AAL5 Sockets
855 * Register our endpoint
857 if (atm_endpoint_register(&atm_aal5_endpt
))
858 panic("atm_aal5_init: register");
861 * Set default connection attributes
863 atm_aal5_defattr
.aal
.v
.aal5
.forward_max_SDU_size
= T_ATM_ABSENT
;
864 atm_aal5_defattr
.aal
.v
.aal5
.backward_max_SDU_size
= T_ATM_ABSENT
;
865 atm_aal5_defattr
.aal
.v
.aal5
.SSCS_type
= T_ATM_NULL
;
870 * Get Connection's Application/Owner Name
873 * tok owner's connection token (atm_pcb)
876 * addr pointer to string containing our name
880 atm_aal5_getname(tok
)
885 return (atp
->atp_name
);