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