xref: /original-bsd/sbin/routed/af.c (revision 1eabc47f)
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