OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [net/] [ipv4/] [devinet.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *      NET3    IP device support routines.
3
 *
4
 *              This program is free software; you can redistribute it and/or
5
 *              modify it under the terms of the GNU General Public License
6
 *              as published by the Free Software Foundation; either version
7
 *              2 of the License, or (at your option) any later version.
8
 *
9
 *      Derived from the IP parts of dev.c 1.0.19
10
 *              Authors:        Ross Biro, <bir7@leland.Stanford.Edu>
11
 *                              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12
 *                              Mark Evans, <evansmp@uhura.aston.ac.uk>
13
 *
14
 *      Additional Authors:
15
 *              Alan Cox, <gw4pts@gw4pts.ampr.org>
16
 */
17
 
18
#include <linux/config.h>       /* For CONFIG_IP_CLASSLESS */
19
 
20
#include <asm/segment.h>
21
#include <asm/system.h>
22
#include <asm/bitops.h>
23
#include <linux/types.h>
24
#include <linux/kernel.h>
25
#include <linux/sched.h>
26
#include <linux/string.h>
27
#include <linux/mm.h>
28
#include <linux/socket.h>
29
#include <linux/sockios.h>
30
#include <linux/in.h>
31
#include <linux/errno.h>
32
#include <linux/interrupt.h>
33
#include <linux/if_ether.h>
34
#include <linux/inet.h>
35
#include <linux/netdevice.h>
36
#include <linux/etherdevice.h>
37
#include <net/ip.h>
38
#include <net/route.h>
39
#include <net/protocol.h>
40
#include <net/tcp.h>
41
#include <linux/skbuff.h>
42
#include <net/sock.h>
43
#include <net/arp.h>
44
 
45
/*
46
 *      Determine a default network mask, based on the IP address.
47
 */
48
 
49
unsigned long ip_get_mask(unsigned long addr)
50
{
51
        unsigned long dst;
52
 
53
        if (addr == 0L)
54
                return(0L);     /* special case */
55
 
56
        dst = ntohl(addr);
57
        if (IN_CLASSA(dst))
58
                return(htonl(IN_CLASSA_NET));
59
        if (IN_CLASSB(dst))
60
                return(htonl(IN_CLASSB_NET));
61
        if (IN_CLASSC(dst))
62
                return(htonl(IN_CLASSC_NET));
63
 
64
        /*
65
         *      Something else, probably a multicast.
66
         */
67
 
68
        return(0);
69
}
70
 
71
/*
72
 *      Check the address for our address, broadcasts, etc.
73
 *
74
 *      I intend to fix this to at the very least cache the last
75
 *      resolved entry.
76
 */
77
 
78
int ip_chk_addr(unsigned long addr)
79
{
80
        struct device *dev;
81
#ifndef CONFIG_IP_CLASSLESS
82
        unsigned long mask;
83
#endif
84
 
85
        /*
86
         *      Accept both `all ones' and `all zeros' as BROADCAST.
87
         *      (Support old BSD in other words). This old BSD
88
         *      support will go very soon as it messes other things
89
         *      up.
90
         *      Also accept `loopback broadcast' as BROADCAST.
91
         */
92
 
93
        if (addr == INADDR_ANY || addr == INADDR_BROADCAST ||
94
            addr == htonl(0x7FFFFFFFL))
95
                return IS_BROADCAST;
96
 
97
#ifndef  CONFIG_IP_CLASSLESS
98
        mask = ip_get_mask(addr);
99
 
100
        /*
101
         *      Accept all of the `loopback' class A net.
102
         */
103
 
104
        if ((addr & mask) == htonl(0x7F000000L))
105
                return IS_MYADDR;
106
#else
107
        if ((addr & htonl(0x7F000000L)) == htonl(0x7F000000L))
108
                return IS_MYADDR;
109
#endif
110
 
111
        /*
112
         *      OK, now check the interface addresses. We could
113
         *      speed this by keeping a dev and a dev_up chain.
114
         */
115
 
116
        for (dev = dev_base; dev != NULL; dev = dev->next)
117
        {
118
                if ((!(dev->flags & IFF_UP)) || dev->family!=AF_INET)
119
                        continue;
120
                /*
121
                 *      If the protocol address of the device is 0 this is special
122
                 *      and means we are address hunting (eg bootp).
123
                 */
124
 
125
                if (dev->pa_addr == 0)
126
                        return IS_MYADDR;
127
                /*
128
                 *      Is it the exact IP address?
129
                 */
130
 
131
                if (addr == dev->pa_addr)
132
                        return IS_MYADDR;
133
                /*
134
                 *      Is it our broadcast address?
135
                 */
136
 
137
                if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
138
                        return IS_BROADCAST;
139
                /*
140
                 *      Nope. Check for a subnetwork broadcast.
141
                 */
142
 
143
                if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0)
144
                {
145
                        if ((addr & ~dev->pa_mask) == 0)
146
                                return IS_BROADCAST;
147
                        if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
148
                                return IS_BROADCAST;
149
                }
150
 
151
#ifndef CONFIG_IP_CLASSLESS
152
                /*
153
                 *      Nope. Check for Network broadcast.
154
                 */
155
 
156
                if (((addr ^ dev->pa_addr) & mask) == 0)
157
                {
158
                        if ((addr & ~mask) == 0)
159
                                return IS_BROADCAST;
160
                        if ((addr & ~mask) == ~mask)
161
                                return IS_BROADCAST;
162
                }
163
#endif
164
        }
165
        if(IN_MULTICAST(ntohl(addr)))
166
                return IS_MULTICAST;
167
        return 0;                /* no match at all */
168
}
169
 
