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.9 (Berkeley) 08/21/89"; 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 = { 49 #ifdef RTM_ADD 50 sizeof (inet_default), 51 #endif 52 AF_INET, INADDR_ANY }; 53 54 inet_hash(sin, hp) 55 register struct sockaddr_in *sin; 56 struct afhash *hp; 57 { 58 register u_long n; 59 60 n = inet_netof(sin->sin_addr); 61 if (n) 62 while ((n & 0xff) == 0) 63 n >>= 8; 64 hp->afh_nethash = n; 65 hp->afh_hosthash = ntohl(sin->sin_addr.s_addr); 66 hp->afh_hosthash &= 0x7fffffff; 67 } 68 69 inet_netmatch(sin1, sin2) 70 struct sockaddr_in *sin1, *sin2; 71 { 72 73 return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr)); 74 } 75 76 /* 77 * Verify the message is from the right port. 78 */ 79 inet_portmatch(sin) 80 register struct sockaddr_in *sin; 81 { 82 83 return (sin->sin_port == sp->s_port); 84 } 85 86 /* 87 * Verify the message is from a "trusted" port. 88 */ 89 inet_portcheck(sin) 90 struct sockaddr_in *sin; 91 { 92 93 return (ntohs(sin->sin_port) <= IPPORT_RESERVED); 94 } 95 96 /* 97 * Internet output routine. 98 */ 99 inet_output(s, flags, sin, size) 100 int s, flags; 101 struct sockaddr_in *sin; 102 int size; 103 { 104 struct sockaddr_in dst; 105 106 dst = *sin; 107 sin = &dst; 108 if (sin->sin_port == 0) 109 sin->sin_port = sp->s_port; 110 if (sin->sin_len == 0) 111 sin->sin_len = sizeof (*sin); 112 if (sendto(s, packet, size, flags, sin, sizeof (*sin)) < 0) 113 perror("sendto"); 114 } 115 116 /* 117 * Return 1 if the address is believed 118 * for an Internet host -- THIS IS A KLUDGE. 119 */ 120 inet_checkhost(sin) 121 struct sockaddr_in *sin; 122 { 123 u_long i = ntohl(sin->sin_addr.s_addr); 124 125 #ifndef IN_EXPERIMENTAL 126 #define IN_EXPERIMENTAL(i) (((long) (i) & 0xe0000000) == 0xe0000000) 127 #endif 128 129 if (IN_EXPERIMENTAL(i) || sin->sin_port != 0) 130 return (0); 131 if (i != 0 && (i & 0xff000000) == 0) 132 return (0); 133 for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++) 134 if (sin->sin_zero[i]) 135 return (0); 136 return (1); 137 } 138 139 inet_canon(sin) 140 struct sockaddr_in *sin; 141 { 142 143 sin->sin_port = 0; 144 sin->sin_len = sizeof(*sin); 145 } 146 147 char * 148 inet_format(sin) 149 struct sockaddr_in *sin; 150 { 151 char *inet_ntoa(); 152 153 return (inet_ntoa(sin->sin_addr)); 154 } 155