Socket library
This commit is contained in:
parent
40b364a6db
commit
e1f43abc09
14 changed files with 941 additions and 0 deletions
|
@ -10,6 +10,9 @@ LIBRARY = ../libc.a
|
|||
all: $(LIBRARY)
|
||||
|
||||
OBJECTS = \
|
||||
$(LIBRARY)(accept.o) \
|
||||
$(LIBRARY)(bind.o) \
|
||||
$(LIBRARY)(connect.o) \
|
||||
$(LIBRARY)(dhcp_gettag.o) \
|
||||
$(LIBRARY)(dhcp_settag.o) \
|
||||
$(LIBRARY)(ether_line.o) \
|
||||
|
@ -24,6 +27,7 @@ OBJECTS = \
|
|||
$(LIBRARY)(getnetent.o) \
|
||||
$(LIBRARY)(getnetbyname.o) \
|
||||
$(LIBRARY)(getnetbyaddr.o) \
|
||||
$(LIBRARY)(getpeername.o) \
|
||||
$(LIBRARY)(getproto.o) \
|
||||
$(LIBRARY)(getprotoent.o) \
|
||||
$(LIBRARY)(getservent.o) \
|
||||
|
@ -33,21 +37,38 @@ OBJECTS = \
|
|||
$(LIBRARY)(inet_addr.o) \
|
||||
$(LIBRARY)(inet_network.o) \
|
||||
$(LIBRARY)(inet_ntoa.o) \
|
||||
$(LIBRARY)(listen.o) \
|
||||
$(LIBRARY)(memcspn.o) \
|
||||
$(LIBRARY)(rcmd.o) \
|
||||
$(LIBRARY)(recv.o) \
|
||||
$(LIBRARY)(recvfrom.o) \
|
||||
$(LIBRARY)(res_comp.o) \
|
||||
$(LIBRARY)(res_init.o) \
|
||||
$(LIBRARY)(res_mkquery.o) \
|
||||
$(LIBRARY)(res_query.o) \
|
||||
$(LIBRARY)(res_send.o) \
|
||||
$(LIBRARY)(ruserok.o) \
|
||||
$(LIBRARY)(send.o) \
|
||||
$(LIBRARY)(sendto.o) \
|
||||
$(LIBRARY)(sethostent.o) \
|
||||
$(LIBRARY)(setsockopt.o) \
|
||||
$(LIBRARY)(servxcheck.o) \
|
||||
$(LIBRARY)(socket.o) \
|
||||
$(LIBRARY)(strcasecmp.o) \
|
||||
|
||||
$(LIBRARY): $(OBJECTS)
|
||||
aal cr $@ *.o
|
||||
rm *.o
|
||||
|
||||
$(LIBRARY)(accept.o): accept.c
|
||||
$(CC1) accept.c
|
||||
|
||||
$(LIBRARY)(bind.o): bind.c
|
||||
$(CC1) bind.c
|
||||
|
||||
$(LIBRARY)(connect.o): connect.c
|
||||
$(CC1) connect.c
|
||||
|
||||
$(LIBRARY)(dhcp_gettag.o): dhcp_gettag.c
|
||||
$(CC1) dhcp_gettag.c
|
||||
|
||||
|
@ -90,6 +111,9 @@ $(LIBRARY)(getnetbyname.o): getnetbyname.c
|
|||
$(LIBRARY)(getnetbyaddr.o): getnetbyaddr.c
|
||||
$(CC1) getnetbyaddr.c
|
||||
|
||||
$(LIBRARY)(getpeername.o): getpeername.c
|
||||
$(CC1) getpeername.c
|
||||
|
||||
$(LIBRARY)(getproto.o): getproto.c
|
||||
$(CC1) getproto.c
|
||||
|
||||
|
@ -117,6 +141,9 @@ $(LIBRARY)(inet_network.o): inet_network.c
|
|||
$(LIBRARY)(inet_ntoa.o): inet_ntoa.c
|
||||
$(CC1) inet_ntoa.c
|
||||
|
||||
$(LIBRARY)(listen.o): listen.c
|
||||
$(CC1) listen.c
|
||||
|
||||
$(LIBRARY)(memcspn.o): memcspn.c
|
||||
$(CC1) memcspn.c
|
||||
|
||||
|
@ -126,6 +153,12 @@ $(LIBRARY)(oneC_sum.o): oneC_sum.c
|
|||
$(LIBRARY)(rcmd.o): rcmd.c
|
||||
$(CC1) rcmd.c
|
||||
|
||||
$(LIBRARY)(recv.o): recv.c
|
||||
$(CC1) recv.c
|
||||
|
||||
$(LIBRARY)(recvfrom.o): recvfrom.c
|
||||
$(CC1) recvfrom.c
|
||||
|
||||
$(LIBRARY)(res_comp.o): res_comp.c
|
||||
$(CC1) res_comp.c
|
||||
|
||||
|
@ -144,8 +177,23 @@ $(LIBRARY)(res_send.o): res_send.c
|
|||
$(LIBRARY)(ruserok.o): ruserok.c
|
||||
$(CC1) ruserok.c
|
||||
|
||||
$(LIBRARY)(send.o): send.c
|
||||
$(CC1) send.c
|
||||
|
||||
$(LIBRARY)(sendto.o): sendto.c
|
||||
$(CC1) sendto.c
|
||||
|
||||
$(LIBRARY)(sethostent.o): sethostent.c
|
||||
$(CC1) sethostent.c
|
||||
|
||||
$(LIBRARY)(setsockopt.o): setsockopt.c
|
||||
$(CC1) setsockopt.c
|
||||
|
||||
$(LIBRARY)(servxcheck.o): servxcheck.c
|
||||
$(CC1) servxcheck.c
|
||||
|
||||
$(LIBRARY)(socket.o): socket.c
|
||||
$(CC1) socket.c
|
||||
|
||||
$(LIBRARY)(strcasecmp.o): strcasecmp.c
|
||||
$(CC1) strcasecmp.c
|
||||
|
|
65
lib/ip/accept.c
Normal file
65
lib/ip/accept.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/netlib.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static int _tcp_accept(int socket, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len);
|
||||
|
||||
int accept(int socket, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len)
|
||||
{
|
||||
int r;
|
||||
|
||||
r= _tcp_accept(socket, address, address_len);
|
||||
return r;
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "accept: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _tcp_accept(int socket, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len)
|
||||
{
|
||||
int r, s1, t_errno;
|
||||
tcp_cookie_t cookie;
|
||||
|
||||
s1= open(TCP_DEVICE, O_RDWR);
|
||||
if (s1 == -1)
|
||||
return s1;
|
||||
r= ioctl(s1, NWIOGTCPCOOKIE, &cookie);
|
||||
if (r == -1)
|
||||
{
|
||||
t_errno= errno;
|
||||
close(s1);
|
||||
errno= t_errno;
|
||||
return -1;
|
||||
}
|
||||
r= ioctl(socket, NWIOTCPACCEPTTO, &cookie);
|
||||
if (r == -1)
|
||||
{
|
||||
t_errno= errno;
|
||||
close(s1);
|
||||
errno= t_errno;
|
||||
return -1;
|
||||
}
|
||||
if (address != NULL)
|
||||
getpeername(s1, address, address_len);
|
||||
return s1;
|
||||
}
|
153
lib/ip/bind.c
Normal file
153
lib/ip/bind.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static int _tcp_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len, nwio_tcpconf_t *tcpconfp);
|
||||
static int _udp_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len, nwio_udpopt_t *udpoptp);
|
||||
|
||||
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
int r;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
nwio_udpopt_t udpopt;
|
||||
|
||||
r= ioctl(socket, NWIOGTCPCONF, &tcpconf);
|
||||
if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
|
||||
{
|
||||
if (r == -1)
|
||||
return r;
|
||||
r= _tcp_bind(socket, address, address_len, &tcpconf);
|
||||
#if DEBUG
|
||||
if (r == -1)
|
||||
{
|
||||
int t_errno= errno;
|
||||
fprintf(stderr, "bind(tcp) failed: %s\n",
|
||||
strerror(errno));
|
||||
errno= t_errno;
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
r= ioctl(socket, NWIOGUDPOPT, &udpopt);
|
||||
if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
|
||||
{
|
||||
if (r == -1)
|
||||
return r;
|
||||
return _udp_bind(socket, address, address_len, &udpopt);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "bind: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _tcp_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len, nwio_tcpconf_t *tcpconfp)
|
||||
{
|
||||
int r;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
struct sockaddr_in *sinp;
|
||||
|
||||
sinp= (struct sockaddr_in *)address;
|
||||
if (sinp->sin_family != AF_INET || address_len != sizeof(*sinp))
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "bind(tcp): sin_family = %d, len = %d\n",
|
||||
sinp->sin_family, address_len);
|
||||
#endif
|
||||
errno= EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sinp->sin_addr.s_addr != INADDR_ANY &&
|
||||
sinp->sin_addr.s_addr != tcpconfp->nwtc_locaddr)
|
||||
{
|
||||
errno= EADDRNOTAVAIL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcpconf.nwtc_flags= 0;
|
||||
|
||||
if (sinp->sin_port == 0)
|
||||
tcpconf.nwtc_flags |= NWTC_LP_SEL;
|
||||
else
|
||||
{
|
||||
tcpconf.nwtc_flags |= NWTC_LP_SET;
|
||||
tcpconf.nwtc_locport= sinp->sin_port;
|
||||
}
|
||||
|
||||
r= ioctl(socket, NWIOSTCPCONF, &tcpconf);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _udp_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len, nwio_udpopt_t *udpoptp)
|
||||
{
|
||||
int r;
|
||||
unsigned long curr_flags;
|
||||
nwio_udpopt_t udpopt;
|
||||
struct sockaddr_in *sinp;
|
||||
|
||||
sinp= (struct sockaddr_in *)address;
|
||||
if (sinp->sin_family != AF_INET || address_len != sizeof(*sinp))
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "bind(udp): sin_family = %d, len = %d\n",
|
||||
sinp->sin_family, address_len);
|
||||
#endif
|
||||
errno= EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sinp->sin_addr.s_addr != INADDR_ANY &&
|
||||
sinp->sin_addr.s_addr != udpoptp->nwuo_locaddr)
|
||||
{
|
||||
errno= EADDRNOTAVAIL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
udpopt.nwuo_flags= 0;
|
||||
|
||||
if (sinp->sin_port == 0)
|
||||
udpopt.nwuo_flags |= NWUO_LP_SEL;
|
||||
else
|
||||
{
|
||||
udpopt.nwuo_flags |= NWUO_LP_SET;
|
||||
udpopt.nwuo_locport= sinp->sin_port;
|
||||
}
|
||||
|
||||
curr_flags= udpoptp->nwuo_flags;
|
||||
if (!(curr_flags & NWUO_ACC_MASK))
|
||||
udpopt.nwuo_flags |= NWUO_EXCL;
|
||||
if (!(curr_flags & (NWUO_EN_LOC|NWUO_DI_LOC)))
|
||||
udpopt.nwuo_flags |= NWUO_EN_LOC;
|
||||
if (!(curr_flags & (NWUO_EN_BROAD|NWUO_DI_BROAD)))
|
||||
udpopt.nwuo_flags |= NWUO_EN_BROAD;
|
||||
if (!(curr_flags & (NWUO_RP_SET|NWUO_RP_ANY)))
|
||||
udpopt.nwuo_flags |= NWUO_RP_ANY;
|
||||
if (!(curr_flags & (NWUO_RA_SET|NWUO_RA_ANY)))
|
||||
udpopt.nwuo_flags |= NWUO_RA_ANY;
|
||||
if (!(curr_flags & (NWUO_RWDATONLY|NWUO_RWDATALL)))
|
||||
udpopt.nwuo_flags |= NWUO_RWDATALL;
|
||||
if (!(curr_flags & (NWUO_EN_IPOPT|NWUO_DI_IPOPT)))
|
||||
udpopt.nwuo_flags |= NWUO_DI_IPOPT;
|
||||
|
||||
r= ioctl(socket, NWIOSUDPOPT, &udpopt);
|
||||
return r;
|
||||
}
|
90
lib/ip/connect.c
Normal file
90
lib/ip/connect.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static int _tcp_connect(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len, nwio_tcpconf_t *tcpconfp);
|
||||
|
||||
int connect(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len)
|
||||
{
|
||||
int r;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
|
||||
r= ioctl(socket, NWIOGTCPCONF, &tcpconf);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
return _tcp_connect(socket, address, address_len, &tcpconf);
|
||||
}
|
||||
#if DEBUG
|
||||
fprintf(stderr, "connect: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _tcp_connect(int socket, const struct sockaddr *address,
|
||||
socklen_t address_len, nwio_tcpconf_t *tcpconfp)
|
||||
{
|
||||
int r;
|
||||
struct sockaddr_in *sinp;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
nwio_tcpcl_t tcpcl;
|
||||
|
||||
if (address_len != sizeof(*sinp))
|
||||
{
|
||||
errno= EINVAL;
|
||||
return -1;
|
||||
}
|
||||
sinp= (struct sockaddr_in *)address;
|
||||
if (sinp->sin_family != AF_INET)
|
||||
{
|
||||
errno= EINVAL;
|
||||
return -1;
|
||||
}
|
||||
tcpconf.nwtc_flags= NWTC_SET_RA | NWTC_SET_RP;
|
||||
if ((tcpconfp->nwtc_flags & NWTC_LOCPORT_MASK) == NWTC_LP_UNSET)
|
||||
tcpconf.nwtc_flags |= NWTC_LP_SEL;
|
||||
tcpconf.nwtc_remaddr= sinp->sin_addr.s_addr;
|
||||
tcpconf.nwtc_remport= sinp->sin_port;
|
||||
|
||||
if (ioctl(socket, NWIOSTCPCONF, &tcpconf) == -1)
|
||||
{
|
||||
int t_errno= errno;
|
||||
|
||||
fprintf(stderr, "setconf failed: %s\n", strerror(errno));
|
||||
|
||||
errno= t_errno;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcpcl.nwtcl_flags= 0;
|
||||
|
||||
r= ioctl(socket, NWIOTCPCONN, &tcpcl);
|
||||
if (r == -1)
|
||||
{
|
||||
int t_errno= errno;
|
||||
|
||||
fprintf(stderr, "connect failed: %s\n", strerror(errno));
|
||||
|
||||
errno= t_errno;
|
||||
}
|
||||
return r;
|
||||
}
|
70
lib/ip/getpeername.c
Normal file
70
lib/ip/getpeername.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static int _tcp_getpeername(int socket, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp);
|
||||
|
||||
int getpeername(int socket, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len)
|
||||
{
|
||||
int r;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
|
||||
r= ioctl(socket, NWIOGTCPCONF, &tcpconf);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
return _tcp_getpeername(socket, address, address_len,
|
||||
&tcpconf);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "getpeername: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _tcp_getpeername(int socket, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len, nwio_tcpconf_t *tcpconfp)
|
||||
{
|
||||
socklen_t len;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (((tcpconfp->nwtc_flags & NWTC_REMADDR_MASK) != NWTC_SET_RA) ||
|
||||
((tcpconfp->nwtc_flags & NWTC_REMPORT_MASK) != NWTC_SET_RP))
|
||||
{
|
||||
errno= ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&sin, '\0', sizeof(sin));
|
||||
sin.sin_family= AF_INET;
|
||||
sin.sin_addr.s_addr= tcpconfp->nwtc_remaddr;
|
||||
sin.sin_port= tcpconfp->nwtc_remport;
|
||||
|
||||
len= *address_len;
|
||||
if (len > sizeof(sin))
|
||||
len= sizeof(sin);
|
||||
memcpy(address, &sin, len);
|
||||
*address_len= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8,3 +8,11 @@ hton.c
|
|||
|
||||
u16_t _tmp;
|
||||
u32_t _tmp_l;
|
||||
|
||||
#if _WORD_SIZE > 2
|
||||
u16_t (htons)(u16_t x) { return HTONS(x); }
|
||||
u16_t (ntohs)(u16_t x) { return NTOHS(x); }
|
||||
u32_t (htonl)(u32_t x) { return HTONL(x); }
|
||||
u32_t (ntohl)(u32_t x) { return NTOHL(x); }
|
||||
#endif
|
||||
|
||||
|
|
30
lib/ip/listen.c
Normal file
30
lib/ip/listen.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
int listen(int socket, int backlog)
|
||||
{
|
||||
int r;
|
||||
|
||||
r= ioctl(socket, NWIOTCPLISTENQ, &backlog);
|
||||
if (r != -1 || errno != EBADIOCTL)
|
||||
return r;
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "listen: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
8
lib/ip/recv.c
Normal file
8
lib/ip/recv.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t recv(int socket, void *buffer, size_t length, int flags)
|
||||
{
|
||||
return recvfrom(socket, buffer, length, flags, NULL, NULL);
|
||||
}
|
||||
|
120
lib/ip/recvfrom.c
Normal file
120
lib/ip/recvfrom.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_hdr.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static ssize_t _udp_recvfrom(int socket, void *_RESTRICT buffer, size_t length,
|
||||
int flags, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len, nwio_udpopt_t *udpoptp);
|
||||
|
||||
ssize_t recvfrom(int socket, void *_RESTRICT buffer, size_t length,
|
||||
int flags, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len)
|
||||
{
|
||||
int r;
|
||||
nwio_udpopt_t udpopt;
|
||||
|
||||
fprintf(stderr, "recvfrom: for fd %d\n", socket);
|
||||
|
||||
r= ioctl(socket, NWIOGUDPOPT, &udpopt);
|
||||
if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
|
||||
{
|
||||
if (r == -1)
|
||||
return r;
|
||||
return _udp_recvfrom(socket, buffer, length, flags,
|
||||
address, address_len, &udpopt);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "recvfrom: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t _udp_recvfrom(int socket, void *_RESTRICT buffer, size_t length,
|
||||
int flags, struct sockaddr *_RESTRICT address,
|
||||
socklen_t *_RESTRICT address_len, nwio_udpopt_t *udpoptp)
|
||||
{
|
||||
int r, t_errno;
|
||||
size_t buflen, len;
|
||||
void *buf;
|
||||
struct sockaddr_in *sinp;
|
||||
udp_io_hdr_t *io_hdrp;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (flags)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "recvfrom(udp): flags not implemented\n");
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr,
|
||||
"recvfrom(udp): NWUO_RWDATONLY not implemented\n");
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buflen= sizeof(*io_hdrp) + length;
|
||||
if (buflen < length)
|
||||
{
|
||||
/* Overflow */
|
||||
errno= EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
buf= malloc(buflen);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
r= read(socket, buf, buflen);
|
||||
if (r == -1)
|
||||
{
|
||||
t_errno= errno;
|
||||
free(buf);
|
||||
errno= t_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(r >= sizeof(*io_hdrp));
|
||||
length= r-sizeof(*io_hdrp);
|
||||
|
||||
io_hdrp= buf;
|
||||
memcpy(buffer, &io_hdrp[1], length);
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
sin.sin_family= AF_INET;
|
||||
sin.sin_addr.s_addr= io_hdrp->uih_src_addr;
|
||||
sin.sin_port= io_hdrp->uih_src_port;
|
||||
len= *address_len;
|
||||
if (len > sizeof(sin))
|
||||
len= sizeof(sin);
|
||||
memcpy(address, &sin, len);
|
||||
*address_len= sizeof(sin);
|
||||
}
|
||||
free(buf);
|
||||
return length;
|
||||
}
|
||||
|
11
lib/ip/send.c
Normal file
11
lib/ip/send.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t send(int socket, const void *buffer, size_t length, int flags)
|
||||
{
|
||||
struct sockaddr sa;
|
||||
|
||||
sa.sa_family= AF_UNSPEC;
|
||||
return sendto(socket, buffer, length, flags, &sa, sizeof(sa));
|
||||
}
|
||||
|
123
lib/ip/sendto.c
Normal file
123
lib/ip/sendto.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_hdr.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static ssize_t _udp_sendto(int socket, const void *message, size_t length,
|
||||
int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
|
||||
nwio_udpopt_t *udpoptp);
|
||||
|
||||
ssize_t sendto(int socket, const void *message, size_t length, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t dest_len)
|
||||
{
|
||||
int r;
|
||||
nwio_udpopt_t udpopt;
|
||||
|
||||
r= ioctl(socket, NWIOGUDPOPT, &udpopt);
|
||||
if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
|
||||
{
|
||||
if (r == -1)
|
||||
return r;
|
||||
return _udp_sendto(socket, message, length, flags,
|
||||
dest_addr, dest_len, &udpopt);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "sendto: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t _udp_sendto(int socket, const void *message, size_t length,
|
||||
int flags, const struct sockaddr *dest_addr, socklen_t dest_len,
|
||||
nwio_udpopt_t *udpoptp)
|
||||
{
|
||||
int r, t_errno;
|
||||
size_t buflen;
|
||||
void *buf;
|
||||
struct sockaddr_in *sinp;
|
||||
udp_io_hdr_t *io_hdrp;
|
||||
|
||||
if (flags)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "sendto(udp): flags not implemented\n");
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (udpoptp->nwuo_flags & NWUO_RWDATONLY)
|
||||
return write(socket, message, length);
|
||||
|
||||
if ((udpoptp->nwuo_flags & NWUO_RP_ANY) ||
|
||||
(udpoptp->nwuo_flags & NWUO_RA_ANY))
|
||||
{
|
||||
/* Check destination address */
|
||||
if (dest_len < sizeof(*sinp))
|
||||
{
|
||||
errno= EINVAL;
|
||||
return -1;
|
||||
}
|
||||
sinp= (struct sockaddr_in *)dest_addr;
|
||||
if (sinp->sin_family != AF_INET)
|
||||
{
|
||||
errno= EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
buflen= sizeof(*io_hdrp) + length;
|
||||
if (buflen < length)
|
||||
{
|
||||
/* Overflow */
|
||||
errno= EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
buf= malloc(buflen);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
io_hdrp= buf;
|
||||
io_hdrp->uih_src_addr= 0; /* Unused */
|
||||
io_hdrp->uih_src_port= 0; /* Will cause error if NWUO_LP_ANY */
|
||||
if (udpoptp->nwuo_flags & NWUO_RA_ANY)
|
||||
io_hdrp->uih_dst_addr= sinp->sin_addr.s_addr;
|
||||
else
|
||||
io_hdrp->uih_dst_addr= 0;
|
||||
if (udpoptp->nwuo_flags & NWUO_RP_ANY)
|
||||
io_hdrp->uih_dst_port= sinp->sin_port;
|
||||
else
|
||||
io_hdrp->uih_dst_port= 0;
|
||||
io_hdrp->uih_ip_opt_len= 0;
|
||||
io_hdrp->uih_data_len= 0;
|
||||
|
||||
memcpy(&io_hdrp[1], message, length);
|
||||
r= write(socket, buf, buflen);
|
||||
if (r == -1)
|
||||
{
|
||||
t_errno= errno;
|
||||
free(buf);
|
||||
errno= t_errno;
|
||||
return -1;
|
||||
}
|
||||
assert(r == buflen);
|
||||
free(buf);
|
||||
return length;
|
||||
}
|
||||
|
79
lib/ip/sethostent.c
Normal file
79
lib/ip/sethostent.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* $OpenBSD: sethostent.c,v 1.1 1997/03/12 10:42:11 downsj Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$From: sethostent.c,v 8.5 1996/09/28 06:51:07 vixie Exp $";
|
||||
#else
|
||||
static char rcsid[] = "$OpenBSD: sethostent.c,v 1.1 1997/03/12 10:42:11 downsj Exp $";
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef notyet
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/resolv.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
sethostent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return;
|
||||
if (stayopen)
|
||||
_res.options |= RES_STAYOPEN | RES_USEVC;
|
||||
}
|
||||
|
||||
void
|
||||
endhostent()
|
||||
{
|
||||
_res.options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
_res_close();
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: sethostent.c,v 1.2 2000/04/01 18:27:16 philip Exp $
|
||||
*/
|
70
lib/ip/setsockopt.c
Normal file
70
lib/ip/setsockopt.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static int _tcp_setsockopt(int socket, int level, int option_name,
|
||||
const void *option_value, socklen_t option_len);
|
||||
|
||||
int setsockopt(int socket, int level, int option_name,
|
||||
const void *option_value, socklen_t option_len)
|
||||
{
|
||||
int r;
|
||||
nwio_tcpopt_t tcpopt;
|
||||
|
||||
r= ioctl(socket, NWIOGTCPOPT, &tcpopt);
|
||||
if (r != -1 || errno != ENOTTY)
|
||||
{
|
||||
if (r == -1)
|
||||
{
|
||||
/* Bad file descriptor */
|
||||
return -1;
|
||||
}
|
||||
return _tcp_setsockopt(socket, level, option_name,
|
||||
option_value, option_len);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "setsockopt: not implemented for fd %d\n", socket);
|
||||
#endif
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _tcp_setsockopt(int socket, int level, int option_name,
|
||||
const void *option_value, socklen_t option_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (level == SOL_SOCKET && option_name == SO_KEEPALIVE)
|
||||
{
|
||||
if (option_len != sizeof(i))
|
||||
{
|
||||
errno= EINVAL;
|
||||
return -1;
|
||||
}
|
||||
i= *(int *)option_value;
|
||||
if (!i)
|
||||
{
|
||||
/* At the moment there is no way to turn off
|
||||
* keepalives.
|
||||
*/
|
||||
errno= ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "_tcp_setsocketopt: level %d, name %d\n",
|
||||
level, option_name);
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
66
lib/ip/socket.c
Normal file
66
lib/ip/socket.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/netlib.h>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
static int _tcp_socket(int protocol);
|
||||
static int _udp_socket(int protocol);
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
if (domain != AF_INET)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "socket: bad domain %d\n", domain);
|
||||
#endif
|
||||
errno= EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if (type == SOCK_STREAM)
|
||||
return _tcp_socket(protocol);
|
||||
|
||||
if (type == SOCK_DGRAM)
|
||||
return _udp_socket(protocol);
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "socket: nothing for domain %d, type %d, protocol %d\n",
|
||||
domain, type, protocol);
|
||||
#endif
|
||||
errno= EPROTOTYPE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _tcp_socket(int protocol)
|
||||
{
|
||||
int fd;
|
||||
if (protocol != 0)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "socket(tcp): bad protocol %d\n", protocol);
|
||||
#endif
|
||||
errno= EPROTONOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
fd= open(TCP_DEVICE, O_RDWR);
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int _udp_socket(int protocol)
|
||||
{
|
||||
int fd;
|
||||
if (protocol != 0)
|
||||
{
|
||||
#if DEBUG
|
||||
fprintf(stderr, "socket(udp): bad protocol %d\n", protocol);
|
||||
#endif
|
||||
errno= EPROTONOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
fd= open(UDP_DEVICE, O_RDWR);
|
||||
return fd;
|
||||
}
|
||||
|
Loading…
Reference in a new issue