|
|
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: 14145 (0x3741)
Types: TextFile
Names: »internet.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/compat/internet.c«
/* internet.c - TCP/IP abstractions */
#ifndef lint
static char *rcsid = "$Header: /f/osi/compat/RCS/internet.c,v 7.1 90/01/11 18:35:06 mrose Exp $";
#endif
/*
* $Header: /f/osi/compat/RCS/internet.c,v 7.1 90/01/11 18:35:06 mrose Exp $
*
*
* $Log: internet.c,v $
* Revision 7.1 90/01/11 18:35:06 mrose
* real-sync
*
* Revision 7.0 89/11/23 21:23:03 mrose
* Release 6.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;
#ifdef BSD43
int onoff;
#endif
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) {
SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
return NOTOK;
}
if (sock == NULL)
goto got_socket;
for (port = IPPORT_RESERVED - priv;; priv ? port-- : port++) {
sock -> sin_port = htons ((u_short) port);
if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
break;
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;
}
}
got_socket: ;
#ifndef BSD43
if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULLCP, 0) == NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
#else
onoff = 1;
if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &onoff,
sizeof onoff) == NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
#endif
return sd;
}
/* \f
*/
int start_tcp_server (sock, backlog, opt1, opt2)
struct sockaddr_in *sock;
int backlog,
opt1,
opt2;
{
register int port;
int eindex,
sd;
#ifdef BSD43
int onoff;
#endif
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: ;
#ifndef BSD43
if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULLCP, 0) == NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
if (opt1 && setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0) == NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
("set socket option 0x%x", opt1));
if (opt2 && setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0) == NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
("set socket option 0x%x", opt2));
#else
onoff = 1;
if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &onoff,
sizeof onoff) == NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
if (opt1
&& setsockopt (sd, SOL_SOCKET, opt1, (char *) &onoff, sizeof onoff)
== NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
("set socket option 0x%x", opt1));
if (opt2
&& setsockopt (sd, SOL_SOCKET, opt2, (char *) &onoff, sizeof onoff)
== NOTOK)
SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
("set socket option 0x%x", opt2));
#endif
(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;
}
/* \f
*/
close_tcp_socket (fd)
int fd;
{
#ifdef never_do_this_if_from_join_tcp_client
(void) shutdown (fd, 2);
#endif
return (close (fd));
}
#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, SO_KEEPALIVE);
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,
SO_KEEPALIVE)) != 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 | SO_KEEPALIVE | 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 | SO_KEEPALIVE | 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[2] = { 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;
bzero ((char *) addrs, sizeof 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] & 0xff) << 24)
| (parts[1] & 0xffffff);
break;
case 3:
val = ((parts[0] & 0xff) << 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);
}
u_long inet_network (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] & 0xff) << 24;
break;
case 2:
val = ((parts[0] & 0xff) << 24)
| ((parts[1] & 0xff) << 16);
break;
case 3:
val = ((parts[0] & 0xff) << 24)
| ((parts[1] & 0xff) << 16)
| ((parts[2] & 0xff) << 8)
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