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.13 2007/04/22 01:13:15 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 .pru_abort
= atm_aal5_abort
,
81 .pru_accept
= atm_aal5_accept
,
82 .pru_attach
= atm_aal5_attach
,
83 .pru_bind
= atm_aal5_bind
,
84 .pru_connect
= atm_aal5_connect
,
85 .pru_connect2
= pru_connect2_notsupp
,
86 .pru_control
= atm_aal5_control
,
87 .pru_detach
= atm_aal5_detach
,
88 .pru_disconnect
= atm_aal5_disconnect
,
89 .pru_listen
= atm_aal5_listen
,
90 .pru_peeraddr
= atm_aal5_peeraddr
,
91 .pru_rcvd
= pru_rcvd_notsupp
,
92 .pru_rcvoob
= pru_rcvoob_notsupp
,
93 .pru_send
= atm_aal5_send
,
94 .pru_sense
= atm_aal5_sense
,
95 .pru_shutdown
= atm_aal5_shutdown
,
96 .pru_sockaddr
= atm_aal5_sockaddr
,
98 .pru_soreceive
= soreceive
,
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(error) { \
212 * Attach protocol to socket
215 * so pointer to socket
216 * proto protocol identifier
217 * p pointer to process
220 * 0 request processed
221 * error error processing request - reason indicated
225 atm_aal5_attach(struct socket
*so
, int proto
, struct pru_attach_info
*ai
)
232 * Do general attach stuff
234 err
= atm_sock_attach(so
, atm_aal5_sendspace
, atm_aal5_recvspace
,
240 * Finish up any protocol specific stuff
242 atp
= sotoatmpcb(so
);
243 atp
->atp_type
= ATPT_AAL5
;
246 * Set default connection attributes
248 atp
->atp_attr
= atm_aal5_defattr
;
249 strncpy(atp
->atp_name
, "(AAL5)", T_ATM_APP_NAME_LEN
);
257 * Detach protocol from socket
260 * so pointer to socket
263 * 0 request processed
264 * error error processing request - reason indicated
268 atm_aal5_detach(struct socket
*so
)
272 err
= atm_sock_detach(so
);
279 * Bind address to socket
282 * so pointer to socket
283 * addr pointer to protocol address
284 * p pointer to process
287 * 0 request processed
288 * error error processing request - reason indicated
292 atm_aal5_bind(struct socket
*so
, struct sockaddr
*addr
, struct thread
*td
)
296 err
= atm_sock_bind(so
, addr
);
303 * Listen for incoming connections
306 * so pointer to socket
307 * p pointer to process
310 * 0 request processed
311 * error error processing request - reason indicated
315 atm_aal5_listen(struct socket
*so
, struct thread
*td
)
319 err
= atm_sock_listen(so
, &atm_aal5_endpt
);
326 * Connect socket to peer
329 * so pointer to socket
330 * addr pointer to protocol address
331 * p pointer to process
334 * 0 request processed
335 * error error processing request - reason indicated
339 atm_aal5_connect(struct socket
*so
, struct sockaddr
*addr
, thread_t td
)
343 ATM_INTRO("connect");
345 atp
= sotoatmpcb(so
);
348 * Resize send socket buffer to maximum sdu size
350 if (atp
->atp_attr
.aal
.tag
== T_ATM_PRESENT
) {
353 size
= atp
->atp_attr
.aal
.v
.aal5
.forward_max_SDU_size
;
354 if (size
!= T_ATM_ABSENT
)
355 if (!ssb_reserve(&so
->so_snd
, size
, so
,
356 &td
->td_proc
->p_rlimit
[RLIMIT_SBSIZE
])) {
364 * Now get the socket connected
366 err
= atm_sock_connect(so
, addr
, &atm_aal5_endpt
);
373 * Accept pending connection
376 * so pointer to socket
377 * addr pointer to pointer to contain protocol address
380 * 0 request processed
381 * error error processing request - reason indicated
385 atm_aal5_accept(struct socket
*so
, struct sockaddr
**addr
)
390 * Everything is pretty much done already, we just need to
391 * return the caller's address to the user.
393 err
= atm_sock_peeraddr(so
, addr
);
400 * Disconnect connected socket
403 * so pointer to socket
406 * 0 request processed
407 * error error processing request - reason indicated
411 atm_aal5_disconnect(struct socket
*so
)
413 ATM_INTRO("disconnect");
415 err
= atm_sock_disconnect(so
);
422 * Shut down socket data transmission
425 * so pointer to socket
428 * 0 request processed
429 * error error processing request - reason indicated
433 atm_aal5_shutdown(struct socket
*so
)
435 ATM_INTRO("shutdown");
447 * so pointer to socket
448 * flags send data flags
449 * m pointer to buffer containing user data
450 * addr pointer to protocol address
451 * control pointer to buffer containing protocol control data
452 * p pointer to process
455 * 0 request processed
456 * error error processing request - reason indicated
464 struct sockaddr
*addr
,
473 * We don't support any control functions
478 clen
= KB_LEN(control
);
487 * We also don't support any flags or send-level addressing
495 * All we've got left is the data, so push it out
497 atp
= sotoatmpcb(so
);
498 err
= atm_cm_cpcs_data(atp
->atp_conn
, m
);
501 * Output problem, drop packet
503 atm_sock_stat
.as_outdrop
[atp
->atp_type
]++;
513 * Abnormally terminate service
516 * so pointer to socket
519 * 0 request processed
520 * error error processing request - reason indicated
524 atm_aal5_abort(struct socket
*so
)
528 so
->so_error
= ECONNABORTED
;
529 err
= atm_sock_detach(so
);
536 * Do control operation - ioctl system call
539 * so pointer to socket
541 * data pointer to code specific parameter data area
542 * ifp pointer to ifnet structure if it's an interface ioctl
543 * p pointer to process
546 * 0 request processed
547 * error error processing request - reason indicated
558 ATM_INTRO("control");
570 * Sense socket status - fstat system call
573 * so pointer to socket
574 * st pointer to file status structure
577 * 0 request processed
578 * error error processing request - reason indicated
582 atm_aal5_sense(struct socket
*so
, struct stat
*st
)
587 * Just return the max sdu size for the connection
589 st
->st_blksize
= so
->so_snd
.ssb_hiwat
;
596 * Retrieve local socket address
599 * so pointer to socket
600 * addr pointer to pointer to contain protocol address
603 * 0 request processed
604 * error error processing request - reason indicated
608 atm_aal5_sockaddr(struct socket
*so
, struct sockaddr
**addr
)
610 ATM_INTRO("sockaddr");
612 err
= atm_sock_sockaddr(so
, addr
);
619 * Retrieve peer socket address
622 * so pointer to socket
623 * addr pointer to pointer to contain protocol address
626 * 0 request processed
627 * error error processing request - reason indicated
631 atm_aal5_peeraddr(struct socket
*so
, struct sockaddr
**addr
)
633 ATM_INTRO("peeraddr");
635 err
= atm_sock_peeraddr(so
, addr
);
642 * Process Incoming Calls
644 * This function will receive control when an incoming call has been matched
645 * to one of our registered listen parameter blocks. Assuming the call passes
646 * acceptance criteria and all required resources are available, we will
647 * create a new protocol control block and socket association. We must
648 * then await notification of the final SVC setup results. If any
649 * problems are encountered, we will just tell the connection manager to
652 * Called from a critical section.
655 * tok owner's matched listening token
656 * cop pointer to incoming call's connection block
657 * ap pointer to incoming call's attributes
658 * tokp pointer to location to store our connection token
662 * error call rejected - reason indicated
666 atm_aal5_incoming(void *tok
, Atm_connection
*cop
, Atm_attributes
*ap
,
669 Atm_pcb
*atp0
= tok
, *atp
;
674 * Allocate a new socket and pcb for this connection.
676 * Note that our attach function will be called via sonewconn
677 * and it will allocate and setup most of the pcb.
679 atm_sock_stat
.as_inconn
[atp0
->atp_type
]++;
680 so
= sonewconn(atp0
->atp_socket
, 0);
684 * Finish pcb setup and pass pcb back to CM
686 atp
= sotoatmpcb(so
);
688 atp
->atp_attr
= *atp0
->atp_conn
->co_lattr
;
689 strncpy(atp
->atp_name
, atp0
->atp_name
, T_ATM_APP_NAME_LEN
);
693 atm_sock_stat
.as_connfail
[atp0
->atp_type
]++;
701 * Process Socket VCC Input Data
704 * tok owner's connection token (atm_pcb)
705 * m pointer to input packet buffer chain
712 atm_aal5_cpcs_data(void *tok
, KBuffer
*m
)
718 so
= atp
->atp_socket
;
723 * Ensure that the socket is able to receive data and
724 * that there's room in the socket buffer
726 if (((so
->so_state
& SS_ISCONNECTED
) == 0) ||
727 (so
->so_state
& SS_CANTRCVMORE
) ||
728 (len
> ssb_space(&so
->so_rcv
))) {
729 atm_sock_stat
.as_indrop
[atp
->atp_type
]++;
735 * Queue the data and notify the user
737 ssb_appendrecord(&so
->so_rcv
, m
);
745 * Process getsockopt/setsockopt system calls
748 * so pointer to socket
749 * sopt pointer to socket option info
752 * 0 request processed
753 * error error processing request - reason indicated
757 atm_aal5_ctloutput(struct socket
*so
, struct sockopt
*sopt
)
761 ATM_INTRO("ctloutput");
764 * Make sure this is for us
766 if (sopt
->sopt_level
!= T_ATM_SIGNALING
) {
769 atp
= sotoatmpcb(so
);
771 ATM_RETERR(ENOTCONN
);
774 switch (sopt
->sopt_dir
) {
782 * Validate socket state
784 switch (sopt
->sopt_name
) {
787 case T_ATM_DROP_LEAF
:
788 if ((so
->so_state
& SS_ISCONNECTED
) == 0) {
789 ATM_RETERR(ENOTCONN
);
798 if (so
->so_state
& SS_ISCONNECTED
) {
805 * Validate and save user-supplied option data
807 err
= atm_sock_setopt(so
, sopt
, atp
);
819 err
= atm_sock_getopt(so
, sopt
, atp
);
830 * Initialize AAL5 Sockets
843 * Register our endpoint
845 if (atm_endpoint_register(&atm_aal5_endpt
))
846 panic("atm_aal5_init: register");
849 * Set default connection attributes
851 atm_aal5_defattr
.aal
.v
.aal5
.forward_max_SDU_size
= T_ATM_ABSENT
;
852 atm_aal5_defattr
.aal
.v
.aal5
.backward_max_SDU_size
= T_ATM_ABSENT
;
853 atm_aal5_defattr
.aal
.v
.aal5
.SSCS_type
= T_ATM_NULL
;
858 * Get Connection's Application/Owner Name
861 * tok owner's connection token (atm_pcb)
864 * addr pointer to string containing our name
868 atm_aal5_getname(void *tok
)
872 return (atp
->atp_name
);