1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)af.c 8.1 (Berkeley) 06/05/93";
10 #endif /* not lint */
11
12 #include "defs.h"
13
14 /*
15 * Address family support routines
16 */
17 int inet_hash(), inet_netmatch(), inet_output(),
18 inet_portmatch(), inet_portcheck(),
19 inet_checkhost(), inet_rtflags(), inet_sendroute(), inet_canon();
20 char *inet_format();
21
22 #define NIL { 0 }
23 #define INET \
24 { inet_hash, inet_netmatch, inet_output, \
25 inet_portmatch, inet_portcheck, inet_checkhost, \
26 inet_rtflags, inet_sendroute, inet_canon, \
27 inet_format \
28 }
29
30 struct afswitch afswitch[AF_MAX] = {
31 NIL, /* 0- unused */
32 NIL, /* 1- Unix domain, unused */
33 INET, /* Internet */
34 };
35
36 int af_max = sizeof(afswitch) / sizeof(afswitch[0]);
37
38 struct sockaddr_in inet_default = {
39 #ifdef RTM_ADD
40 sizeof (inet_default),
41 #endif
42 AF_INET, INADDR_ANY };
43
inet_hash(sin,hp)44 inet_hash(sin, hp)
45 register struct sockaddr_in *sin;
46 struct afhash *hp;
47 {
48 register u_long n;
49
50 n = inet_netof(sin->sin_addr);
51 if (n)
52 while ((n & 0xff) == 0)
53 n >>= 8;
54 hp->afh_nethash = n;
55 hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
56 hp->afh_hosthash &= 0x7fffffff;
57 }
58
59 inet_netmatch(sin1, sin2)
60 struct sockaddr_in *sin1, *sin2;
61 {
62
63 return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr));
64 }
65
66 /*
67 * Verify the message is from the right port.
68 */
inet_portmatch(sin)69 inet_portmatch(sin)
70 register struct sockaddr_in *sin;
71 {
72
73 return (sin->sin_port == sp->s_port);
74 }
75
76 /*
77 * Verify the message is from a "trusted" port.
78 */
79 inet_portcheck(sin)
80 struct sockaddr_in *sin;
81 {
82
83 return (ntohs(sin->sin_port) <= IPPORT_RESERVED);
84 }
85
86 /*
87 * Internet output routine.
88 */
inet_output(s,flags,sin,size)89 inet_output(s, flags, sin, size)
90 int s, flags;
91 struct sockaddr_in *sin;
92 int size;
93 {
94 struct sockaddr_in dst;
95
96 dst = *sin;
97 sin = &dst;
98 if (sin->sin_port == 0)
99 sin->sin_port = sp->s_port;
100 if (sin->sin_len == 0)
101 sin->sin_len = sizeof (*sin);
102 if (sendto(s, packet, size, flags,
103 (struct sockaddr *)sin, sizeof (*sin)) < 0)
104 perror("sendto");
105 }
106
107 /*
108 * Return 1 if the address is believed
109 * for an Internet host -- THIS IS A KLUDGE.
110 */
111 inet_checkhost(sin)
112 struct sockaddr_in *sin;
113 {
114 u_long i = ntohl(sin->sin_addr.s_addr);
115
116 #ifndef IN_EXPERIMENTAL
117 #define IN_EXPERIMENTAL(i) (((long) (i) & 0xe0000000) == 0xe0000000)
118 #endif
119
120 if (IN_EXPERIMENTAL(i) || sin->sin_port != 0)
121 return (0);
122 if (i != 0 && (i & 0xff000000) == 0)
123 return (0);
124 for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++)
125 if (sin->sin_zero[i])
126 return (0);
127 return (1);
128 }
129
130 inet_canon(sin)
131 struct sockaddr_in *sin;
132 {
133
134 sin->sin_port = 0;
135 sin->sin_len = sizeof(*sin);
136 }
137
138 char *
inet_format(sin)139 inet_format(sin)
140 struct sockaddr_in *sin;
141 {
142 char *inet_ntoa();
143
144 return (inet_ntoa(sin->sin_addr));
145 }
146