170
 
171
/*
172
 *      Retrieve our own address.
173
 *
174
 *      Because the loopback address (127.0.0.1) is already recognized
175
 *      automatically, we can use the loopback interface's address as
176
 *      our "primary" interface.  This is the address used by IP et
177
 *      al when it doesn't know which address to use (i.e. it does not
178
 *      yet know from or to which interface to go...).
179
 */
180
 
181
unsigned long ip_my_addr(void)
182
{
183
        struct device *dev;
184
 
185
        for (dev = dev_base; dev != NULL; dev = dev->next)
186
        {
187
                if (dev->flags & IFF_LOOPBACK)
188
                        return(dev->pa_addr);
189
        }
190
        return(0);
191
}
192
 
193
/*
194
 *      Find an interface that can handle addresses for a certain address.
195
 */
196
 
197
struct device * ip_dev_bynet(unsigned long addr, unsigned long mask)
198
{
199
        struct device *dev;
200
        struct device *best_dev = NULL;
201
        __u32  best_mask = mask;
202
 
203
        for (dev = dev_base; dev; dev = dev->next)
204
        {
205
                if (!(dev->flags & IFF_UP))
206
                        continue;
207
                if (dev->flags & IFF_POINTOPOINT)
208
                {
209
                        if (addr == dev->pa_dstaddr)
210
                                return dev;
211
                        continue;
212
                }
213
                if (dev->pa_mask & (addr ^ dev->pa_addr))
214
                        continue;
215
                if (mask == dev->pa_mask)
216
                        return dev;
217
                if (best_dev && (best_mask & dev->pa_mask) != best_mask)
218
                        continue;
219
                best_dev = dev;
220
                best_mask = dev->pa_mask;
221
        }
222
        return best_dev;
223
}
224
 
225
/*
226
 *      Find the first device with a given source address.
227
 */
228
 
229
struct device *ip_dev_find(unsigned long addr)
230
{
231
        struct device *dev;
232
        for(dev = dev_base; dev; dev=dev->next)
233
        {
234
                if((dev->flags&IFF_UP) && dev->pa_addr==addr)
235
                        return dev;
236
        }
237
        return NULL;
238
}
239
 
240
struct device *dev_getbytype(unsigned short type)
241
{
242
        struct device *dev;
243
 
244
        for (dev = dev_base; dev != NULL; dev = dev->next)
245
        {
246
                if (dev->type == type && !(dev->flags&(IFF_LOOPBACK|IFF_NOARP)))
247
                        return(dev);
248
        }
249
        return(NULL);
250
}
251
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.