10 #include <sys/socket.h>
11 #include <netinet/in.h>
13 #include <net/gen/in.h>
14 #include <net/gen/tcp.h>
15 #include <net/gen/tcp_io.h>
16 #include <net/gen/udp.h>
17 #include <net/gen/udp_hdr.h>
18 #include <net/gen/udp_io.h>
22 static ssize_t
_tcp_recvfrom(int socket
, void *_RESTRICT buffer
, size_t length
,
23 int flags
, struct sockaddr
*_RESTRICT address
,
24 socklen_t
*_RESTRICT address_len
, nwio_tcpconf_t
*tcpconfp
);
25 static ssize_t
_udp_recvfrom(int socket
, void *_RESTRICT buffer
, size_t length
,
26 int flags
, struct sockaddr
*_RESTRICT address
,
27 socklen_t
*_RESTRICT address_len
, nwio_udpopt_t
*udpoptp
);
29 ssize_t
recvfrom(int socket
, void *_RESTRICT buffer
, size_t length
,
30 int flags
, struct sockaddr
*_RESTRICT address
,
31 socklen_t
*_RESTRICT address_len
)
34 nwio_tcpconf_t tcpconf
;
38 fprintf(stderr
, "recvfrom: for fd %d\n", socket
);
41 r
= ioctl(socket
, NWIOGTCPCONF
, &tcpconf
);
42 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
46 return _tcp_recvfrom(socket
, buffer
, length
, flags
,
47 address
, address_len
, &tcpconf
);
50 r
= ioctl(socket
, NWIOGUDPOPT
, &udpopt
);
51 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
55 return _udp_recvfrom(socket
, buffer
, length
, flags
,
56 address
, address_len
, &udpopt
);
60 fprintf(stderr
, "recvfrom: not implemented for fd %d\n", socket
);
67 static ssize_t
_tcp_recvfrom(int socket
, void *_RESTRICT buffer
, size_t length
,
68 int flags
, struct sockaddr
*_RESTRICT address
,
69 socklen_t
*_RESTRICT address_len
, nwio_tcpconf_t
*tcpconfp
)
73 struct sockaddr_in sin
;
78 fprintf(stderr
, "recvfrom(tcp): flags not implemented\n");
84 r
= read(socket
, buffer
, length
);
86 if (r
>= 0 && address
!= NULL
)
88 sin
.sin_family
= AF_INET
;
89 sin
.sin_addr
.s_addr
= tcpconfp
->nwtc_remaddr
;
90 sin
.sin_port
= tcpconfp
->nwtc_remport
;
92 if (len
> sizeof(sin
))
94 memcpy(address
, &sin
, len
);
95 *address_len
= sizeof(sin
);
101 static ssize_t
_udp_recvfrom(int socket
, void *_RESTRICT buffer
, size_t length
,
102 int flags
, struct sockaddr
*_RESTRICT address
,
103 socklen_t
*_RESTRICT address_len
, nwio_udpopt_t
*udpoptp
)
108 udp_io_hdr_t
*io_hdrp
;
109 struct sockaddr_in sin
;
114 fprintf(stderr
, "recvfrom(udp): flags not implemented\n");
120 if (udpoptp
->nwuo_flags
& NWUO_RWDATONLY
)
122 if (address
!= NULL
&&
123 (udpoptp
->nwuo_flags
& (NWUO_RA_SET
| NWUO_RP_SET
)) !=
124 (NWUO_RA_SET
| NWUO_RP_SET
))
129 "recvfrom(udp): RWDATONLY on unconnected socket\n");
135 r
= read(socket
, buffer
, length
);
141 sin
.sin_family
= AF_INET
;
142 sin
.sin_addr
.s_addr
= udpoptp
->nwuo_remaddr
;
143 sin
.sin_port
= udpoptp
->nwuo_remport
;
145 if (len
> sizeof(sin
))
147 memcpy(address
, &sin
, len
);
148 *address_len
= sizeof(sin
);
154 buflen
= sizeof(*io_hdrp
) + length
;
165 r
= read(socket
, buf
, buflen
);
170 fprintf(stderr
, "recvfrom(udp): read failed: %s\n",
172 fprintf(stderr
, "udp opt flags = 0x%x\n", udpoptp
->nwuo_flags
);
179 assert(r
>= sizeof(*io_hdrp
));
180 length
= r
-sizeof(*io_hdrp
);
183 memcpy(buffer
, &io_hdrp
[1], length
);
187 sin
.sin_family
= AF_INET
;
188 sin
.sin_addr
.s_addr
= io_hdrp
->uih_src_addr
;
189 sin
.sin_port
= io_hdrp
->uih_src_port
;
191 if (len
> sizeof(sin
))
193 memcpy(address
, &sin
, len
);
194 *address_len
= sizeof(sin
);