]> arthur.barton.de Git - netatalk.git/blob - sys/solaris/sock.c
Remove bdb env on exit
[netatalk.git] / sys / solaris / sock.c
1 /* $Id: sock.c,v 1.2 2002-01-17 07:11:13 srittau Exp $
2  */
3
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif /* HAVE_CONFIG_H */
7
8 #include <sys/types.h>
9 #include <sys/stream.h>
10 #include <sys/socket.h>
11 #include <sys/errno.h>
12 #include <sys/kmem.h>
13 #include <sys/cmn_err.h>
14 #include <sys/tihdr.h>
15 #include <sys/ethernet.h>
16 #include <net/if.h>
17
18 #ifdef STDC_HEADERS
19 #include <strings.h>
20 #else
21 #include <string.h>
22 #endif
23
24 #include <netatalk/at.h>
25
26 #include "if.h"
27 #include "sock.h"
28
29 static struct sock_data *sockets = NULL;
30
31     struct sock_data *
32 sock_alloc( queue_t *q )
33 {
34     struct sock_data    *sd;
35
36     if (( sd = kmem_alloc( sizeof( struct sock_data ), KM_SLEEP )) == NULL ) {
37         return( NULL );
38     }
39     sd->sd_state = TS_UNBND;
40     sd->sd_q = q;
41     sd->sd_next = sd->sd_prev = NULL;
42     bzero( (caddr_t)&sd->sd_sat, sizeof( struct sockaddr_at ));
43
44     sd->sd_next = sockets;
45     if ( sockets != NULL ) {
46         sockets->sd_prev = sd;
47     }
48     sockets = sd;
49
50     return( sd );
51 }
52
53     void
54 sock_free( struct sock_data *sd )
55 {
56     if ( sd == sockets ) {
57         sockets = sd->sd_next;
58     }
59     if ( sd->sd_next != NULL ) {
60         sd->sd_next->sd_prev = sd->sd_prev;
61     }
62     if ( sd->sd_prev != NULL ) {
63         sd->sd_prev->sd_next = sd->sd_next;
64     }
65     kmem_free( sd, sizeof( struct sock_data ));
66     return;
67 }
68
69     struct sock_data *
70 sock_dest( struct atif_data *aid, struct sockaddr_at *sat )
71 {
72     struct sock_data    *sd;
73
74     for ( sd = sockets; sd != NULL; sd = sd->sd_next ) {
75         if ( sat->sat_port == sd->sd_sat.sat_port &&
76                 /* huh? */
77                 aid->aid_sat.sat_addr.s_net == sd->sd_sat.sat_addr.s_net &&
78                 ( sat->sat_addr.s_node == sd->sd_sat.sat_addr.s_node ||
79                 sat->sat_addr.s_node == ATADDR_BCAST )) {
80             break;
81         }
82     }
83     return( sd );
84 }
85
86 /*
87  * This is a change in semantics.  The port must be ATADDR_ANYPORT for
88  * ATADDR_ANYNET/NODE to not mean the loopback.
89  */
90     int
91 sock_bind( struct sock_data *sd, struct sockaddr_at *sat )
92 {
93     struct atif_data    *paid;
94     struct sock_data    *psd;
95     struct sockaddr_at  psat;
96     u_short             port;
97
98     psat = *sat;
99     if ( psat.sat_family != AF_APPLETALK ) {
100         cmn_err( CE_CONT, "sock_bind non-AppleTalk\n" );
101         return( EPROTOTYPE );
102     }
103
104     if ( psat.sat_port == ATADDR_ANYPORT ) {
105         if ( psat.sat_addr.s_net == ATADDR_ANYNET &&
106                 psat.sat_addr.s_node == ATADDR_ANYNODE ) {
107             /* chose primary interface */
108             if (( paid = if_primary()) == NULL ) {
109                 return( EADDRNOTAVAIL );
110             }
111             psat.sat_addr.s_net = paid->aid_sat.sat_addr.s_net;
112             psat.sat_addr.s_node = paid->aid_sat.sat_addr.s_node;
113         }
114
115         /* pick unused port */
116         for ( port = ATPORT_RESERVED; port < ATPORT_LAST; port++ ) {
117             for ( psd = sockets; psd != NULL; psd = psd->sd_next ) {
118                 if ( port == psd->sd_sat.sat_port &&
119                         psat.sat_addr.s_net == psd->sd_sat.sat_addr.s_net &&
120                         psat.sat_addr.s_node == psd->sd_sat.sat_addr.s_node ) {
121                     break;
122                 }
123             }
124             if ( psd == NULL ) {
125                 break;
126             }
127         }
128         if ( psd != NULL ) {
129             return( EADDRINUSE );
130         }
131         psat.sat_port = port;
132     }
133
134     sd->sd_sat = psat;
135     sd->sd_state = TS_IDLE;
136     return( 0 );
137 }