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
)
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
)
57 /* Bad file descriptor */
60 return _udp_connect(sock
, address
, address_len
, &udpopt
);
63 r
= _uds_connect(sock
, address
, address_len
);
64 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EAFNOSUPPORT
))
68 /* Bad file descriptor */
76 fprintf(stderr
, "connect: not implemented for fd %d\n", sock
);
82 static int _tcp_connect(int sock
, const struct sockaddr
*address
,
83 socklen_t address_len
, nwio_tcpconf_t
*tcpconfp
)
86 struct sockaddr_in
*sinp
;
87 nwio_tcpconf_t tcpconf
;
90 if (address_len
!= sizeof(*sinp
))
95 sinp
= (struct sockaddr_in
*) __UNCONST(address
);
96 if (sinp
->sin_family
!= AF_INET
)
101 tcpconf
.nwtc_flags
= NWTC_SET_RA
| NWTC_SET_RP
;
102 if ((tcpconfp
->nwtc_flags
& NWTC_LOCPORT_MASK
) == NWTC_LP_UNSET
)
103 tcpconf
.nwtc_flags
|= NWTC_LP_SEL
;
104 tcpconf
.nwtc_remaddr
= sinp
->sin_addr
.s_addr
;
105 tcpconf
.nwtc_remport
= sinp
->sin_port
;
107 if (ioctl(sock
, NWIOSTCPCONF
, &tcpconf
) == -1)
109 /* Ignore EISCONN error. The NWIOTCPCONN ioctl will get the
112 if (errno
!= EISCONN
)
116 tcpcl
.nwtcl_flags
= TCF_DEFAULT
;
118 r
= fcntl(sock
, F_GETFL
);
122 tcpcl
.nwtcl_flags
|= TCF_ASYNCH
;
124 r
= ioctl(sock
, NWIOTCPCONN
, &tcpcl
);
128 static int _udp_connect(int sock
, const struct sockaddr
*address
,
129 socklen_t address_len
, nwio_udpopt_t
*udpoptp
)
132 struct sockaddr_in
*sinp
;
133 nwio_udpopt_t udpopt
;
137 /* Unset remote address */
138 udpopt
.nwuo_flags
= NWUO_RP_ANY
| NWUO_RA_ANY
| NWUO_RWDATALL
;
140 r
= ioctl(sock
, NWIOSUDPOPT
, &udpopt
);
144 if (address_len
!= sizeof(*sinp
))
149 sinp
= (struct sockaddr_in
*) __UNCONST(address
);
150 if (sinp
->sin_family
!= AF_INET
)
155 udpopt
.nwuo_flags
= NWUO_RP_SET
| NWUO_RA_SET
| NWUO_RWDATONLY
;
156 if ((udpoptp
->nwuo_flags
& NWUO_LOCPORT_MASK
) == NWUO_LP_ANY
)
157 udpopt
.nwuo_flags
|= NWUO_LP_SEL
;
158 udpopt
.nwuo_remaddr
= sinp
->sin_addr
.s_addr
;
159 udpopt
.nwuo_remport
= sinp
->sin_port
;
161 r
= ioctl(sock
, NWIOSUDPOPT
, &udpopt
);
165 static int _uds_connect(int sock
, const struct sockaddr
*address
,
166 socklen_t address_len
)
169 if (address
== NULL
) {
174 /* perform the connect */
175 return ioctl(sock
, NWIOSUDSCONN
, (void *) __UNCONST(address
));