3 #include <minix/config.h>
11 #include <sys/ioctl.h>
12 #include <sys/socket.h>
13 #include <sys/types.h>
15 #include <netinet/in.h>
17 #include <net/gen/in.h>
18 #include <net/gen/tcp.h>
19 #include <net/gen/tcp_io.h>
20 #include <net/gen/udp.h>
21 #include <net/gen/udp_io.h>
23 #include <minix/const.h>
27 static int _tcp_connect(int sock
, const struct sockaddr
*address
,
28 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
);
29 static int _udp_connect(int sock
, const struct sockaddr
*address
,
30 socklen_t address_len
, nwio_udpopt_t
*udpoptp
);
31 static int _uds_connect(int sock
, const struct sockaddr
*address
,
32 socklen_t address_len
);
34 int connect(int sock
, const struct sockaddr
*address
,
35 socklen_t address_len
)
38 nwio_tcpconf_t tcpconf
;
41 r
= ioctl(sock
, NWIOGTCPCONF
, &tcpconf
);
42 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
46 /* Bad file descriptor */
49 return _tcp_connect(sock
, address
, address_len
, &tcpconf
);
52 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
53 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
57 /* Bad file descriptor */
60 return _udp_connect(sock
, address
, address_len
, &udpopt
);
63 r
= _uds_connect(sock
, address
, address_len
);
65 (errno
!= ENOTTY
&& errno
!= EBADIOCTL
&&
66 errno
!= EAFNOSUPPORT
))
70 /* Bad file descriptor */
78 fprintf(stderr
, "connect: not implemented for fd %d\n", sock
);
84 static int _tcp_connect(int sock
, const struct sockaddr
*address
,
85 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
)
88 struct sockaddr_in
*sinp
;
89 nwio_tcpconf_t tcpconf
;
92 if (address_len
!= sizeof(*sinp
))
97 sinp
= (struct sockaddr_in
*) __UNCONST(address
);
98 if (sinp
->sin_family
!= AF_INET
)
103 tcpconf
.nwtc_flags
= NWTC_SET_RA
| NWTC_SET_RP
;
104 if ((tcpconfp
->nwtc_flags
& NWTC_LOCPORT_MASK
) == NWTC_LP_UNSET
)
105 tcpconf
.nwtc_flags
|= NWTC_LP_SEL
;
106 tcpconf
.nwtc_remaddr
= sinp
->sin_addr
.s_addr
;
107 tcpconf
.nwtc_remport
= sinp
->sin_port
;
109 if (ioctl(sock
, NWIOSTCPCONF
, &tcpconf
) == -1)
111 /* Ignore EISCONN error. The NWIOTCPCONN ioctl will get the
114 if (errno
!= EISCONN
)
118 tcpcl
.nwtcl_flags
= TCF_DEFAULT
;
120 r
= fcntl(sock
, F_GETFL
);
124 tcpcl
.nwtcl_flags
|= TCF_ASYNCH
;
126 r
= ioctl(sock
, NWIOTCPCONN
, &tcpcl
);
130 static int _udp_connect(int sock
, const struct sockaddr
*address
,
131 socklen_t address_len
, nwio_udpopt_t
*udpoptp
)
134 struct sockaddr_in
*sinp
;
135 nwio_udpopt_t udpopt
;
139 /* Unset remote address */
140 udpopt
.nwuo_flags
= NWUO_RP_ANY
| NWUO_RA_ANY
| NWUO_RWDATALL
;
142 r
= ioctl(sock
, NWIOSUDPOPT
, &udpopt
);
146 if (address_len
!= sizeof(*sinp
))
151 sinp
= (struct sockaddr_in
*) __UNCONST(address
);
152 if (sinp
->sin_family
!= AF_INET
)
157 udpopt
.nwuo_flags
= NWUO_RP_SET
| NWUO_RA_SET
| NWUO_RWDATONLY
;
158 if ((udpoptp
->nwuo_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_ANY
)
159 udpopt
.nwuo_flags
|= NWUO_LP_SEL
;
160 udpopt
.nwuo_remaddr
= sinp
->sin_addr
.s_addr
;
161 udpopt
.nwuo_remport
= sinp
->sin_port
;
163 r
= ioctl(sock
, NWIOSUDPOPT
, &udpopt
);
167 static int _uds_connect(int sock
, const struct sockaddr
*address
,
168 socklen_t address_len
)
171 if (address
== NULL
) {
176 /* perform the connect */
177 return ioctl(sock
, NWIOSUDSCONN
, (void *) __UNCONST(address
));