1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)af.c 5.8 (Berkeley) 06/18/88"; 20 #endif /* not lint */ 21 22 #include "defs.h" 23 24 /* 25 * Address family support routines 26 */ 27 int inet_hash(), inet_netmatch(), inet_output(), 28 inet_portmatch(), inet_portcheck(), 29 inet_checkhost(), inet_rtflags(), inet_sendroute(), inet_canon(); 30 char *inet_format(); 31 32 #define NIL { 0 } 33 #define INET \ 34 { inet_hash, inet_netmatch, inet_output, \ 35 inet_portmatch, inet_portcheck, inet_checkhost, \ 36 inet_rtflags, inet_sendroute, inet_canon, \ 37 inet_format \ 38 } 39 40 struct afswitch afswitch[AF_MAX] = { 41 NIL, /* 0- unused */ 42 NIL, /* 1- Unix domain, unused */ 43 INET, /* Internet */ 44 }; 45 46 int af_max = sizeof(afswitch) / sizeof(afswitch[0]); 47 48 struct sockaddr_in inet_default = { AF_INET, INADDR_ANY }; 49 50 inet_hash(sin, hp) 51 register struct sockaddr_in *sin; 52 struct afhash *hp; 53 { 54 register u_long n; 55 56 n = inet_netof(sin->sin_addr); 57 if (n) 58 while ((n & 0xff) == 0) 59 n >>= 8; 60 hp->afh_nethash = n; 61 hp->afh_hosthash = ntohl(sin->sin_addr.s_addr); 62 hp->afh_hosthash &= 0x7fffffff; 63 } 64 65 inet_netmatch(sin1, sin2) 66 struct sockaddr_in *sin1, *sin2; 67 { 68 69 return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr)); 70 } 71 72 /* 73 * Verify the message is from the right port. 74 */ 75 inet_portmatch(sin) 76 register struct sockaddr_in *sin; 77 { 78 79 return (sin->sin_port == sp->s_port); 80 } 81 82 /* 83 * Verify the message is from a "trusted" port. 84 */ 85 inet_portcheck(sin) 86 struct sockaddr_in *sin; 87 { 88 89 return (ntohs(sin->sin_port) <= IPPORT_RESERVED); 90 } 91 92 /* 93 * Internet output routine. 94 */ 95 inet_output(s, flags, sin, size) 96 int s, flags; 97 struct sockaddr_in *sin; 98 int size; 99 { 100 struct sockaddr_in dst; 101 102 dst = *sin; 103 sin = &dst; 104 if (sin->sin_port == 0) 105 sin->sin_port = sp->s_port; 106 if (sendto(s, packet, size, flags, sin, sizeof (*sin)) < 0) 107 perror("sendto"); 108 } 109 110 /* 111 * Return 1 if the address is believed 112 * for an Internet host -- THIS IS A KLUDGE. 113 */ 114 inet_checkhost(sin) 115 struct sockaddr_in *sin; 116 { 117 u_long i = ntohl(sin->sin_addr.s_addr); 118 119 #ifndef IN_EXPERIMENTAL 120 #define IN_EXPERIMENTAL(i) (((long) (i) & 0xe0000000) == 0xe0000000) 121 #endif 122 123 if (IN_EXPERIMENTAL(i) || sin->sin_port != 0) 124 return (0); 125 if (i != 0 && (i & 0xff000000) == 0) 126 return (0); 127 for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++) 128 if (sin->sin_zero[i]) 129 return (0); 130 return (1); 131 } 132 133 inet_canon(sin) 134 struct sockaddr_in *sin; 135 { 136 137 sin->sin_port = 0; 138 } 139 140 char * 141 inet_format(sin) 142 struct sockaddr_in *sin; 143 { 144 char *inet_ntoa(); 145 146 return (inet_ntoa(sin->sin_addr)); 147 } 148