OSDN Git Service

Add MS7619SE
[uclinux-h8/uClinux-dist.git] / user / routed / af.c
1 /*
2  * Copyright (c) 1983, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * From: @(#)af.c       5.11 (Berkeley) 2/28/91
36  * From: @(#)af.c       8.1 (Berkeley) 6/5/93
37  */
38 char af_rcsid[] = 
39   "$Id: af.c,v 1.8 1999/09/28 15:48:20 dholland Exp $";
40
41 #include "defs.h"
42
43 /*
44  * Address family support routines
45  */
46
47 void inet_canon(struct sockaddr *);
48 int inet_checkhost(struct sockaddr *);
49 char *inet_format(struct sockaddr *, char *, size_t);
50 void inet_hash(struct sockaddr *, struct afhash *);
51 int inet_netmatch(struct sockaddr *, struct sockaddr *);
52 int inet_portcheck(struct sockaddr *);
53 int inet_portmatch(struct sockaddr *);
54 void inet_output(int, int, struct sockaddr *, int);
55
56 #define NIL     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
57 #define INET \
58         { inet_hash,            inet_netmatch,          inet_output, \
59           inet_portmatch,       inet_portcheck,         inet_checkhost, \
60           inet_rtflags,         inet_sendroute,         inet_canon, \
61           inet_format \
62         }
63
64 struct afswitch afswitch[AF_MAX] = 
65 {
66         NIL,            /* 0- unused */
67         NIL,            /* 1- Unix domain, unused */
68         INET,           /* Internet */
69         /* 
70          * Expect a warning here from gcc 2.95 about missing initializer.
71          * They appear to have decided that the standard behavior of C 
72          * where unspecified initializers are 0 - something tons of old
73          * unix code relies on - is evil. Trouble is, here, AF_MAX is
74          * defined by the kernel, so even if we were to put in a whole
75          * pile of NILs here, it would become kernel-version dependent
76          * for no good reason. Idiots. Someone fix gcc.
77          */
78 };
79
80 int af_max = sizeof(afswitch) / sizeof(afswitch[0]);
81
82 struct sockaddr_in inet_default = 
83 {
84         AF_INET, 0, { INADDR_ANY }, { 0 }
85 };
86
87 void inet_hash(struct sockaddr *sa, struct afhash *hp)
88 {
89         struct sockaddr_in *sin=(struct sockaddr_in *)sa;
90         u_long n;
91
92         n = inet_netof_subnet(sin->sin_addr);
93         if (n)
94             while ((n & 0xff) == 0)
95                 n >>= 8;
96         hp->afh_nethash = n;
97         hp->afh_hosthash = ntohl(sin->sin_addr.s_addr);
98         hp->afh_hosthash &= 0x7fffffff;
99 }
100
101 int inet_netmatch(struct sockaddr *sa1, struct sockaddr *sa2)
102 {
103         struct sockaddr_in *sin1=(struct sockaddr_in *)sa1;
104         struct sockaddr_in *sin2=(struct sockaddr_in *)sa2;
105         return (inet_netof_subnet(sin1->sin_addr) ==
106             inet_netof_subnet(sin2->sin_addr));
107 }
108
109 /*
110  * Verify the message is from the right port.
111  */
112 int inet_portmatch(struct sockaddr *sa)
113 {
114         struct sockaddr_in *sin=(struct sockaddr_in *)sa;
115         return (sin->sin_port == rip_port);
116 }
117
118 /*
119  * Verify the message is from a "trusted" port.
120  */
121 int inet_portcheck(struct sockaddr *sa)
122 {
123         struct sockaddr_in *sin=(struct sockaddr_in *)sa;
124         return (ntohs(sin->sin_port) <= IPPORT_RESERVED);
125 }
126
127 /*
128  * Internet output routine.
129  */
130 void inet_output(int s, int flags, struct sockaddr *sa, int size)
131 {
132         struct sockaddr_in dst = *(struct sockaddr_in *)sa;
133
134         if (dst.sin_port == 0) {
135                 dst.sin_port = rip_port;
136         }
137         if (sendto(s, packet, size, flags, (struct sockaddr *)&dst, 
138                    sizeof(dst)) < 0) {
139                 perror("sendto");
140         }
141 }
142
143 /*
144  * Return 1 if the address is believed
145  * for an Internet host -- THIS IS A KLUDGE.
146  */
147 int inet_checkhost(struct sockaddr *sa)
148 {
149         struct sockaddr_in *sin=(struct sockaddr_in *)sa;
150         u_long i = ntohl(sin->sin_addr.s_addr);
151
152         if (IN_EXPERIMENTAL(i) || sin->sin_port != 0)
153                 return (0);
154         if (i != 0 && (i & 0xff000000) == 0)
155                 return (0);
156         for (i = 0; i < sizeof(sin->sin_zero)/sizeof(sin->sin_zero[0]); i++)
157                 if (sin->sin_zero[i])
158                         return (0);
159         return (1);
160 }
161
162 void inet_canon(struct sockaddr *sa)
163 {
164         struct sockaddr_in *sin=(struct sockaddr_in *)sa;
165         sin->sin_port = 0;
166 }
167
168 char *inet_format(struct sockaddr *sa, char *buf, size_t sz)
169 {
170         struct sockaddr_in *sin=(struct sockaddr_in *)sa;
171         strncpy(buf, inet_ntoa(sin->sin_addr), sz);
172         buf[sz - 1] = '\0';
173         return (buf);
174 }