|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 11205 (0x2bc5) Types: TextFile Names: »internet.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/compat/internet.c«
/* internet.c - TCP/IP abstractions */ #ifndef lint static char *rcsid = "$Header: /f/osi/compat/RCS/internet.c,v 6.0 89/03/18 23:25:10 mrose Rel $"; #endif /* * $Header: /f/osi/compat/RCS/internet.c,v 6.0 89/03/18 23:25:10 mrose Rel $ * * * $Log: internet.c,v $ * Revision 6.0 89/03/18 23:25:10 mrose * Release 5.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ /* LINTLIBRARY */ #include <ctype.h> #include <errno.h> #include <stdio.h> #include "general.h" #include "manifest.h" #include "tailor.h" /* \f */ #ifdef TCP #include "internet.h" extern int errno; /* \f Berkeley UNIX: 4.2 */ #ifdef SOCKETS /* For real networking, nothing is better than 4BSD! */ int start_tcp_client (sock, priv) struct sockaddr_in *sock; int priv; { register int port; int eindex, sd; if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) { SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket")); return NOTOK; } if (sock == NULL) return sd; for (port = IPPORT_RESERVED - priv;; priv ? port-- : port++) { sock -> sin_port = htons ((u_short) port); if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK) return sd; switch (errno) { case EADDRINUSE: if (!priv || (port >= IPPORT_RESERVED / 2)) continue; /* else fall */ case EADDRNOTAVAIL: default: eindex = errno; SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind")); (void) close_tcp_socket (sd); errno = eindex; return NOTOK; } } } /* \f */ int start_tcp_server (sock, backlog, opt1, opt2) struct sockaddr_in *sock; int backlog, opt1, opt2; { register int port; int eindex, sd; if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) { SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket")); return NOTOK; } if (sock -> sin_port != 0) { if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK) goto got_socket; eindex = errno; SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind")); (void) close_tcp_socket (sd); errno = eindex; return NOTOK; } for (port = IPPORT_RESERVED;; port++) { sock -> sin_port = htons ((u_short) port); if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK) break; switch (errno) { case EADDRINUSE: continue; case EADDRNOTAVAIL: default: eindex = errno; SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind")); (void) close_tcp_socket (sd); errno = eindex; return NOTOK; } } got_socket: ; if (opt1) (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0); if (opt2) (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0); (void) listen (sd, backlog); return sd; } /* \f */ int join_tcp_client (fd, sock) int fd; struct sockaddr_in *sock; { int eindex, len = sizeof *sock, result; if ((result = accept (fd, (struct sockaddr *) sock, &len)) == NOTOK) { eindex = errno; SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("accept")); errno = eindex; } return result; } /* \f */ int join_tcp_server (fd, sock) int fd; struct sockaddr_in *sock; { int eindex, result; if ((result = connect (fd, (struct sockaddr *) sock, sizeof *sock)) == NOTOK) { eindex = errno; SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("connect")); errno = eindex; } return result; } #endif /* \f AT&T UNIX: 5r3 using TLI */ /* \f AT&T UNIX: 5 with EXOS 8044 TCP/IP card */ #ifdef EXOS /* If we had a getsockname() for the EXOS card, then we could postpone some of the binding until connect time. But since we don't, our hand is forced and we must prematurely bind the sockets to IP addresses. */ start_tcp_client (sock, priv) struct sockaddr_in *sock; int priv; { register int port; int sd; register struct hostent *hp; if (sock == NULL) return socket (SOCK_STREAM, 0, (struct sockaddr *) 0, 0); if (sock -> sin_addr.s_addr == 0) { if ((hp = gethostbyname ("localhost")) == NULL) { errno = EADDRNOTAVAIL; return NOTOK; } sock -> sin_family = hp -> h_addrtype; inaddr_copy (hp, sock); } for (port = IPPORT_RESERVED - priv;; priv ? port-- : port++) { sock -> sin_port = htons ((u_short) port); if ((sd = socket (SOCK_STREAM, 0, (struct sockaddr *) sock, 0)) != NOTOK) return sd; switch (errno) { case EADDRINUSE: if (!priv || (port >= IPPORT_RESERVED / 2)) continue; /* else fall */ case EADDRNOTAVAIL: default: return NOTOK; } } } /* \f */ int start_tcp_server (sock, backlog, opt1, opt2) struct sockaddr_in *sock; int backlog, opt1, opt2; { register int port; int sd; register struct hostent *hp; if (backlog != 1) return socket (SOCK_STREAM, 0, (struct sockaddr *) sock, SO_ACCEPTCONN | opt1 | opt2); if (sock -> sin_addr.s_addr == 0) { if ((hp = gethostbyname ("localhost")) == NULL) { errno = EADDRNOTAVAIL; return NOTOK; } sock -> sin_family = hp -> h_addrtype; inaddr_copy (hp, sock); } for (port = IPPORT_RESERVED;; port++) { sock -> sin_port = htons ((u_short) port); if ((sd = socket (SOCK_STREAM, 0, (struct sockaddr *) sock, SO_ACCEPTCONN | opt1 | opt2)) != NOTOK) return sd; switch (errno) { case EADDRINUSE: continue; case EADDRNOTAVAIL: default: return NOTOK; } } } #endif /* \f GETHOSTENT PLUS */ static char *empty = NULL; #ifdef h_addr static char *addrs = NULL; #endif struct hostent *gethostbystring (s) char *s; { register struct hostent *h; #ifndef DG static u_long iaddr; #else static struct in_addr iaddr; #endif static struct hostent hs; iaddr = inet_addr (s); #ifndef DG if (iaddr == NOTOK) #else if (iaddr.s_addr == NOTOK) #endif return gethostbyname (s); h = &hs; h -> h_name = s; h -> h_aliases = ∅ h -> h_addrtype = AF_INET; h -> h_length = sizeof (iaddr); #ifdef h_addr h -> h_addr_list = &addrs; #endif h -> h_addr = (char *) &iaddr; return h; } /* \f AT&T UNIX: 5 with EXOS 8044 TCP/IP card */ #ifdef EXOS long rhost (); char *raddr (); struct hostent *gethostbyaddr (addr, len, type) char *addr; int len, type; { long iaddr; char *name; static char buffer[BUFSIZ]; static struct hostent hs; register struct hostent *h = &hs; if (len != sizeof (long) || type != AF_INET) return NULL; bcopy (addr, (char *) &iaddr, len); if ((name = raddr (iaddr)) == NULL) return NULL; (void) strcpy (buffer, name); free (name); h -> h_name = buffer; h -> h_aliases = ∅ h -> h_addrtype = type; h -> h_length = len; h -> h_addr = addr; return h; } struct hostent *gethostbyname (name) char *name; { static long iaddr; static char buffer[BUFSIZ]; static struct hostent hs; register struct hostent *h = &hs; if ((iaddr = rhost (&name)) == NOTOK) return NULL; (void) strcpy (buffer, name); free (name); h -> h_name = buffer; h -> h_aliases = ∅ h -> h_addrtype = AF_INET; h -> h_length = sizeof (iaddr); h -> h_addr = (char *) &iaddr; return h; } /* \f */ /* really only need the "tsap" entry in this table... but why not? */ static struct servent services[] = { "tsap", NULL, 102, "tcp", "miscellany", NULL, 17000, "lpp", "echo", NULL, 7, "tcp", /* Network standard functions */ "echo", NULL, 7, "udp", "sink", NULL, 9, "tcp", "sink", NULL, 9, "udp", "users", NULL, 11, "tcp", "users", NULL, 11, "udp", "daytime", NULL, 13, "tcp", "daytime", NULL, 13, "udp", "netstat", NULL, 15, "tcp", "netstat", NULL, 15, "udp", "qotd", NULL, 17, "tcp", "qotd", NULL, 17, "udp", "chargen", NULL, 19, "tcp", "chargen", NULL, 19, "udp", "ftp", NULL, 21, "tcp", "telnet", NULL, 23, "tcp", "smtp", NULL, 25, "tcp", "imagen", NULL, 35, "udp", "time", NULL, 37, "tcp", "time", NULL, 37, "udp", "name", NULL, 42, "tcp", "name", NULL, 42, "udp", "whois", NULL, 43, "tcp", "whois", NULL, 43, "udp", "nameserver", NULL, 53, "tcp", "nameserver", NULL, 53, "udp", "mtp", NULL, 57, "tcp", "hostnames", NULL, 101, "tcp", "pop", NULL, 109, "tcp", "pwdgen", NULL, 129, "tcp", "pwdgen", NULL, 129, "udp", "x25bridge", NULL, 146, "tcp", "iso-ip", NULL, 147, "udp", "tftp", NULL, 69, "udp", /* Host specific functions */ "rje", NULL, 77, "tcp", "nmui", NULL, 77, "udp", "finger", NULL, 79, "tcp", "finger", NULL, 79, "udp", "link", NULL, 87, "tcp", "supdup", NULL, 95, "tcp", "path", NULL, 117, "tcp", "exec", NULL, 512, "tcp", /* UNIX TCP sockets */ "login", NULL, 513, "tcp", "shell", NULL, 514, "tcp", "printer", NULL, 515, "tcp", "rfile", NULL, 522, "tcp", "ingreslock", NULL, 1524, "tcp", "biff", NULL, 512, "udp", /* UNIX UDP sockets */ "who", NULL, 513, "udp", "syslog", NULL, 514, "udp", "talk", NULL, 517, "udp", "routed", NULL, 520, "udp", "router_1", NULL, 521, "udp", NULL, &empty, 0, NULL }; struct servent *getservbyname (name, proto) register char *name, *proto; { register struct servent *s; for (s = services; s -> s_name; s++) if (strcmp (name, s -> s_name) == 0 && strcmp (proto, s -> s_proto) == 0) { if (s -> s_aliases == NULL) { s -> s_aliases = ∅ s -> s_port = htons ((u_short) s -> s_port); } return s; } return NULL; } /* \f */ #define s2a(b) (((int) (b)) & 0xff) char *inet_ntoa (in) struct in_addr in; { register char *s = (char *) ∈ static char addr[4 * 3 + 3 + 1]; (void) sprintf (addr, "%d.%d.%d.%d", s2a (s[0]), s2a (s[1]), s2a (s[2]), s2a (s[3])); return addr; } u_long inet_addr (cp) char *cp; { register int base; register char c; register u_long val; u_long parts[4]; register u_long *pp = parts; for (;;) { val = 0, base = 10; if (*cp == '0') base = 8, cp++; if (*cp == 'x' || *cp == 'X') base = 16, cp++; for (; isxdigit (c = *cp); cp++) if (base == 16) val = (val << 4) + (c + 10 - (islower (c) ? 'a' : 'A')); else if (isdigit (c)) val = (val * base) + (c - '0'); else break; switch (*cp) { case '.': if (pp >= parts + 4) return NOTOK; *pp++ = val, cp++; continue; default: if (*cp && !isspace (*cp)) return NOTOK; *pp++ = val; break; } break; } switch (pp - parts) { case 1: val = parts[0]; break; case 2: val = (parts[0] << 24) | (parts[1] & 0xffffff); break; case 3: val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) | (parts[2] & 0xffff); break; case 4: val = ((parts[0]&0xff) << 24) | ((parts[1] & 0xff) << 16) | ((parts[2] & 0xff) << 8) | (parts[3] & 0xff); break; default: return NOTOK; } return htonl (val); } #endif #endif