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/ip_hdr.h>
18 #include <net/gen/icmp_hdr.h>
19 #include <net/gen/tcp.h>
20 #include <net/gen/tcp_io.h>
21 #include <net/gen/udp.h>
22 #include <net/gen/udp_hdr.h>
23 #include <net/gen/udp_io.h>
27 static ssize_t
_tcp_sendto(int sock
, const void *message
, size_t length
,
28 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
);
29 static ssize_t
_udp_sendto(int sock
, const void *message
, size_t length
,
30 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
,
31 nwio_udpopt_t
*udpoptp
);
32 static ssize_t
_uds_sendto_conn(int sock
, const void *message
, size_t length
,
33 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
);
34 static ssize_t
_uds_sendto_dgram(int sock
, const void *message
, size_t length
,
35 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
);
37 ssize_t
sendto(int sock
, const void *message
, size_t length
, int flags
,
38 const struct sockaddr
*dest_addr
, socklen_t dest_len
)
45 r
= ioctl(sock
, NWIOGTCPOPT
, &tcpopt
);
46 if (r
!= -1 || errno
!= ENOTTY
)
50 return _tcp_sendto(sock
, message
, length
, flags
,
54 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
55 if (r
!= -1 || errno
!= ENOTTY
)
59 return _udp_sendto(sock
, message
, length
, flags
,
60 dest_addr
, dest_len
, &udpopt
);
63 r
= ioctl(sock
, NWIOGUDSSOTYPE
, &uds_sotype
);
64 if (r
!= -1 || errno
!= ENOTTY
)
70 if (uds_sotype
== SOCK_DGRAM
) {
72 return _uds_sendto_dgram(sock
, message
,
73 length
, flags
,dest_addr
, dest_len
);
76 return _uds_sendto_conn(sock
, message
,
77 length
, flags
, dest_addr
, dest_len
);
85 struct sockaddr_in
*sinp
;
87 sinp
= (struct sockaddr_in
*) __UNCONST(dest_addr
);
88 if (sinp
->sin_family
!= AF_INET
)
95 ip_hdr
= (ip_hdr_t
*)message
;
96 ip_hdr
->ih_dst
= sinp
->sin_addr
.s_addr
;
98 return write(sock
, message
, length
);
102 fprintf(stderr
, "sendto: not implemented for fd %d\n", sock
);
108 static ssize_t
_tcp_sendto(int sock
, const void *message
, size_t length
,
109 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
)
114 fprintf(stderr
, "sendto(tcp): flags not implemented\n");
120 /* Silently ignore destination, if given. */
122 return write(sock
, message
, length
);
125 static ssize_t
_udp_sendto(int sock
, const void *message
, size_t length
,
126 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
,
127 nwio_udpopt_t
*udpoptp
)
132 struct sockaddr_in
*sinp
;
133 udp_io_hdr_t
*io_hdrp
;
138 fprintf(stderr
, "sendto(udp): flags not implemented\n");
144 if (udpoptp
->nwuo_flags
& NWUO_RWDATONLY
)
145 return write(sock
, message
, length
);
147 if ((udpoptp
->nwuo_flags
& NWUO_RP_ANY
) ||
148 (udpoptp
->nwuo_flags
& NWUO_RA_ANY
))
156 /* Check destination address */
157 if (dest_len
< sizeof(*sinp
))
162 sinp
= (struct sockaddr_in
*) __UNCONST(dest_addr
);
163 if (sinp
->sin_family
!= AF_INET
)
170 buflen
= sizeof(*io_hdrp
) + length
;
182 io_hdrp
->uih_src_addr
= 0; /* Unused */
183 io_hdrp
->uih_src_port
= 0; /* Will cause error if NWUO_LP_ANY */
184 if (udpoptp
->nwuo_flags
& NWUO_RA_ANY
)
185 io_hdrp
->uih_dst_addr
= sinp
->sin_addr
.s_addr
;
187 io_hdrp
->uih_dst_addr
= 0;
188 if (udpoptp
->nwuo_flags
& NWUO_RP_ANY
)
189 io_hdrp
->uih_dst_port
= sinp
->sin_port
;
191 io_hdrp
->uih_dst_port
= 0;
192 io_hdrp
->uih_ip_opt_len
= 0;
193 io_hdrp
->uih_data_len
= 0;
195 memcpy(&io_hdrp
[1], message
, length
);
196 r
= write(sock
, buf
, buflen
);
209 static ssize_t
_uds_sendto_conn(int sock
, const void *message
, size_t length
,
210 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
)
213 /* for connection oriented unix domain sockets (SOCK_STREAM /
219 fprintf(stderr
, "sendto(uds): flags not implemented\n");
225 /* Silently ignore destination, if given. */
227 return write(sock
, message
, length
);
230 static ssize_t
_uds_sendto_dgram(int sock
, const void *message
, size_t length
,
231 int flags
, const struct sockaddr
*dest_addr
, socklen_t dest_len
)
235 /* for connectionless unix domain sockets (SOCK_DGRAM) */
239 fprintf(stderr
, "sendto(uds): flags not implemented\n");
245 if (dest_addr
== NULL
) {
250 /* set the target address */
251 r
= ioctl(sock
, NWIOSUDSTADDR
, (void *) __UNCONST(dest_addr
));
257 return write(sock
, message
, length
);