From e1f43abc090841327c69e2b5f7a2873fee0ea958 Mon Sep 17 00:00:00 2001 From: Philip Homburg Date: Wed, 27 Jul 2005 11:57:59 +0000 Subject: [PATCH] Socket library --- lib/ip/Makefile | 48 ++++++++++++++ lib/ip/accept.c | 65 ++++++++++++++++++ lib/ip/bind.c | 153 +++++++++++++++++++++++++++++++++++++++++++ lib/ip/connect.c | 90 +++++++++++++++++++++++++ lib/ip/getpeername.c | 70 ++++++++++++++++++++ lib/ip/hton.c | 8 +++ lib/ip/listen.c | 30 +++++++++ lib/ip/recv.c | 8 +++ lib/ip/recvfrom.c | 120 +++++++++++++++++++++++++++++++++ lib/ip/send.c | 11 ++++ lib/ip/sendto.c | 123 ++++++++++++++++++++++++++++++++++ lib/ip/sethostent.c | 79 ++++++++++++++++++++++ lib/ip/setsockopt.c | 70 ++++++++++++++++++++ lib/ip/socket.c | 66 +++++++++++++++++++ 14 files changed, 941 insertions(+) create mode 100644 lib/ip/accept.c create mode 100644 lib/ip/bind.c create mode 100644 lib/ip/connect.c create mode 100644 lib/ip/getpeername.c create mode 100644 lib/ip/listen.c create mode 100644 lib/ip/recv.c create mode 100644 lib/ip/recvfrom.c create mode 100644 lib/ip/send.c create mode 100644 lib/ip/sendto.c create mode 100644 lib/ip/sethostent.c create mode 100644 lib/ip/setsockopt.c create mode 100644 lib/ip/socket.c diff --git a/lib/ip/Makefile b/lib/ip/Makefile index 4d309d305..fed1b163a 100755 --- a/lib/ip/Makefile +++ b/lib/ip/Makefile @@ -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 diff --git a/lib/ip/accept.c b/lib/ip/accept.c new file mode 100644 index 000000000..28a543b7b --- /dev/null +++ b/lib/ip/accept.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/ip/bind.c b/lib/ip/bind.c new file mode 100644 index 000000000..f84e2be73 --- /dev/null +++ b/lib/ip/bind.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/ip/connect.c b/lib/ip/connect.c new file mode 100644 index 000000000..295bb8c95 --- /dev/null +++ b/lib/ip/connect.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} diff --git a/lib/ip/getpeername.c b/lib/ip/getpeername.c new file mode 100644 index 000000000..3d5d826d0 --- /dev/null +++ b/lib/ip/getpeername.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} + diff --git a/lib/ip/hton.c b/lib/ip/hton.c index 69e3dbd57..4f93f591a 100755 --- a/lib/ip/hton.c +++ b/lib/ip/hton.c @@ -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 + diff --git a/lib/ip/listen.c b/lib/ip/listen.c new file mode 100644 index 000000000..d2283e52e --- /dev/null +++ b/lib/ip/listen.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} + diff --git a/lib/ip/recv.c b/lib/ip/recv.c new file mode 100644 index 000000000..6806ef2b2 --- /dev/null +++ b/lib/ip/recv.c @@ -0,0 +1,8 @@ +#include +#include + +ssize_t recv(int socket, void *buffer, size_t length, int flags) +{ + return recvfrom(socket, buffer, length, flags, NULL, NULL); +} + diff --git a/lib/ip/recvfrom.c b/lib/ip/recvfrom.c new file mode 100644 index 000000000..ee09f837f --- /dev/null +++ b/lib/ip/recvfrom.c @@ -0,0 +1,120 @@ +#undef NDEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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; +} + diff --git a/lib/ip/send.c b/lib/ip/send.c new file mode 100644 index 000000000..27ea0d012 --- /dev/null +++ b/lib/ip/send.c @@ -0,0 +1,11 @@ +#include +#include + +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)); +} + diff --git a/lib/ip/sendto.c b/lib/ip/sendto.c new file mode 100644 index 000000000..1646cf486 --- /dev/null +++ b/lib/ip/sendto.c @@ -0,0 +1,123 @@ +#undef NDEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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; +} + diff --git a/lib/ip/sethostent.c b/lib/ip/sethostent.c new file mode 100644 index 000000000..d0b641607 --- /dev/null +++ b/lib/ip/sethostent.c @@ -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 +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#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 $ + */ diff --git a/lib/ip/setsockopt.c b/lib/ip/setsockopt.c new file mode 100644 index 000000000..f6ddff06d --- /dev/null +++ b/lib/ip/setsockopt.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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); +} + diff --git a/lib/ip/socket.c b/lib/ip/socket.c new file mode 100644 index 000000000..95a7fd0eb --- /dev/null +++ b/lib/ip/socket.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include + +#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; +} +