5 #include <sys/socket.h>
6 #include <netinet/in.h>
8 #include <net/gen/in.h>
9 #include <net/gen/tcp.h>
10 #include <net/gen/tcp_io.h>
11 #include <net/gen/udp.h>
12 #include <net/gen/udp_io.h>
16 static int _tcp_bind(int socket
, const struct sockaddr
*address
,
17 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
);
18 static int _udp_bind(int socket
, const struct sockaddr
*address
,
19 socklen_t address_len
, nwio_udpopt_t
*udpoptp
);
21 int bind(int socket
, const struct sockaddr
*address
, socklen_t address_len
)
24 nwio_tcpconf_t tcpconf
;
27 r
= ioctl(socket
, NWIOGTCPCONF
, &tcpconf
);
28 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
32 r
= _tcp_bind(socket
, address
, address_len
, &tcpconf
);
37 fprintf(stderr
, "bind(tcp) failed: %s\n",
45 r
= ioctl(socket
, NWIOGUDPOPT
, &udpopt
);
46 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
50 return _udp_bind(socket
, address
, address_len
, &udpopt
);
54 fprintf(stderr
, "bind: not implemented for fd %d\n", socket
);
60 static int _tcp_bind(int socket
, const struct sockaddr
*address
,
61 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
)
64 nwio_tcpconf_t tcpconf
;
65 struct sockaddr_in
*sinp
;
67 sinp
= (struct sockaddr_in
*)address
;
68 if (sinp
->sin_family
!= AF_INET
|| address_len
!= sizeof(*sinp
))
71 fprintf(stderr
, "bind(tcp): sin_family = %d, len = %d\n",
72 sinp
->sin_family
, address_len
);
78 if (sinp
->sin_addr
.s_addr
!= INADDR_ANY
&&
79 sinp
->sin_addr
.s_addr
!= tcpconfp
->nwtc_locaddr
)
85 tcpconf
.nwtc_flags
= 0;
87 if (sinp
->sin_port
== 0)
88 tcpconf
.nwtc_flags
|= NWTC_LP_SEL
;
91 tcpconf
.nwtc_flags
|= NWTC_LP_SET
;
92 tcpconf
.nwtc_locport
= sinp
->sin_port
;
95 r
= ioctl(socket
, NWIOSTCPCONF
, &tcpconf
);
99 static int _udp_bind(int socket
, const struct sockaddr
*address
,
100 socklen_t address_len
, nwio_udpopt_t
*udpoptp
)
103 unsigned long curr_flags
;
104 nwio_udpopt_t udpopt
;
105 struct sockaddr_in
*sinp
;
107 sinp
= (struct sockaddr_in
*)address
;
108 if (sinp
->sin_family
!= AF_INET
|| address_len
!= sizeof(*sinp
))
111 fprintf(stderr
, "bind(udp): sin_family = %d, len = %d\n",
112 sinp
->sin_family
, address_len
);
118 if (sinp
->sin_addr
.s_addr
!= INADDR_ANY
&&
119 sinp
->sin_addr
.s_addr
!= udpoptp
->nwuo_locaddr
)
121 errno
= EADDRNOTAVAIL
;
125 udpopt
.nwuo_flags
= 0;
127 if (sinp
->sin_port
== 0)
128 udpopt
.nwuo_flags
|= NWUO_LP_SEL
;
131 udpopt
.nwuo_flags
|= NWUO_LP_SET
;
132 udpopt
.nwuo_locport
= sinp
->sin_port
;
135 curr_flags
= udpoptp
->nwuo_flags
;
136 if (!(curr_flags
& NWUO_ACC_MASK
))
137 udpopt
.nwuo_flags
|= NWUO_EXCL
;
138 if (!(curr_flags
& (NWUO_EN_LOC
|NWUO_DI_LOC
)))
139 udpopt
.nwuo_flags
|= NWUO_EN_LOC
;
140 if (!(curr_flags
& (NWUO_EN_BROAD
|NWUO_DI_BROAD
)))
141 udpopt
.nwuo_flags
|= NWUO_EN_BROAD
;
142 if (!(curr_flags
& (NWUO_RP_SET
|NWUO_RP_ANY
)))
143 udpopt
.nwuo_flags
|= NWUO_RP_ANY
;
144 if (!(curr_flags
& (NWUO_RA_SET
|NWUO_RA_ANY
)))
145 udpopt
.nwuo_flags
|= NWUO_RA_ANY
;
146 if (!(curr_flags
& (NWUO_RWDATONLY
|NWUO_RWDATALL
)))
147 udpopt
.nwuo_flags
|= NWUO_RWDATALL
;
148 if (!(curr_flags
& (NWUO_EN_IPOPT
|NWUO_DI_IPOPT
)))
149 udpopt
.nwuo_flags
|= NWUO_DI_IPOPT
;
151 r
= ioctl(socket
, NWIOSUDPOPT
, &udpopt
);