]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netatm/atm_aal5.c
This commit was generated by cvs2svn to compensate for changes in r170222,
[FreeBSD/FreeBSD.git] / sys / netatm / atm_aal5.c
1 /*-
2  * ===================================
3  * HARP  |  Host ATM Research Platform
4  * ===================================
5  *
6  *
7  * This Host ATM Research Platform ("HARP") file (the "Software") is
8  * made available by Network Computing Services, Inc. ("NetworkCS")
9  * "AS IS".  NetworkCS does not provide maintenance, improvements or
10  * support of any kind.
11  *
12  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16  * In no event shall NetworkCS be responsible for any damages, including
17  * but not limited to consequential damages, arising from or relating to
18  * any use of the Software or related support.
19  *
20  * Copyright 1994-1998 Network Computing Services, Inc.
21  *
22  * Copies of this Software may be made, however, the above copyright
23  * notice must be reproduced on all copies.
24  */
25
26 /*
27  * Core ATM Services
28  * -----------------
29  *
30  * ATM AAL5 socket protocol processing
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/lock.h>
38 #include <sys/protosw.h>
39 #include <sys/signalvar.h>
40 #include <sys/socket.h>
41 #include <sys/socketvar.h>
42 #include <sys/stat.h>
43 #include <sys/sx.h>
44 #include <sys/systm.h>
45 #include <net/if.h>
46 #include <netatm/port.h>
47 #include <netatm/queue.h>
48 #include <netatm/atm.h>
49 #include <netatm/atm_sys.h>
50 #include <netatm/atm_sap.h>
51 #include <netatm/atm_cm.h>
52 #include <netatm/atm_if.h>
53 #include <netatm/atm_stack.h>
54 #include <netatm/atm_pcb.h>
55 #include <netatm/atm_var.h>
56
57
58 /*
59  * Global variables
60  */
61 u_long          atm_aal5_sendspace = 64 * 1024; /* XXX */
62 u_long          atm_aal5_recvspace = 64 * 1024; /* XXX */
63
64
65 /*
66  * Local functions
67  */
68 static int      atm_aal5_attach(struct socket *, int, struct thread *td);
69 static void     atm_aal5_detach(struct socket *);
70 static int      atm_aal5_bind(struct socket *, struct sockaddr *, 
71                         struct thread *td);
72 static int      atm_aal5_listen(struct socket *, int backlog,
73                         struct thread *td);
74 static int      atm_aal5_connect(struct socket *, struct sockaddr *,
75                         struct thread *td);
76 static int      atm_aal5_accept(struct socket *, struct sockaddr **);
77 static int      atm_aal5_disconnect(struct socket *);
78 static int      atm_aal5_shutdown(struct socket *);
79 static int      atm_aal5_send(struct socket *, int, KBuffer *,
80                         struct sockaddr *, KBuffer *, struct thread *td);
81 static void     atm_aal5_abort(struct socket *);
82 static int      atm_aal5_control(struct socket *, u_long, caddr_t, 
83                         struct ifnet *, struct thread *td);
84 static int      atm_aal5_sense(struct socket *, struct stat *);
85 static int      atm_aal5_sockaddr(struct socket *, struct sockaddr **);
86 static int      atm_aal5_peeraddr(struct socket *, struct sockaddr **);
87 static int      atm_aal5_incoming(void *, Atm_connection *,
88                         Atm_attributes *, void **);
89 static void     atm_aal5_cpcs_data(void *, KBuffer *);
90 static caddr_t  atm_aal5_getname(void *);
91 static void     atm_aal5_close(struct socket *);
92
93
94 /*
95  * New-style socket request routines
96  */
97 struct pr_usrreqs       atm_aal5_usrreqs = {
98         .pru_abort =            atm_aal5_abort,
99         .pru_accept =           atm_aal5_accept,
100         .pru_attach =           atm_aal5_attach,
101         .pru_bind =             atm_aal5_bind,
102         .pru_connect =          atm_aal5_connect,
103         .pru_control =          atm_aal5_control,
104         .pru_detach =           atm_aal5_detach,
105         .pru_disconnect =       atm_aal5_disconnect,
106         .pru_listen =           atm_aal5_listen,
107         .pru_peeraddr =         atm_aal5_peeraddr,
108         .pru_send =             atm_aal5_send,
109         .pru_sense =            atm_aal5_sense,
110         .pru_shutdown =         atm_aal5_shutdown,
111         .pru_sockaddr =         atm_aal5_sockaddr,
112         .pru_close =            atm_aal5_close,
113 };
114
115 /*
116  * Local variables
117  */
118 static Atm_endpoint     atm_aal5_endpt = {
119         NULL,
120         ENDPT_SOCK_AAL5,
121         NULL,
122         atm_aal5_getname,
123         atm_sock_connected,
124         atm_sock_cleared,
125         atm_aal5_incoming,
126         NULL,
127         NULL,
128         NULL,
129         atm_aal5_cpcs_data,
130         NULL,
131         NULL,
132         NULL,
133         NULL
134 };
135
136 static Atm_attributes   atm_aal5_defattr = {
137         NULL,                   /* nif */
138         CMAPI_CPCS,             /* api */
139         0,                      /* api_init */
140         0,                      /* headin */
141         0,                      /* headout */
142         {                       /* aal */
143                 T_ATM_PRESENT,
144                 ATM_AAL5
145         },
146         {                       /* traffic */
147                 T_ATM_ABSENT,
148         },
149         {                       /* bearer */
150                 T_ATM_ABSENT,
151         },
152         {                       /* bhli */
153                 T_ATM_ABSENT
154         },
155         {                       /* blli */
156                 T_ATM_ABSENT,
157                 T_ATM_ABSENT,
158         },
159         {                       /* llc */
160                 T_ATM_ABSENT,
161         },
162         {                       /* called */
163                 T_ATM_ABSENT,
164                 {
165                         T_ATM_ABSENT,
166                         0
167                 },
168                 {
169                         T_ATM_ABSENT,
170                         0
171                 }
172         },
173         {                       /* calling */
174                 T_ATM_ABSENT
175         },
176         {                       /* qos */
177                 T_ATM_ABSENT,
178         },
179         {                       /* transit */
180                 T_ATM_ABSENT
181         },
182         {                       /* cause */
183                 T_ATM_ABSENT
184         }
185 };
186
187
188 /*
189  * Handy common code macros
190  */
191 #ifdef DIAGNOSTIC
192 #define ATM_INTRO(f)                                            \
193         int             s, err = 0;                             \
194         s = splnet();                                           \
195         ATM_DEBUG2("aal5 socket %s (%p)\n", f, so);             \
196         /*                                                      \
197          * Stack queue should have been drained                 \
198          */                                                     \
199         if (atm_stackq_head != NULL)                            \
200                 panic("atm_aal5: stack queue not empty");       \
201         ;
202 #else /* !DIAGNOSTIC */
203 #define ATM_INTRO(f)                                            \
204         int             s, err = 0;                             \
205         s = splnet();                                           \
206         ;
207 #endif /* DIAGNOSTIC */
208
209 #define ATM_INTRO_NOERR(f)                                      \
210         int             s;                                      \
211         s = splnet();                                           \
212         ;
213
214 #define ATM_OUTRO()                                             \
215         /*                                                      \
216          * Drain any deferred calls                             \
217          */                                                     \
218         STACK_DRAIN();                                          \
219         (void) splx(s);                                         \
220         return (err);                                           \
221         ;
222
223 #define ATM_OUTRO_NOERR()                                       \
224         /*                                                      \
225          * Drain any deferred calls                             \
226          */                                                     \
227         STACK_DRAIN();                                          \
228         (void) splx(s);                                         \
229         ;
230
231 #define ATM_RETERR(errno) {                                     \
232         err = errno;                                            \
233         goto out;                                               \
234 }
235
236
237 /*
238  * Attach protocol to socket
239  *
240  * Arguments:
241  *      so      pointer to socket
242  *      proto   protocol identifier
243  *      p       pointer to process
244  *
245  * Returns:
246  *      0       request processed
247  *      errno   error processing request - reason indicated
248  *
249  */
250 static int
251 atm_aal5_attach(so, proto, td)
252         struct socket   *so;
253         int             proto;
254         struct thread   *td;
255 {
256         Atm_pcb         *atp;
257
258         ATM_INTRO("attach");
259
260         /*
261          * Do general attach stuff
262          */
263         err = atm_sock_attach(so, atm_aal5_sendspace, atm_aal5_recvspace);
264         if (err)
265                 ATM_RETERR(err);
266
267         /*
268          * Finish up any protocol specific stuff
269          */
270         atp = sotoatmpcb(so);
271         atp->atp_type = ATPT_AAL5;
272
273         /*
274          * Set default connection attributes
275          */
276         atp->atp_attr = atm_aal5_defattr;
277         strncpy(atp->atp_name, "(AAL5)", T_ATM_APP_NAME_LEN);
278
279 out:
280         ATM_OUTRO();
281 }
282
283
284 /*
285  * Detach protocol from socket
286  *
287  * Arguments:
288  *      so      pointer to socket
289  *
290  * Returns:
291  *      0       request processed
292  *      errno   error processing request - reason indicated
293  *
294  */
295 static void
296 atm_aal5_detach(so)
297         struct socket   *so;
298 {
299         ATM_INTRO_NOERR("detach");
300
301         atm_sock_detach(so);
302
303         ATM_OUTRO_NOERR();
304 }
305
306
307 /*
308  * Bind address to socket
309  *
310  * Arguments:
311  *      so      pointer to socket
312  *      addr    pointer to protocol address
313  *      p       pointer to process
314  *
315  * Returns:
316  *      0       request processed
317  *      errno   error processing request - reason indicated
318  *
319  */
320 static int
321 atm_aal5_bind(so, addr, td)
322         struct socket   *so;
323         struct sockaddr *addr;
324         struct thread   *td;
325 {
326         ATM_INTRO("bind");
327
328         err = atm_sock_bind(so, addr);
329
330         ATM_OUTRO();
331 }
332
333
334 /*
335  * Listen for incoming connections
336  *
337  * Arguments:
338  *      so      pointer to socket
339  *      p       pointer to process
340  *
341  * Returns:
342  *      0       request processed
343  *      errno   error processing request - reason indicated
344  *
345  */
346 static int
347 atm_aal5_listen(so, backlog, td)
348         struct socket   *so;
349         int              backlog;
350         struct thread   *td;
351 {
352         ATM_INTRO("listen");
353
354         err = atm_sock_listen(so, &atm_aal5_endpt, backlog);
355
356         ATM_OUTRO();
357 }
358
359
360 /*
361  * Connect socket to peer
362  *
363  * Arguments:
364  *      so      pointer to socket
365  *      addr    pointer to protocol address
366  *      p       pointer to process
367  *
368  * Returns:
369  *      0       request processed
370  *      errno   error processing request - reason indicated
371  *
372  */
373 static int
374 atm_aal5_connect(so, addr, td)
375         struct socket   *so;
376         struct sockaddr *addr;
377         struct thread   *td;
378 {
379         Atm_pcb         *atp;
380
381         ATM_INTRO("connect");
382
383         atp = sotoatmpcb(so);
384
385         /*
386          * Resize send socket buffer to maximum sdu size
387          */
388         if (atp->atp_attr.aal.tag == T_ATM_PRESENT) {
389                 long    size;
390
391                 size = atp->atp_attr.aal.v.aal5.forward_max_SDU_size;
392                 if (size != T_ATM_ABSENT)
393                         if (!sbreserve(&so->so_snd, size, so, td)) {
394                                 err = ENOBUFS;
395                                 ATM_OUTRO();
396                         }
397                                 
398         }
399
400         /*
401          * Now get the socket connected
402          */
403         err = atm_sock_connect(so, addr, &atm_aal5_endpt);
404
405         ATM_OUTRO();
406 }
407
408
409 /*
410  * Accept pending connection
411  *
412  * Arguments:
413  *      so      pointer to socket
414  *      addr    pointer to pointer to contain protocol address
415  *
416  * Returns:
417  *      0       request processed
418  *      errno   error processing request - reason indicated
419  *
420  */
421 static int
422 atm_aal5_accept(so, addr)
423         struct socket   *so;
424         struct sockaddr **addr;
425 {
426         ATM_INTRO("accept");
427
428         /*
429          * Everything is pretty much done already, we just need to
430          * return the caller's address to the user.
431          */
432         err = atm_sock_peeraddr(so, addr);
433
434         ATM_OUTRO();
435 }
436
437
438 /*
439  * Disconnect connected socket
440  *
441  * Arguments:
442  *      so      pointer to socket
443  *
444  * Returns:
445  *      0       request processed
446  *      errno   error processing request - reason indicated
447  *
448  */
449 static int
450 atm_aal5_disconnect(so)
451         struct socket   *so;
452 {
453         ATM_INTRO("disconnect");
454
455         err = atm_sock_disconnect(so);
456
457         ATM_OUTRO();
458 }
459
460
461 /*
462  * Shut down socket data transmission
463  *
464  * Arguments:
465  *      so      pointer to socket
466  *
467  * Returns:
468  *      0       request processed
469  *      errno   error processing request - reason indicated
470  *
471  */
472 static int
473 atm_aal5_shutdown(so)
474         struct socket   *so;
475 {
476         ATM_INTRO("shutdown");
477
478         socantsendmore(so);
479
480         ATM_OUTRO();
481 }
482
483
484 /*
485  * Send user data
486  *
487  * Arguments:
488  *      so      pointer to socket
489  *      flags   send data flags
490  *      m       pointer to buffer containing user data
491  *      addr    pointer to protocol address
492  *      control pointer to buffer containing protocol control data
493  *      p       pointer to process
494  *
495  * Returns:
496  *      0       request processed
497  *      errno   error processing request - reason indicated
498  *
499  */
500 static int
501 atm_aal5_send(so, flags, m, addr, control, td)
502         struct socket   *so;
503         int             flags;
504         KBuffer         *m;
505         struct sockaddr *addr;
506         KBuffer         *control;
507         struct thread   *td;
508 {
509         Atm_pcb         *atp;
510
511         ATM_INTRO("send");
512
513         /*
514          * We don't support any control functions
515          */
516         if (control) {
517                 int     clen;
518
519                 clen = KB_LEN(control);
520                 KB_FREEALL(control);
521                 if (clen) {
522                         KB_FREEALL(m);
523                         ATM_RETERR(EINVAL);
524                 }
525         }
526
527         /*
528          * We also don't support any flags or send-level addressing
529          */
530         if (flags || addr) {
531                 KB_FREEALL(m);
532                 ATM_RETERR(EINVAL);
533         }
534
535         /*
536          * All we've got left is the data, so push it out
537          */
538         atp = sotoatmpcb(so);
539         err = atm_cm_cpcs_data(atp->atp_conn, m);
540         if (err) {
541                 /*
542                  * Output problem, drop packet
543                  */
544                 atm_sock_stat.as_outdrop[atp->atp_type]++;
545                 KB_FREEALL(m);
546         }
547
548 out:
549         ATM_OUTRO();
550 }
551
552
553 /*
554  * Abnormally terminate service
555  *
556  * Arguments:
557  *      so      pointer to socket
558  *
559  * Returns:
560  *      0       request processed
561  *      errno   error processing request - reason indicated
562  *
563  */
564 static void
565 atm_aal5_abort(so)
566         struct socket   *so;
567 {
568         ATM_INTRO_NOERR("abort");
569
570         (void)atm_sock_disconnect(so);
571         so->so_error = ECONNABORTED;
572
573         ATM_OUTRO_NOERR();
574 }
575
576 static void
577 atm_aal5_close(so)
578         struct socket   *so;
579 {
580         ATM_INTRO_NOERR("close");
581
582         (void)atm_sock_disconnect(so);
583
584         ATM_OUTRO_NOERR();
585 }
586
587
588 /*
589  * Do control operation - ioctl system call
590  *
591  * Arguments:
592  *      so      pointer to socket
593  *      cmd     ioctl code
594  *      data    pointer to code specific parameter data area
595  *      ifp     pointer to ifnet structure if it's an interface ioctl
596  *      p       pointer to process
597  *
598  * Returns:
599  *      0       request processed
600  *      errno   error processing request - reason indicated
601  *
602  */
603 static int
604 atm_aal5_control(so, cmd, data, ifp, td)
605         struct socket   *so;
606         u_long          cmd;
607         caddr_t         data;
608         struct ifnet    *ifp;
609         struct thread   *td;
610 {
611         ATM_INTRO("control");
612
613         switch (cmd) {
614
615         default:
616                 err = EOPNOTSUPP;
617         }
618
619         ATM_OUTRO();
620 }
621
622 /*
623  * Sense socket status - fstat system call
624  *
625  * Arguments:
626  *      so      pointer to socket
627  *      st      pointer to file status structure
628  *
629  * Returns:
630  *      0       request processed
631  *      errno   error processing request - reason indicated
632  *
633  */
634 static int
635 atm_aal5_sense(so, st)
636         struct socket   *so;
637         struct stat     *st;
638 {
639         ATM_INTRO("sense");
640
641         /*
642          * Just return the max sdu size for the connection
643          */
644         st->st_blksize = so->so_snd.sb_hiwat;
645
646         ATM_OUTRO();
647 }
648
649
650 /*
651  * Retrieve local socket address
652  *
653  * Arguments:
654  *      so      pointer to socket
655  *      addr    pointer to pointer to contain protocol address
656  *
657  * Returns:
658  *      0       request processed
659  *      errno   error processing request - reason indicated
660  *
661  */
662 static int
663 atm_aal5_sockaddr(so, addr)
664         struct socket   *so;
665         struct sockaddr **addr;
666 {
667         ATM_INTRO("sockaddr");
668
669         err = atm_sock_sockaddr(so, addr);
670
671         ATM_OUTRO();
672 }
673
674
675 /*
676  * Retrieve peer socket address
677  *
678  * Arguments:
679  *      so      pointer to socket
680  *      addr    pointer to pointer to contain protocol address
681  *
682  * Returns:
683  *      0       request processed
684  *      errno   error processing request - reason indicated
685  *
686  */
687 static int
688 atm_aal5_peeraddr(so, addr)
689         struct socket   *so;
690         struct sockaddr **addr;
691 {
692         ATM_INTRO("peeraddr");
693
694         err = atm_sock_peeraddr(so, addr);
695
696         ATM_OUTRO();
697 }
698
699
700 /*
701  * Process Incoming Calls
702  *
703  * This function will receive control when an incoming call has been matched
704  * to one of our registered listen parameter blocks.  Assuming the call passes
705  * acceptance criteria and all required resources are available, we will
706  * create a new protocol control block and socket association.  We must
707  * then await notification of the final SVC setup results.  If any
708  * problems are encountered, we will just tell the connection manager to
709  * reject the call.
710  *
711  * Called at splnet.
712  *
713  * Arguments:
714  *      tok     owner's matched listening token
715  *      cop     pointer to incoming call's connection block
716  *      ap      pointer to incoming call's attributes
717  *      tokp    pointer to location to store our connection token
718  *
719  * Returns:
720  *      0       call is accepted
721  *      errno   call rejected - reason indicated
722  *
723  */
724 static int
725 atm_aal5_incoming(tok, cop, ap, tokp)
726         void            *tok;
727         Atm_connection  *cop;
728         Atm_attributes  *ap;
729         void            **tokp;
730 {
731         Atm_pcb         *atp0 = tok, *atp;
732         struct socket   *so;
733         int             err = 0;
734
735         /*
736          * Allocate a new socket and pcb for this connection.
737          *
738          * Note that our attach function will be called via sonewconn
739          * and it will allocate and setup most of the pcb.
740          */
741         atm_sock_stat.as_inconn[atp0->atp_type]++;
742         so = sonewconn(atp0->atp_socket, 0);
743
744         if (so) {
745                 /*
746                  * Finish pcb setup and pass pcb back to CM
747                  */
748                 atp = sotoatmpcb(so);
749                 atp->atp_conn = cop;
750                 atp->atp_attr = *atp0->atp_conn->co_lattr;
751                 strncpy(atp->atp_name, atp0->atp_name, T_ATM_APP_NAME_LEN);
752                 *tokp = atp;
753         } else {
754                 err = ECONNABORTED;
755                 atm_sock_stat.as_connfail[atp0->atp_type]++;
756         }
757
758         return (err);
759 }
760
761
762 /*
763  * Process Socket VCC Input Data
764  *
765  * Arguments:
766  *      tok     owner's connection token (atm_pcb)
767  *      m       pointer to input packet buffer chain
768  *
769  * Returns:
770  *      none
771  *
772  */
773 static void
774 atm_aal5_cpcs_data(tok, m)
775         void            *tok;
776         KBuffer         *m;
777 {
778         Atm_pcb         *atp = tok;
779         struct socket   *so;
780         int             len;
781
782         so = atp->atp_socket;
783
784         KB_PLENGET(m, len);
785
786         /*
787          * Ensure that the socket is able to receive data and
788          * that there's room in the socket buffer
789          */
790         if (((so->so_state & SS_ISCONNECTED) == 0) ||
791             (so->so_rcv.sb_state & SBS_CANTRCVMORE) ||
792             (len > sbspace(&so->so_rcv))) {
793                 atm_sock_stat.as_indrop[atp->atp_type]++;
794                 KB_FREEALL(m);
795                 return;
796         }
797
798         /*
799          * Queue the data and notify the user
800          */
801         sbappendrecord(&so->so_rcv, m);
802         sorwakeup(so);
803
804         return;
805 }
806
807
808 /*
809  * Process getsockopt/setsockopt system calls
810  *
811  * Arguments:
812  *      so      pointer to socket
813  *      sopt    pointer to socket option info
814  *
815  * Returns:
816  *      0       request processed
817  *      errno   error processing request - reason indicated
818  *
819  */
820 int
821 atm_aal5_ctloutput(so, sopt)
822         struct socket   *so;
823         struct sockopt  *sopt;
824 {
825         Atm_pcb         *atp;
826
827         ATM_INTRO("ctloutput");
828
829         /*
830          * Make sure this is for us
831          */
832         if (sopt->sopt_level != T_ATM_SIGNALING) {
833                 ATM_RETERR(EINVAL);
834         }
835         atp = sotoatmpcb(so);
836         if (atp == NULL) {
837                 ATM_RETERR(ENOTCONN);
838         }
839
840         switch (sopt->sopt_dir) {
841
842         case SOPT_SET:
843                 /*
844                  * setsockopt()
845                  */
846
847                 /*
848                  * Validate socket state
849                  */
850                 switch (sopt->sopt_name) {
851
852                 case T_ATM_ADD_LEAF:
853                 case T_ATM_DROP_LEAF:
854                         if ((so->so_state & SS_ISCONNECTED) == 0) {
855                                 ATM_RETERR(ENOTCONN);
856                         }
857                         break;
858
859                 case T_ATM_CAUSE:
860                 case T_ATM_APP_NAME:
861                         break;
862
863                 default:
864                         if (so->so_state & SS_ISCONNECTED) {
865                                 ATM_RETERR(EISCONN);
866                         }
867                         break;
868                 }
869
870                 /*
871                  * Validate and save user-supplied option data
872                  */
873                 err = atm_sock_setopt(so, sopt, atp);
874
875                 break;
876
877         case SOPT_GET:
878                 /*
879                  * getsockopt()
880                  */
881
882                 /*
883                  * Return option data
884                  */
885                 err = atm_sock_getopt(so, sopt, atp);
886
887                 break;
888         }
889
890 out:
891         ATM_OUTRO();
892 }
893
894
895 /*
896  * Initialize AAL5 Sockets
897  *
898  * Arguments:
899  *      none
900  *
901  * Returns:
902  *      none
903  *
904  */
905 void
906 atm_aal5_init()
907 {
908         /*
909          * Register our endpoint
910          */
911         if (atm_endpoint_register(&atm_aal5_endpt))
912                 panic("atm_aal5_init: register");
913
914         /*
915          * Set default connection attributes
916          */
917         atm_aal5_defattr.aal.v.aal5.forward_max_SDU_size = T_ATM_ABSENT;
918         atm_aal5_defattr.aal.v.aal5.backward_max_SDU_size = T_ATM_ABSENT;
919         atm_aal5_defattr.aal.v.aal5.SSCS_type = T_ATM_NULL;
920 }
921
922
923 /*
924  * Get Connection's Application/Owner Name
925  *
926  * Arguments:
927  *      tok     owner's connection token (atm_pcb)
928  *
929  * Returns:
930  *      addr    pointer to string containing our name
931  *
932  */
933 static caddr_t
934 atm_aal5_getname(tok)
935         void            *tok;
936 {
937         Atm_pcb         *atp = tok;
938
939         return (atp->atp_name);
940 }
941