~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to sys/solaris/sock.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}