5 __weak_alias(bind
, _bind
)
15 #include <sys/ioctl.h>
16 #include <sys/socket.h>
17 #include <sys/types.h>
19 #include <netinet/in.h>
21 #include <net/gen/in.h>
22 #include <net/gen/tcp.h>
23 #include <net/gen/tcp_io.h>
24 #include <net/gen/udp.h>
25 #include <net/gen/udp_io.h>
28 #include <minix/config.h>
29 #include <minix/const.h>
33 static int _tcp_bind(int sock
, const struct sockaddr
*address
,
34 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
);
35 static int _udp_bind(int sock
, const struct sockaddr
*address
,
36 socklen_t address_len
, nwio_udpopt_t
*udpoptp
);
37 static int _uds_bind(int sock
, const struct sockaddr
*address
,
38 socklen_t address_len
, struct sockaddr_un
*uds_addr
);
40 int bind(int sock
, const struct sockaddr
*address
, socklen_t address_len
)
43 nwio_tcpconf_t tcpconf
;
45 struct sockaddr_un uds_addr
;
47 r
= ioctl(sock
, NWIOGTCPCONF
, &tcpconf
);
48 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
52 r
= _tcp_bind(sock
, address
, address_len
, &tcpconf
);
57 fprintf(stderr
, "bind(tcp) failed: %s\n",
65 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
66 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
70 return _udp_bind(sock
, address
, address_len
, &udpopt
);
73 r
= ioctl(sock
, NWIOGUDSADDR
, &uds_addr
);
74 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
78 return _uds_bind(sock
, address
, address_len
, &uds_addr
);
82 fprintf(stderr
, "bind: not implemented for fd %d\n", sock
);
88 static int _tcp_bind(int sock
, const struct sockaddr
*address
,
89 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
)
92 nwio_tcpconf_t tcpconf
;
93 struct sockaddr_in
*sinp
;
95 sinp
= (struct sockaddr_in
*) __UNCONST(address
);
96 if (sinp
->sin_family
!= AF_INET
|| address_len
< sizeof(*sinp
))
99 fprintf(stderr
, "bind(tcp): sin_family = %d, len = %d\n",
100 sinp
->sin_family
, address_len
);
106 if (sinp
->sin_addr
.s_addr
!= INADDR_ANY
&&
107 sinp
->sin_addr
.s_addr
!= tcpconfp
->nwtc_locaddr
)
109 errno
= EADDRNOTAVAIL
;
113 tcpconf
.nwtc_flags
= 0;
115 if (sinp
->sin_port
== 0)
116 tcpconf
.nwtc_flags
|= NWTC_LP_SEL
;
119 tcpconf
.nwtc_flags
|= NWTC_LP_SET
;
120 tcpconf
.nwtc_locport
= sinp
->sin_port
;
123 r
= ioctl(sock
, NWIOSTCPCONF
, &tcpconf
);
127 static int _udp_bind(int sock
, const struct sockaddr
*address
,
128 socklen_t address_len
, nwio_udpopt_t
*udpoptp
)
131 unsigned long curr_flags
;
132 nwio_udpopt_t udpopt
;
133 struct sockaddr_in
*sinp
;
135 sinp
= (struct sockaddr_in
*) __UNCONST(address
);
136 if (sinp
->sin_family
!= AF_INET
|| address_len
< sizeof(*sinp
))
139 fprintf(stderr
, "bind(udp): sin_family = %d, len = %d\n",
140 sinp
->sin_family
, address_len
);
146 if (sinp
->sin_addr
.s_addr
!= INADDR_ANY
&&
147 sinp
->sin_addr
.s_addr
!= udpoptp
->nwuo_locaddr
)
149 errno
= EADDRNOTAVAIL
;
153 udpopt
.nwuo_flags
= 0;
155 if (sinp
->sin_port
== 0)
156 udpopt
.nwuo_flags
|= NWUO_LP_SEL
;
159 udpopt
.nwuo_flags
|= NWUO_LP_SET
;
160 udpopt
.nwuo_locport
= sinp
->sin_port
;
163 curr_flags
= udpoptp
->nwuo_flags
;
164 if (!(curr_flags
& NWUO_ACC_MASK
))
165 udpopt
.nwuo_flags
|= NWUO_EXCL
;
166 if (!(curr_flags
& (NWUO_EN_LOC
|NWUO_DI_LOC
)))
167 udpopt
.nwuo_flags
|= NWUO_EN_LOC
;
168 if (!(curr_flags
& (NWUO_EN_BROAD
|NWUO_DI_BROAD
)))
169 udpopt
.nwuo_flags
|= NWUO_EN_BROAD
;
170 if (!(curr_flags
& (NWUO_RP_SET
|NWUO_RP_ANY
)))
171 udpopt
.nwuo_flags
|= NWUO_RP_ANY
;
172 if (!(curr_flags
& (NWUO_RA_SET
|NWUO_RA_ANY
)))
173 udpopt
.nwuo_flags
|= NWUO_RA_ANY
;
174 if (!(curr_flags
& (NWUO_RWDATONLY
|NWUO_RWDATALL
)))
175 udpopt
.nwuo_flags
|= NWUO_RWDATALL
;
176 if (!(curr_flags
& (NWUO_EN_IPOPT
|NWUO_DI_IPOPT
)))
177 udpopt
.nwuo_flags
|= NWUO_DI_IPOPT
;
179 r
= ioctl(sock
, NWIOSUDPOPT
, &udpopt
);
183 static int _uds_bind(int sock
, const struct sockaddr
*address
,
184 socklen_t address_len
, struct sockaddr_un
*uds_addr
)
189 if (address
== NULL
) {
196 r
= mknod(((struct sockaddr_un
*) __UNCONST(address
))->sun_path
,
197 S_IFSOCK
|S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IWGRP
|S_IROTH
|S_IWOTH
, 0);
199 if (r
== -1 && errno
!= EEXIST
) {
205 /* perform the bind */
206 r
= ioctl(sock
, NWIOSUDSADDR
, (void *) __UNCONST(address
));
208 if (r
== -1 && did_mknod
) {
210 /* bind() failed in pfs, so we roll back the
213 unlink(((struct sockaddr_un
*) __UNCONST(address
))->sun_path
);