This is inet.c in view mode; [Download] [Up]
/*
* $Header: /disk/d/src/devel/gated/dist/src/RCS/inet.c,v 2.1 92/02/24 14:12:40 jch Exp $
*/
/*%Copyright%*/
/************************************************************************
* *
* GateD, Release 2 *
* *
* Copyright (c) 1990,1991,1992 by Cornell University *
* All rights reserved. *
* *
* THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY *
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT *
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
* AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
* Royalty-free licenses to redistribute GateD Release *
* 2 in whole or in part may be obtained by writing to: *
* *
* GateDaemon Project *
* Information Technologies/Network Resources *
* 143 Caldwell Hall *
* Cornell University *
* Ithaca, NY 14853-2602 *
* *
* GateD is based on Kirton's EGP, UC Berkeley's routing *
* daemon (routed), and DCN's HELLO routing Protocol. *
* Development of Release 2 has been supported by the *
* National Science Foundation. *
* *
* Please forward bug fixes, enhancements and questions to the *
* gated mailing list: gated-people@gated.cornell.edu. *
* *
* Authors: *
* *
* Jeffrey C Honig <jch@gated.cornell.edu> *
* Scott W Brim <swb@gated.cornell.edu> *
* *
*************************************************************************
* *
* Portions of this software may fall under the following *
* copyrights: *
* *
* Copyright (c) 1988 Regents of the University of California. *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms are *
* permitted provided that the above copyright notice and *
* this paragraph are duplicated in all such forms and that *
* any documentation, advertising materials, and other *
* materials related to such distribution and use *
* acknowledge that the software was developed by the *
* University of California, Berkeley. The name of the *
* University may not be used to endorse or promote *
* products derived from this software without specific *
* prior written permission. THIS SOFTWARE IS PROVIDED *
* ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
* *
************************************************************************/
#include "include.h"
/*
* Formulate an Internet address from network + host.
*/
struct in_addr
gd_inet_makeaddr(net, host, subnetsAllowed)
u_long net;
int host, subnetsAllowed;
{
register u_long mask;
struct in_addr addr;
addr.s_addr = net;
if (subnetsAllowed && (mask = if_subnetmask(addr))) {
mask = ~mask;
} else if (mask = gd_inet_netmask(net)) {
mask = ~mask;
} else {
addr.s_addr = INADDR_ANY;
return (addr);
}
addr.s_addr = net | (host & mask);
addr.s_addr = htonl(addr.s_addr);
return (addr);
}
/*
* Return the network number from an internet address.
*/
u_long
gd_inet_netof(in)
struct in_addr in;
{
register u_long net;
register u_long mask;
if (mask = if_subnetmask(in)) {
net = ntohl(in.s_addr) &mask;
} else {
net = gd_inet_wholenetof(in);
}
return (net);
}
/*
* Return the network number from an internet address.
* unsubnetted version.
*/
u_long
gd_inet_wholenetof(in)
struct in_addr in;
{
register u_long i = ntohl(in.s_addr);
return (i & gd_inet_netmask(i));
}
/*
* Return the host portion of an internet address.
*/
u_long
gd_inet_lnaof(in)
struct in_addr in;
{
register u_long host = ntohl(in.s_addr);
register u_long mask;
if (mask = if_subnetmask(in)) {
host &= ~mask;
} else {
host ^= gd_inet_wholenetof(in);
}
return (host);
}
/*
* Return the class of the network or zero in not valid
*/
int
gd_inet_class(net)
u_char *net;
{
if (in_isa(*net)) {
return CLAA;
} else if (in_isb(*net)) {
return CLAB;
} else if (in_isc(*net)) {
return CLAC;
} else {
return 0;
}
}
/*
* Return 1 if the address is believed
* for an Internet host -- THIS IS A KLUDGE.
*/
int
gd_inet_checkhost(sin)
struct sockaddr_in *sin;
{
u_long i = ntohl(sin->sin_addr.s_addr);
if (!gd_inet_class((u_char *) & sin->sin_addr.s_addr) || sin->sin_port != 0) {
return (0);
}
if (i != 0 && (i & 0xff000000) == 0) {
return (0);
}
for (i = 0; i < sizeof(sin->sin_zero) / sizeof(sin->sin_zero[0]); i++) {
if (sin->sin_zero[i]) {
return (0);
}
}
return (1);
}
/*
* hash routine for the route table.
*/
u_long
gd_inet_hash(sin)
register sockaddr_un *sin;
{
register u_long n;
n = gd_inet_netof(sin->in.sin_addr);
if (n) {
while (!(n & 0xff)) {
n >>= 8;
}
}
return (n);
}
/*
* Convert network-format internet address
* to base 256 d.d.d.d representation.
*/
#if 0
#ifndef vax11c
char *
inet_ntoa(in_addr)
struct in_addr in_addr;
{
static char buf[16];
struct sockaddr_in addr;
sockclear_in(&addr);
addr.sin_addr = in_addr; /* struct copy */
(void) sprintf(buf, "%A",
&addr);
return (buf);
}
#endif /* vax11c */
#endif
/*
* Checksum routine for Internet Protocol - Modified from 4.3+ networking in_chksum.c
*
*/
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
u_short
gd_inet_cksum(v, nv, len)
register struct iovec v[]; /* List of iovecs */
register int nv; /* Number of iovecs */
register int len; /* Length of data */
{
register u_short *w;
register int sum = 0;
register int vlen = 0;
register struct iovec *vp;
int byte_swapped = 0;
union {
char c[2];
u_short s;
} s_util;
union {
u_short s[2];
long l;
} l_util;
for (vp = v; nv && len; nv--, vp++) {
if (vp->iov_len == 0) {
continue;
}
w = (u_short *) vp->iov_base;
if (vlen == -1) {
/*
* The first byte of this mbuf is the continuation
* of a word spanning between this mbuf and the
* last mbuf.
*
* s_util.c[0] is already saved when scanning previous
* mbuf.
*/
s_util.c[1] = *(char *) w;
sum += s_util.s;
w = (u_short *) ((char *) w + 1);
vlen = vp->iov_len - 1;
len--;
} else {
vlen = vp->iov_len;
}
if (len < vlen) {
vlen = len;
}
len -= vlen;
/*
* Force to even boundary.
*/
if ((1 & (int) w) && (vlen > 0)) {
REDUCE;
sum <<= 8;
s_util.c[0] = *(u_char *) w;
w = (u_short *) ((char *) w + 1);
vlen--;
byte_swapped = 1;
}
/*
* Unroll the loop to make overhead from
* branches &c small.
*/
while ((vlen -= 32) >= 0) {
sum += w[0];
sum += w[1];
sum += w[2];
sum += w[3];
sum += w[4];
sum += w[5];
sum += w[6];
sum += w[7];
sum += w[8];
sum += w[9];
sum += w[10];
sum += w[11];
sum += w[12];
sum += w[13];
sum += w[14];
sum += w[15];
w += 16;
}
vlen += 32;
while ((vlen -= 8) >= 0) {
sum += w[0];
sum += w[1];
sum += w[2];
sum += w[3];
w += 4;
}
vlen += 8;
if (vlen == 0 && byte_swapped == 0) {
continue;
}
REDUCE;
while ((vlen -= 2) >= 0) {
sum += *w++;
}
if (byte_swapped) {
REDUCE;
sum <<= 8;
byte_swapped = 0;
if (vlen == -1) {
s_util.c[1] = *(char *) w;
sum += s_util.s;
vlen = 0;
} else {
vlen = -1;
}
} else if (vlen == -1) {
s_util.c[0] = *(char *) w;
}
}
if (len) {
trace(TR_ALL, LOG_ERR, "inet_cksum: out of data");
}
if (vlen == -1) {
/* The last buffer has odd # of bytes. Follow the
standard (the odd byte may be shifted left by 8 bits
or not as determined by endian-ness of the machine) */
s_util.c[1] = 0;
sum += s_util.s;
}
REDUCE;
return (~sum & 0xffff);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.