1 /* 2 * The mrouted program is covered by the license in the accompanying file 3 * named "LICENSE". Use of the mrouted program represents acceptance of 4 * the terms and conditions listed in that file. 5 * 6 * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of 7 * Leland Stanford Junior University. 8 * 9 * 10 * from: Id: inet.c,v 1.4 1993/05/30 01:36:38 deering Exp 11 * $Id: inet.c,v 1.1 1994/01/11 20:15:55 brezak Exp $ 12 */ 13 14 #ifndef lint 15 static char rcsid[] = "$Id: inet.c,v 1.1 1994/01/11 20:15:55 brezak Exp $"; 16 #endif 17 18 #include "defs.h" 19 20 21 /* 22 * Exported variables. 23 */ 24 char s1[16]; /* buffers to hold the string representations */ 25 char s2[16]; /* of IP addresses, to be passed to inet_fmt() */ 26 char s3[16]; /* or inet_fmts(). */ 27 28 29 /* 30 * Verify that a given IP address is credible as a host address. 31 * (Without a mask, cannot detect addresses of the form {subnet,0} or 32 * {subnet,-1}.) 33 */ 34 int inet_valid_host(naddr) 35 u_long naddr; 36 { 37 register u_long addr; 38 39 addr = ntohl(naddr); 40 41 return (!(IN_MULTICAST(addr) || 42 IN_BADCLASS (addr) || 43 (addr & 0xff000000) == 0)); 44 } 45 46 47 /* 48 * Verify that a given subnet number and mask pair are credible. 49 */ 50 int inet_valid_subnet(nsubnet, nmask) 51 u_long nsubnet, nmask; 52 { 53 register u_long subnet, mask; 54 55 subnet = ntohl(nsubnet); 56 mask = ntohl(nmask); 57 58 if ((subnet & mask) != subnet) return (FALSE); 59 60 if (IN_CLASSA(subnet)) { 61 if (mask < 0xff000000 || 62 (subnet & 0xff000000) == 0 || 63 (subnet & 0xff000000) == 0x7f000000) return (FALSE); 64 } 65 else if (IN_CLASSB(subnet)) { 66 if (mask < 0xffff0000) return (FALSE); 67 } 68 else if (IN_CLASSC(subnet)) { 69 if (mask < 0xffffff00) return (FALSE); 70 } 71 else return (FALSE); 72 73 return (TRUE); 74 } 75 76 77 /* 78 * Convert an IP address in u_long (network) format into a printable string. 79 */ 80 char *inet_fmt(addr, s) 81 u_long addr; 82 char *s; 83 { 84 register u_char *a; 85 86 a = (u_char *)&addr; 87 sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]); 88 return (s); 89 } 90 91 92 /* 93 * Convert an IP subnet number in u_long (network) format into a printable 94 * string. 95 */ 96 char *inet_fmts(addr, mask, s) 97 u_long addr, mask; 98 char *s; 99 { 100 register u_char *a, *m; 101 102 a = (u_char *)&addr; 103 m = (u_char *)&mask; 104 105 if (m[3] != 0) sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]); 106 else if (m[2] != 0) sprintf(s, "%u.%u.%u", a[0], a[1], a[2]); 107 else if (m[1] != 0) sprintf(s, "%u.%u", a[0], a[1]); 108 else sprintf(s, "%u", a[0]); 109 110 return (s); 111 } 112 113 114 /* 115 * Convert the printable string representation of an IP address into the 116 * u_long (network) format. Return 0xffffffff on error. (To detect the 117 * legal address with that value, you must explicitly compare the string 118 * with "255.255.255.255".) 119 */ 120 u_long inet_parse(s) 121 char *s; 122 { 123 u_long a; 124 u_int a0, a1, a2, a3; 125 char c; 126 127 if (sscanf(s, "%u.%u.%u.%u%c", &a0, &a1, &a2, &a3, &c) != 4 || 128 a0 > 255 || a1 > 255 || a2 > 255 || a3 > 255) 129 return (0xffffffff); 130 131 ((u_char *)&a)[0] = a0; 132 ((u_char *)&a)[1] = a1; 133 ((u_char *)&a)[2] = a2; 134 ((u_char *)&a)[3] = a3; 135 136 return (a); 137 } 138 139 140 /* 141 * inet_cksum extracted from: 142 * P I N G . C 143 * 144 * Author - 145 * Mike Muuss 146 * U. S. Army Ballistic Research Laboratory 147 * December, 1983 148 * Modified at Uc Berkeley 149 * 150 * (ping.c) Status - 151 * Public Domain. Distribution Unlimited. 152 * 153 * I N _ C K S U M 154 * 155 * Checksum routine for Internet Protocol family headers (C Version) 156 * 157 */ 158 int inet_cksum(addr, len) 159 u_short *addr; 160 u_int len; 161 { 162 register int nleft = (int)len; 163 register u_short *w = addr; 164 u_short answer = 0; 165 register int sum = 0; 166 167 /* 168 * Our algorithm is simple, using a 32 bit accumulator (sum), 169 * we add sequential 16 bit words to it, and at the end, fold 170 * back all the carry bits from the top 16 bits into the lower 171 * 16 bits. 172 */ 173 while( nleft > 1 ) { 174 sum += *w++; 175 nleft -= 2; 176 } 177 178 /* mop up an odd byte, if necessary */ 179 if( nleft == 1 ) { 180 *(u_char *) (&answer) = *(u_char *)w ; 181 sum += answer; 182 } 183 184 /* 185 * add back carry outs from top 16 bits to low 16 bits 186 */ 187 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 188 sum += (sum >> 16); /* add carry */ 189 answer = ~sum; /* truncate to 16 bits */ 190 return (answer); 191 } 192