12 #include <sys/ioctl.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
16 #include <net/gen/in.h>
17 #include <net/gen/tcp.h>
18 #include <net/gen/tcp_io.h>
19 #include <net/gen/udp.h>
20 #include <net/gen/udp_hdr.h>
21 #include <net/gen/udp_io.h>
25 static ssize_t
_tcp_sendto(int sock
, const void *message
, size_t length
,
26 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
);
27 static ssize_t
_udp_sendto(int sock
, const void *message
, size_t length
,
28 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
,
29 nwio_udpopt_t
*udpoptp
);
30 static ssize_t
_uds_sendto_conn(int sock
, const void *message
, size_t length
,
31 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
);
32 static ssize_t
_uds_sendto_dgram(int sock
, const void *message
, size_t length
,
33 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
);
35 ssize_t
sendto(int sock
, const void *message
, size_t length
, int flags
,
36 const struct sockaddr
*dest_addr
, socklen_t dest_len
)
43 r
= ioctl(sock
, NWIOGTCPOPT
, &tcpopt
);
44 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
48 return _tcp_sendto(sock
, message
, length
, flags
,
52 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
53 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
57 return _udp_sendto(sock
, message
, length
, flags
,
58 dest_addr
, dest_len
, &udpopt
);
61 r
= ioctl(sock
, NWIOGUDSSOTYPE
, &uds_sotype
);
62 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
68 if (uds_sotype
== SOCK_DGRAM
) {
70 return _uds_sendto_dgram(sock
, message
,
71 length
, flags
,dest_addr
, dest_len
);
74 return _uds_sendto_conn(sock
, message
,
75 length
, flags
, dest_addr
, dest_len
);
80 fprintf(stderr
, "sendto: not implemented for fd %d\n", sock
);
86 static ssize_t
_tcp_sendto(int sock
, const void *message
, size_t length
,
87 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
)
92 fprintf(stderr
, "sendto(tcp): flags not implemented\n");
98 /* Silently ignore destination, if given. */
100 return write(sock
, message
, length
);
103 static ssize_t
_udp_sendto(int sock
, const void *message
, size_t length
,
104 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
,
105 nwio_udpopt_t
*udpoptp
)
110 struct sockaddr_in
*sinp
;
111 udp_io_hdr_t
*io_hdrp
;
116 fprintf(stderr
, "sendto(udp): flags not implemented\n");
122 if (udpoptp
->nwuo_flags
& NWUO_RWDATONLY
)
123 return write(sock
, message
, length
);
125 if ((udpoptp
->nwuo_flags
& NWUO_RP_ANY
) ||
126 (udpoptp
->nwuo_flags
& NWUO_RA_ANY
))
134 /* Check destination address */
135 if (dest_len
< sizeof(*sinp
))
140 sinp
= (struct sockaddr_in
*) __UNCONST(dest_addr
);
141 if (sinp
->sin_family
!= AF_INET
)
148 buflen
= sizeof(*io_hdrp
) + length
;
160 io_hdrp
->uih_src_addr
= 0; /* Unused */
161 io_hdrp
->uih_src_port
= 0; /* Will cause error if NWUO_LP_ANY */
162 if (udpoptp
->nwuo_flags
& NWUO_RA_ANY
)
163 io_hdrp
->uih_dst_addr
= sinp
->sin_addr
.s_addr
;
165 io_hdrp
->uih_dst_addr
= 0;
166 if (udpoptp
->nwuo_flags
& NWUO_RP_ANY
)
167 io_hdrp
->uih_dst_port
= sinp
->sin_port
;
169 io_hdrp
->uih_dst_port
= 0;
170 io_hdrp
->uih_ip_opt_len
= 0;
171 io_hdrp
->uih_data_len
= 0;
173 memcpy(&io_hdrp
[1], message
, length
);
174 r
= write(sock
, buf
, buflen
);
187 static ssize_t
_uds_sendto_conn(int sock
, const void *message
, size_t length
,
188 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
)
191 /* for connection oriented unix domain sockets (SOCK_STREAM /
197 fprintf(stderr
, "sendto(uds): flags not implemented\n");
203 /* Silently ignore destination, if given. */
205 return write(sock
, message
, length
);
208 static ssize_t
_uds_sendto_dgram(int sock
, const void *message
, size_t length
,
209 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
)
213 /* for connectionless unix domain sockets (SOCK_DGRAM) */
217 fprintf(stderr
, "sendto(uds): flags not implemented\n");
223 if (dest_addr
== NULL
) {
228 /* set the target address */
229 r
= ioctl(sock
, NWIOSUDSTADDR
, (void *) __UNCONST(dest_addr
));
235 return write(sock
, message
, length
);