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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [ipv4/] [icmp.c] - Blame information for rev 1772

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *      NET3:   Implementation of the ICMP protocol layer.
3
 *
4
 *              Alan Cox, <alan@cymru.net>
5
 *
6
 *      This program is free software; you can redistribute it and/or
7
 *      modify it under the terms of the GNU General Public License
8
 *      as published by the Free Software Foundation; either version
9
 *      2 of the License, or (at your option) any later version.
10
 *
11
 *      Some of the function names and the icmp unreach table for this
12
 *      module were derived from [icmp.c 1.0.11 06/02/93] by
13
 *      Ross Biro, Fred N. van Kempen, Mark Evans, Alan Cox, Gerhard Koerting.
14
 *      Other than that this module is a complete rewrite.
15
 *
16
 *      Fixes:
17
 *              Mike Shaver     :       RFC1122 checks.
18
 *              Alan Cox        :       Multicast ping reply as self.
19
 *              Alan Cox        :       Fix atomicity lockup in ip_build_xmit
20
 *                                      call.
21
 *              Alan Cox        :       Added 216,128 byte paths to the MTU
22
 *                                      code.
23
 *              Martin Mares    :       RFC1812 checks.
24
 *              Martin Mares    :       Can be configured to follow redirects
25
 *                                      if acting as a router _without_ a
26
 *                                      routing protocol (RFC 1812).
27
 *              Martin Mares    :       Echo requests may be configured to
28
 *                                      be ignored (RFC 1812).
29
 *              Martin Mares    :       Limitation of ICMP error message
30
 *                                      transmit rate (RFC 1812).
31
 *              Martin Mares    :       TOS and Precedence set correctly
32
 *                                      (RFC 1812).
33
 *              Martin Mares    :       Now copying as much data from the
34
 *                                      original packet as we can without
35
 *                                      exceeding 576 bytes (RFC 1812).
36
 *      Willy Konynenberg       :       Transparent proxying support.
37
 *              Keith Owens     :       RFC1191 correction for 4.2BSD based
38
 *                                      path MTU bug.
39
 *              Thomas Quinot   :       ICMP Dest Unreach codes up to 15 are
40
 *                                      valid (RFC 1812).
41
 *              Alan Cox        :       Spoofing and junk icmp protections.
42
 *              Elliot Poger    :       Added support for SO_BINDTODEVICE.
43
 *      Willy Konynenberg       :       Transparent proxy adapted to new
44
 *                                      socket hash code.
45
 *
46
 *
47
 * RFC1122 (Host Requirements -- Comm. Layer) Status:
48
 * (boy, are there a lot of rules for ICMP)
49
 *  3.2.2 (Generic ICMP stuff)
50
 *   MUST discard messages of unknown type. (OK)
51
 *   MUST copy at least the first 8 bytes from the offending packet
52
 *     when sending ICMP errors. (OBSOLETE -- see RFC1812)
53
 *   MUST pass received ICMP errors up to protocol level. (OK)
54
 *   SHOULD send ICMP errors with TOS == 0. (OBSOLETE -- see RFC1812)
55
 *   MUST NOT send ICMP errors in reply to:
56
 *     ICMP errors (OK)
57
 *     Broadcast/multicast datagrams (OK)
58
 *     MAC broadcasts (OK)
59
 *     Non-initial fragments (OK)
60
 *     Datagram with a source address that isn't a single host. (OK)
61
 *  3.2.2.1 (Destination Unreachable)
62
 *   All the rules govern the IP layer, and are dealt with in ip.c, not here.
63
 *  3.2.2.2 (Redirect)
64
 *   Host SHOULD NOT send ICMP_REDIRECTs.  (OK)
65
 *   MUST update routing table in response to host or network redirects.
66
 *     (host OK, network OBSOLETE)
67
 *   SHOULD drop redirects if they're not from directly connected gateway
68
 *     (OK -- we drop it if it's not from our old gateway, which is close
69
 *      enough)
70
 * 3.2.2.3 (Source Quench)
71
 *   MUST pass incoming SOURCE_QUENCHs to transport layer (OK)
72
 *   Other requirements are dealt with at the transport layer.
73
 * 3.2.2.4 (Time Exceeded)
74
 *   MUST pass TIME_EXCEEDED to transport layer (OK)
75
 *   Other requirements dealt with at IP (generating TIME_EXCEEDED).
76
 * 3.2.2.5 (Parameter Problem)
77
 *   SHOULD generate these (OK)
78
 *   MUST pass received PARAMPROBLEM to transport layer (NOT YET)
79
 *      [Solaris 2.X seems to assert EPROTO when this occurs] -- AC
80
 * 3.2.2.6 (Echo Request/Reply)
81
 *   MUST reply to ECHO_REQUEST, and give app to do ECHO stuff (OK, OK)
82
 *   MAY discard broadcast ECHO_REQUESTs. (We don't, but that's OK.)
83
 *   MUST reply using same source address as the request was sent to.
84
 *     We're OK for unicast ECHOs, and it doesn't say anything about
85
 *     how to handle broadcast ones, since it's optional.
86
 *   MUST copy data from REQUEST to REPLY (OK)
87
 *     unless it would require illegal fragmentation (OK)
88
 *   MUST pass REPLYs to transport/user layer (OK)
89
 *   MUST use any provided source route (reversed) for REPLY. (NOT YET)
90
 * 3.2.2.7 (Information Request/Reply)
91
 *   MUST NOT implement this. (I guess that means silently discard...?) (OK)
92
 * 3.2.2.8 (Timestamp Request/Reply)
93
 *   MAY implement (OK)
94
 *   SHOULD be in-kernel for "minimum variability" (OK)
95
 *   MAY discard broadcast REQUESTs.  (OK, but see source for inconsistency)
96
 *   MUST reply using same source address as the request was sent to. (OK)
97
 *   MUST reverse source route, as per ECHO (NOT YET)
98
 *   MUST pass REPLYs to transport/user layer (requires RAW, just like
99
 *      ECHO) (OK)
100
 *   MUST update clock for timestamp at least 15 times/sec (OK)
101
 *   MUST be "correct within a few minutes" (OK)
102
 * 3.2.2.9 (Address Mask Request/Reply)
103
 *   MAY implement (OK)
104
 *   MUST send a broadcast REQUEST if using this system to set netmask
105
 *     (OK... we don't use it)
106
 *   MUST discard received REPLYs if not using this system (OK)
107
 *   MUST NOT send replies unless specifically made agent for this sort
108
 *     of thing. (OK)
109
 *
110
 *
111
 * RFC 1812 (IPv4 Router Requirements) Status (even longer):
112
 *  4.3.2.1 (Unknown Message Types)
113
 *   MUST pass messages of unknown type to ICMP user iface or silently discard
114
 *     them (OK)
115
 *  4.3.2.2 (ICMP Message TTL)
116
 *   MUST initialize TTL when originating an ICMP message (OK)
117
 *  4.3.2.3 (Original Message Header)
118
 *   SHOULD copy as much data from the offending packet as possible without
119
 *     the length of the ICMP datagram exceeding 576 bytes (OK)
120
 *   MUST leave original IP header of the offending packet, but we're not
121
 *     required to undo modifications made (OK)
122
 *  4.3.2.4 (Original Message Source Address)
123
 *   MUST use one of addresses for the interface the orig. packet arrived as
124
 *     source address (OK)
125
 *  4.3.2.5 (TOS and Precedence)
126
 *   SHOULD leave TOS set to the same value unless the packet would be
127
 *     discarded for that reason (OK)
128
 *   MUST use TOS=0 if not possible to leave original value (OK)
129
 *   MUST leave IP Precedence for Source Quench messages (OK -- not sent
130
 *      at all)
131
 *   SHOULD use IP Precedence = 6 (Internetwork Control) or 7 (Network Control)
132
 *     for all other error messages (OK, we use 6)
133
 *   MAY allow configuration of IP Precedence (OK -- not done)
134
 *   MUST leave IP Precedence and TOS for reply messages (OK)
135
 *  4.3.2.6 (Source Route)
136
 *   SHOULD use reverse source route UNLESS sending Parameter Problem on source
137
 *     routing and UNLESS the packet would be immediately discarded (NOT YET)
138
 *  4.3.2.7 (When Not to Send ICMP Errors)
139
 *   MUST NOT send ICMP errors in reply to:
140
 *     ICMP errors (OK)
141
 *     Packets failing IP header validation tests unless otherwise noted (OK)
142
 *     Broadcast/multicast datagrams (OK)
143
 *     MAC broadcasts (OK)
144
 *     Non-initial fragments (OK)
145
 *     Datagram with a source address that isn't a single host. (OK)
146
 *  4.3.2.8 (Rate Limiting)
147
 *   SHOULD be able to limit error message rate (OK)
148
 *   SHOULD allow setting of rate limits (OK, in the source)
149
 *  4.3.3.1 (Destination Unreachable)
150
 *   All the rules govern the IP layer, and are dealt with in ip.c, not here.
151
 *  4.3.3.2 (Redirect)
152
 *   MAY ignore ICMP Redirects if running a routing protocol or if forwarding
153
 *     is enabled on the interface (OK -- ignores)
154
 *  4.3.3.3 (Source Quench)
155
 *   SHOULD NOT originate SQ messages (OK)
156
 *   MUST be able to limit SQ rate if originates them (OK as we don't
157
 *      send them)
158
 *   MAY ignore SQ messages it receives (OK -- we don't)
159
 *  4.3.3.4 (Time Exceeded)
160
 *   Requirements dealt with at IP (generating TIME_EXCEEDED).
161
 *  4.3.3.5 (Parameter Problem)
162
 *   MUST generate these for all errors not covered by other messages (OK)
163
 *   MUST include original value of the value pointed by (OK)
164
 *  4.3.3.6 (Echo Request)
165
 *   MUST implement echo server function (OK)
166
 *   MUST process at ER of at least max(576, MTU) (OK)
167
 *   MAY reject broadcast/multicast ER's (We don't, but that's OK)
168
 *   SHOULD have a config option for silently ignoring ER's (OK)
169
 *   MUST have a default value for the above switch = NO (OK)
170
 *   MUST have application layer interface for Echo Request/Reply (OK)
171
 *   MUST reply using same source address as the request was sent to.
172
 *     We're OK for unicast ECHOs, and it doesn't say anything about
173
 *     how to handle broadcast ones, since it's optional.
174
 *   MUST copy data from Request to Reply (OK)
175
 *   SHOULD update Record Route / Timestamp options (??)
176
 *   MUST use reversed Source Route for Reply if possible (NOT YET)
177
 *  4.3.3.7 (Information Request/Reply)
178
 *   SHOULD NOT originate or respond to these (OK)
179
 *  4.3.3.8 (Timestamp / Timestamp Reply)
180
 *   MAY implement (OK)
181
 *   MUST reply to every Timestamp message received (OK)
182
 *   MAY discard broadcast REQUESTs.  (OK, but see source for inconsistency)
183
 *   MUST reply using same source address as the request was sent to. (OK)
184
 *   MUST use reversed Source Route if possible (NOT YET)
185
 *   SHOULD update Record Route / Timestamp options (??)
186
 *   MUST pass REPLYs to transport/user layer (requires RAW, just like
187
 *      ECHO) (OK)
188
 *   MUST update clock for timestamp at least 16 times/sec (OK)
189
 *   MUST be "correct within a few minutes" (OK)
190
 * 4.3.3.9 (Address Mask Request/Reply)
191
 *   MUST have support for receiving AMRq and responding with AMRe (OK,
192
 *      but only as a compile-time option)
193
 *   SHOULD have option for each interface for AMRe's, MUST default to
194
 *      NO (NOT YET)
195
 *   MUST NOT reply to AMRq before knows the correct AM (OK)
196
 *   MUST NOT respond to AMRq with source address 0.0.0.0 on physical
197
 *      interfaces having multiple logical i-faces with different masks
198
 *      (NOT YET)
199
 *   SHOULD examine all AMRe's it receives and check them (NOT YET)
200
 *   SHOULD log invalid AMRe's (AM+sender) (NOT YET)
201
 *   MUST NOT use contents of AMRe to determine correct AM (OK)
202
 *   MAY broadcast AMRe's after having configured address masks (OK -- doesn't)
203
 *   MUST NOT do broadcast AMRe's if not set by extra option (OK, no option)
204
 *   MUST use the { <NetPrefix>, -1 } form of broadcast addresses (OK)
205
 * 4.3.3.10 (Router Advertisement and Solicitations)
206
 *   MUST support router part of Router Discovery Protocol on all networks we
207
 *     support broadcast or multicast addressing. (OK -- done by gated)
208
 *   MUST have all config parameters with the respective defaults (OK)
209
 * 5.2.7.1 (Destination Unreachable)
210
 *   MUST generate DU's (OK)
211
 *   SHOULD choose a best-match response code (OK)
212
 *   SHOULD NOT generate Host Isolated codes (OK)
213
 *   SHOULD use Communication Administratively Prohibited when administratively
214
 *     filtering packets (NOT YET -- bug-to-bug compatibility)
215
 *   MAY include config option for not generating the above and silently
216
 *      discard the packets instead (OK)
217
 *   MAY include config option for not generating Precedence Violation and
218
 *     Precedence Cutoff messages (OK as we don't generate them at all)
219
 *   MUST use Host Unreachable or Dest. Host Unknown codes whenever other hosts
220
 *     on the same network might be reachable (OK -- no net unreach's at all)
221
 *   MUST use new form of Fragmentation Needed and DF Set messages (OK)
222
 * 5.2.7.2 (Redirect)
223
 *   MUST NOT generate network redirects (OK)
224
 *   MUST be able to generate host redirects (OK)
225
 *   SHOULD be able to generate Host+TOS redirects (NO as we don't use TOS)
226
 *   MUST have an option to use Host redirects instead of Host+TOS ones (OK as
227
 *     no Host+TOS Redirects are used)
228
 *   MUST NOT generate redirects unless forwarding to the same i-face and the
229
 *     dest. address is on the same subnet as the src. address and no source
230
 *     routing is in use. (OK)
231
 *   MUST NOT follow redirects when using a routing protocol (OK)
232
 *   MAY use redirects if not using a routing protocol (OK, compile-time option)
233
 *   MUST comply to Host Requirements when not acting as a router (OK)
234
 *  5.2.7.3 (Time Exceeded)
235
 *   MUST generate Time Exceeded Code 0 when discarding packet due to TTL=0 (OK)
236
 *   MAY have a per-interface option to disable origination of TE messages, but
237
 *     it MUST default to "originate" (OK -- we don't support it)
238
 */
239
 
240
#include <linux/config.h>
241
#include <linux/types.h>
242
#include <linux/sched.h>
243
#include <linux/kernel.h>
244
#include <linux/fcntl.h>
245
#include <linux/socket.h>
246
#include <linux/in.h>
247
#include <linux/inet.h>
248
#include <linux/netdevice.h>
249
#include <linux/string.h>
250
#include <net/snmp.h>
251
#include <net/ip.h>
252
#include <net/route.h>
253
#include <net/protocol.h>
254
#include <net/icmp.h>
255
#include <net/tcp.h>
256
#include <net/udp.h>
257
#include <net/snmp.h>
258
#include <linux/skbuff.h>
259
#include <net/sock.h>
260
#include <linux/errno.h>
261
#include <linux/timer.h>
262
#include <asm/system.h>
263
#include <asm/segment.h>
264
#include <net/checksum.h>
265
 
266
#define min(a,b)        ((a)<(b)?(a):(b))
267
 
268
/*
269
 *      Statistics
270
 */
271
 
272
struct icmp_mib icmp_statistics;
273
 
274
/* An array of errno for error messages from dest unreach. */
275
/* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOS_UNREACH and SR_FAIELD MUST be considered 'transient errs'. */
276
 
277
struct icmp_err icmp_err_convert[] = {
278
  { ENETUNREACH,        0 },     /*      ICMP_NET_UNREACH        */
279
  { EHOSTUNREACH,       0 },     /*      ICMP_HOST_UNREACH       */
280
  { ENOPROTOOPT,        1 },    /*      ICMP_PROT_UNREACH       */
281
  { ECONNREFUSED,       1 },    /*      ICMP_PORT_UNREACH       */
282
  { EOPNOTSUPP,         0 },     /*      ICMP_FRAG_NEEDED        */
283
  { EOPNOTSUPP,         0 },     /*      ICMP_SR_FAILED          */
284
  { ENETUNREACH,        1 },    /*      ICMP_NET_UNKNOWN        */
285
  { EHOSTDOWN,          1 },    /*      ICMP_HOST_UNKNOWN       */
286
  { ENONET,             1 },    /*      ICMP_HOST_ISOLATED      */
287
  { ENETUNREACH,        1 },    /*      ICMP_NET_ANO            */
288
  { EHOSTUNREACH,       1 },    /*      ICMP_HOST_ANO           */
289
  { ENETUNREACH,        0 },     /*      ICMP_NET_UNR_TOS        */
290
  { EHOSTUNREACH,       0 },     /*      ICMP_HOST_UNR_TOS       */
291
  { EHOSTUNREACH,       1 },    /*      ICMP_PKT_FILTERED       */
292
  { EHOSTUNREACH,       1 },    /*      ICMP_PREC_VIOLATION     */
293
  { EHOSTUNREACH,       1 }     /*      ICMP_PREC_CUTOFF        */
294
};
295
 
296
/*
297
 *      A spare long used to speed up statistics updating
298
 */
299
 
300
unsigned long dummy;
301
 
302
/*
303
 *      ICMP transmit rate limit control structures. We use a relatively simple
304
 *      approach to the problem: For each type of ICMP message with rate limit
305
 *      we count the number of messages sent during some time quantum. If this
306
 *      count exceeds given maximal value, we ignore all messages not separated
307
 *      from the last message sent at least by specified time.
308
 */
309
 
310
#define XRLIM_CACHE_SIZE 16             /* How many destination hosts do we cache */
311
 
312
struct icmp_xrl_cache                   /* One entry of the ICMP rate cache */
313
{
314
        __u32 daddr;                    /* Destination address */
315
        unsigned long counter;          /* Message counter */
316
        unsigned long next_reset;       /* Time of next reset of the counter */
317
        unsigned long last_access;      /* Time of last access to this entry (LRU) */
318
        unsigned int restricted;        /* Set if we're in restricted mode */
319
        unsigned long next_packet;      /* When we'll allow a next packet if restricted */
320
};
321
 
322
struct icmp_xrlim
323
{
324
        unsigned long timeout;          /* Time quantum for rate measuring */
325
        unsigned long limit;            /* Maximal number of messages per time quantum allowed */
326
        unsigned long delay;            /* How long we wait between packets when restricting */
327
        struct icmp_xrl_cache cache[XRLIM_CACHE_SIZE];  /* Rate cache */
328
};
329
 
330
/*
331
 *      ICMP control array. This specifies what to do with each ICMP.
332
 */
333
 
334
struct icmp_control
335
{
336
        unsigned long *output;          /* Address to increment on output */
337
        unsigned long *input;           /* Address to increment on input */
338
        void (*handler)(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len);
339
        unsigned long error;            /* This ICMP is classed as an error message */
340
        struct icmp_xrlim *xrlim;       /* Transmit rate limit control structure or NULL for no limits */
341
};
342
 
343
static struct icmp_control icmp_pointers[19];
344
 
345
/*
346
 *      Build xmit assembly blocks
347
 */
348
 
349
struct icmp_bxm
350
{
351
        void *data_ptr;
352
        int data_len;
353
        struct icmphdr icmph;
354
        unsigned long csum;
355
        struct options replyopts;
356
        unsigned char  optbuf[40];
357
};
358
 
359
/*
360
 *      The ICMP socket. This is the most convenient way to flow control
361
 *      our ICMP output as well as maintain a clean interface throughout
362
 *      all layers. All Socketless IP sends will soon be gone.
363
 */
364
 
365
struct socket icmp_socket;
366
 
367
/*
368
 *      Send an ICMP frame.
369
 */
370
 
371
 
372
/*
373
 *      Initialize the transmit rate limitation mechanism.
374
 */
375
 
376
#ifndef CONFIG_NO_ICMP_LIMIT
377
 
378
static void xrlim_init(void)
379
{
380
        int type, entry;
381
        struct icmp_xrlim *xr;
382
 
383
        for (type=0; type<=18; type++) {
384
                xr = icmp_pointers[type].xrlim;
385
                if (xr) {
386
                        for (entry=0; entry<XRLIM_CACHE_SIZE; entry++)
387
                                xr->cache[entry].daddr = INADDR_NONE;
388
                }
389
        }
390
}
391
 
392
/*
393
 *      Check transmit rate limitation for given message.
394
 *
395
 *      RFC 1812: 4.3.2.8 SHOULD be able to limit error message rate
396
 *                        SHOULD allow setting of rate limits (we allow
397
 *                        in the source)
398
 */
399
 
400
static int xrlim_allow(int type, __u32 addr)
401
{
402
        struct icmp_xrlim *r;
403
        struct icmp_xrl_cache *c;
404
        unsigned long now;
405
 
406
        if (type > 18)                  /* No time limit present */
407
                return 1;
408
        r = icmp_pointers[type].xrlim;
409
        if (!r)
410
                return 1;
411
 
412
        for (c = r->cache; c < &r->cache[XRLIM_CACHE_SIZE]; c++)
413
          /* Cache lookup */
414
                if (c->daddr == addr)
415
                        break;
416
 
417
        now = jiffies;          /* Cache current time (saves accesses to volatile variable) */
418
 
419
        if (c == &r->cache[XRLIM_CACHE_SIZE]) {         /* Cache miss */
420
                unsigned long oldest = now;             /* Find the oldest entry to replace */
421
                struct icmp_xrl_cache *d;
422
                c = r->cache;
423
                for (d = r->cache; d < &r->cache[XRLIM_CACHE_SIZE]; d++)
424
                        if (!d->daddr) {                /* Unused entry */
425
                                c = d;
426
                                break;
427
                        } else if (d->last_access < oldest) {
428
                                oldest = d->last_access;
429
                                c = d;
430
                        }
431
                c->last_access = now;                   /* Fill the entry with new data */
432
                c->daddr = addr;
433
                c->counter = 1;
434
                c->next_reset = now + r->timeout;
435
                c->restricted = 0;
436
                return 1;
437
        }
438
 
439
        c->last_access = now;
440
        if (c->next_reset > now) {                      /* Let's increment the counter */
441
                c->counter++;
442
                if (c->counter == r->limit) {           /* Limit exceeded, start restrictions */
443
                        c->restricted = 1;
444
                        c->next_packet = now + r->delay;
445
                        return 0;
446
                }
447
                if (c->restricted) {                    /* Any restrictions pending? */
448
                        if (c->next_packet > now)
449
                                return 0;
450
                        c->next_packet = now + r->delay;
451
                        return 1;
452
                }
453
        } else {                                        /* Reset the counter */
454
                if (c->counter < r->limit)              /* Switch off all restrictions */
455
                        c->restricted = 0;
456
                c->next_reset = now + r->timeout;
457
                c->counter = 0;
458
        }
459
 
460
        return 1;                                       /* Send the packet */
461
}
462
 
463
#endif /* CONFIG_NO_ICMP_LIMIT */
464
 
465
/*
466
 *      Maintain the counters used in the SNMP statistics for outgoing ICMP
467
 */
468
 
469
static void icmp_out_count(int type)
470
{
471
        if(type>18)
472
                return;
473
        (*icmp_pointers[type].output)++;
474
        icmp_statistics.IcmpOutMsgs++;
475
}
476
 
477
/*
478
 *      Checksum each fragment, and on the first include the headers and final checksum.
479
 */
480
 
481
static void icmp_glue_bits(const void *p, __u32 saddr, char *to, unsigned int offset, unsigned int fraglen)
482
{
483
        struct icmp_bxm *icmp_param = (struct icmp_bxm *)p;
484
        struct icmphdr *icmph;
485
        unsigned long csum;
486
 
487
        if (offset) {
488
                icmp_param->csum=csum_partial_copy(icmp_param->data_ptr+offset-sizeof(struct icmphdr),
489
                                to, fraglen,icmp_param->csum);
490
                return;
491
        }
492
 
493
        /*
494
         *      First fragment includes header. Note that we've done
495
         *      the other fragments first, so that we get the checksum
496
         *      for the whole packet here.
497
         */
498
        csum = csum_partial_copy((void *)&icmp_param->icmph,
499
                to, sizeof(struct icmphdr),
500
                icmp_param->csum);
501
        csum = csum_partial_copy(icmp_param->data_ptr,
502
                to+sizeof(struct icmphdr),
503
                fraglen-sizeof(struct icmphdr), csum);
504
        icmph=(struct icmphdr *)to;
505
        icmph->checksum = csum_fold(csum);
506
}
507
 
508
/*
509
 *      Driving logic for building and sending ICMP messages.
510
 */
511
 
512
static void icmp_build_xmit(struct icmp_bxm *icmp_param, __u32 saddr, __u32 daddr, __u8 tos)
513
{
514
        struct sock *sk=icmp_socket.data;
515
        icmp_param->icmph.checksum=0;
516
        icmp_param->csum=0;
517
        icmp_out_count(icmp_param->icmph.type);
518
        sk->ip_tos = tos;
519
        ip_build_xmit(sk, icmp_glue_bits, icmp_param,
520
                icmp_param->data_len+sizeof(struct icmphdr),
521
                daddr, saddr, &icmp_param->replyopts, 0, IPPROTO_ICMP, 1);
522
}
523
 
524
 
525
/*
526
 *      Send an ICMP message in response to a situation
527
 *
528
 *      RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we do).
529
 *                      MUST NOT change this header information.
530
 *                      MUST NOT reply to a multicast/broadcast IP address.
531
 *                      MUST NOT reply to a multicast/broadcast MAC address.
532
 *                      MUST reply to only the first fragment.
533
 */
534
 
535
void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, struct device *dev)
536
{
537
        struct iphdr *iph;
538
        struct icmphdr *icmph;
539
        int atype, room;
540
        struct icmp_bxm icmp_param;
541
        __u32 saddr;
542
 
543
        /*
544
         *      Find the original header
545
         */
546
 
547
        iph = skb_in->ip_hdr;
548
 
549
        /*
550
         *      No replies to physical multicast/broadcast
551
         */
552
 
553
        if(skb_in->pkt_type!=PACKET_HOST)
554
                return;
555
 
556
        /*
557
         *      Now check at the protocol level
558
         */
559
 
560
        atype=ip_chk_addr(iph->daddr);
561
        if(atype==IS_BROADCAST||atype==IS_MULTICAST)
562
                return;
563
 
564
        /*
565
         *      Only reply to fragment 0. We byte re-order the constant
566
         *      mask for efficiency.
567
         */
568
 
569
        if(iph->frag_off&htons(IP_OFFSET))
570
                return;
571
 
572
        /*
573
         *      If we send an ICMP error to an ICMP error a mess would result..
574
         */
575
 
576
        if(icmp_pointers[type].error)
577
        {
578
                /*
579
                 *      We are an error, check if we are replying to an ICMP error
580
                 */
581
 
582
                if(iph->protocol==IPPROTO_ICMP)
583
                {
584
                        icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2));
585
                        /*
586
                         *      Assume any unknown ICMP type is an error. This isn't
587
                         *      specified by the RFC, but think about it..
588
                         */
589
                        if(icmph->type>18 || icmp_pointers[icmph->type].error)
590
                                return;
591
                }
592
        }
593
 
594
        /*
595
         *      Check the rate limit
596
         */
597
 
598
#ifndef CONFIG_NO_ICMP_LIMIT
599
        if (!xrlim_allow(type, iph->saddr))
600
                return;
601
#endif  
602
 
603
        /*
604
         *      Construct source address and options.
605
         */
606
 
607
        saddr=iph->daddr;
608
        if(saddr!=dev->pa_addr && ip_chk_addr(saddr)!=IS_MYADDR)
609
                saddr=dev->pa_addr;
610
        if(ip_options_echo(&icmp_param.replyopts, NULL, saddr, iph->saddr, skb_in))
611
                return;
612
 
613
        /*
614
         *      Prepare data for ICMP header.
615
         */
616
 
617
        icmp_param.icmph.type=type;
618
        icmp_param.icmph.code=code;
619
        icmp_param.icmph.un.gateway = info;
620
        icmp_param.data_ptr=iph;
621
        room = 576 - sizeof(struct iphdr) - icmp_param.replyopts.optlen;
622
        icmp_param.data_len=(iph->ihl<<2)+skb_in->len;  /* RFC says return as much as we can without exceeding 576 bytes */
623
        if (icmp_param.data_len > room)
624
                icmp_param.data_len = room;
625
 
626
        /*
627
         *      Build and send the packet.
628
         */
629
 
630
        icmp_build_xmit(&icmp_param, saddr, iph->saddr,
631
                        icmp_pointers[type].error ?
632
                        (iph->tos & 0x1E) | 0xC0 : iph->tos);
633
}
634
 
635
 
636
/*
637
 *      Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, and ICMP_QUENCH.
638
 */
639
 
640
static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
641
{
642
        struct iphdr *iph;
643
        int hash;
644
        struct inet_protocol *ipprot;
645
        unsigned char *dp;
646
        int match_addr=0;
647
 
648
        if(len<sizeof(struct iphdr))
649
                goto flush_it;
650
 
651
        iph = (struct iphdr *) (icmph + 1);
652
 
653
        len-=iph->ihl<<2;
654
        if(len<0)
655
                goto flush_it;
656
 
657
        dp= ((unsigned char *)iph)+(iph->ihl<<2);
658
 
659
        if(icmph->type==ICMP_DEST_UNREACH)
660
        {
661
                switch(icmph->code & 15)
662
                {
663
                        case ICMP_NET_UNREACH:
664
                                break;
665
                        case ICMP_HOST_UNREACH:
666
                                break;
667
                        case ICMP_PROT_UNREACH:
668
                                NETDEBUG(printk(KERN_INFO "ICMP: %s:%d: protocol unreachable.\n",
669
                                        in_ntoa(iph->daddr), (int)iph->protocol));
670
                        /* Drop through */
671
                        case ICMP_PORT_UNREACH:
672
                                match_addr=1;
673
                                break;
674
                        case ICMP_FRAG_NEEDED:
675
#ifdef CONFIG_NO_PATH_MTU_DISCOVERY
676
                                NETDEBUG(printk(KERN_INFO "ICMP: %s: fragmentation needed and DF set.\n",
677
                                                                in_ntoa(iph->daddr)));
678
                                break;
679
#else
680
                        {
681
                                unsigned short old_mtu = ntohs(iph->tot_len);
682
                                unsigned short new_mtu = ntohs(icmph->un.echo.sequence);
683
 
684
                                /*
685
                                 * RFC1191 5.  4.2BSD based router can return incorrect
686
                                 * Total Length.  If current mtu is unknown or old_mtu
687
                                 * is not less than current mtu, reduce old_mtu by 4 times
688
                                 * the header length.
689
                                 */
690
 
691
                                if (skb->sk == NULL /* can this happen? */
692
                                        || skb->sk->ip_route_cache == NULL
693
                                        || skb->sk->ip_route_cache->rt_mtu <= old_mtu)
694
                                {
695
                                        NETDEBUG(printk(KERN_INFO "4.2BSD based fragmenting router between here and %s, mtu corrected from %d", in_ntoa(iph->daddr), old_mtu));
696
                                        old_mtu -= 4 * iph->ihl;
697
                                        NETDEBUG(printk(" to %d\n", old_mtu));
698
                                }
699
 
700
                                if (new_mtu < 68 || new_mtu >= old_mtu)
701
                                {
702
                                        /*
703
                                         *      It is either dumb router, which does not
704
                                         *      understand Path MTU Disc. protocol
705
                                         *      or broken (f.e. Linux<=1.3.37 8) router.
706
                                         *      Try to guess...
707
                                         *      The table is taken from RFC-1191.
708
                                         */
709
                                        if (old_mtu > 32000)
710
                                                new_mtu = 32000;
711
                                        else if (old_mtu > 17914)
712
                                                new_mtu = 17914;
713
                                        else if (old_mtu > 8166)
714
                                                new_mtu = 8166;
715
                                        else if (old_mtu > 4352)
716
                                                new_mtu = 4352;
717
                                        else if (old_mtu > 2002)
718
                                                new_mtu = 2002;
719
                                        else if (old_mtu > 1492)
720
                                                new_mtu = 1492;
721
                                        else if (old_mtu > 576)
722
                                                new_mtu = 576;
723
                                        else if (old_mtu > 296)
724
                                                new_mtu = 296;
725
                                        /*
726
                                         *      These two are not from the RFC but
727
                                         *      are needed for AMPRnet AX.25 paths.
728
                                         */
729
                                        else if (old_mtu > 216)
730
                                                new_mtu = 216;
731
                                        else if (old_mtu > 128)
732
                                                new_mtu = 128;
733
                                        else
734
                                        /*
735
                                         *      Despair..
736
                                         */
737
                                                new_mtu = 68;
738
                                }
739
                                /*
740
                                 * Ugly trick to pass MTU to protocol layer.
741
                                 * Really we should add argument "info" to error handler.
742
                                 */
743
                                iph->id = htons(new_mtu);
744
                                break;
745
                        }
746
#endif
747
                        case ICMP_SR_FAILED:
748
                                NETDEBUG(printk(KERN_INFO "ICMP: %s: Source Route Failed.\n", in_ntoa(iph->daddr)));
749
                                break;
750
                        default:
751
                                break;
752
                }
753
                if(icmph->code>NR_ICMP_UNREACH) /* Invalid type */
754
                        goto flush_it;
755
        }
756
 
757
        /*
758
         *      Throw it at our lower layers
759
         *
760
         *      RFC 1122: 3.2.2 MUST extract the protocol ID from the passed header.
761
         *      RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the transport layer.
762
         *      RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to transport layer.
763
         *
764
         *      Rule: Require port unreachable and protocol unreachable come
765
         *              from the host in question. Stop junk spoofs.
766
         */
767
 
768
        if(!match_addr || saddr == iph->daddr)
769
        {
770
                /*
771
                 *      Get the protocol(s).
772
                 */
773
 
774
                hash = iph->protocol & (MAX_INET_PROTOS -1);
775
 
776
                /*
777
                 *      This can't change while we are doing it.
778
                 */
779
 
780
                ipprot = (struct inet_protocol *) inet_protos[hash];
781
                while(ipprot != NULL)
782
                {
783
                        struct inet_protocol *nextip;
784
 
785
                        nextip = (struct inet_protocol *) ipprot->next;
786
 
787
                        /*
788
                         *      Pass it off to everyone who wants it.
789
                         */
790
 
791
                        /* RFC1122: OK. Passes appropriate ICMP errors to the */
792
                        /* appropriate protocol layer (MUST), as per 3.2.2. */
793
 
794
                        if (iph->protocol == ipprot->protocol && ipprot->err_handler)
795
                        {
796
                                ipprot->err_handler(icmph->type, icmph->code, dp,
797
                                            iph->daddr, iph->saddr, ipprot, len);
798
                        }
799
 
800
                        ipprot = nextip;
801
                }
802
        }
803
flush_it:
804
        kfree_skb(skb, FREE_READ);
805
}
806
 
807
 
808
/*
809
 *      Handle ICMP_REDIRECT.
810
 */
811
 
812
static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 source, __u32 daddr, int len)
813
{
814
        struct iphdr *iph;
815
        unsigned long ip;
816
 
817
        /*
818
         *      Get the copied header of the packet that caused the redirect
819
         */
820
 
821
        if(len<=sizeof(struct iphdr))
822
                goto flush_it;
823
 
824
        iph = (struct iphdr *) (icmph + 1);
825
        ip = iph->daddr;
826
 
827
        /*
828
         *      If we are a router and we run a routing protocol, we MUST NOT follow redirects.
829
         *      When using no routing protocol, we MAY follow redirects. (RFC 1812, 5.2.7.2)
830
         */
831
 
832
#if !defined(CONFIG_IP_DUMB_ROUTER)
833
        if (sysctl_ip_forward) {
834
        NETDEBUG(printk(KERN_INFO "icmp: ICMP redirect ignored. dest = %lX, "
835
               "orig gw = %lX, \"new\" gw = %lX, device = %s.\n", ntohl(ip),
836
                ntohl(source), ntohl(icmph->un.gateway), dev->name));
837
                goto flush_it;
838
        }
839
#endif
840
        switch(icmph->code & 7)
841
        {
842
                case ICMP_REDIR_NET:
843
                        /*
844
                         *      This causes a problem with subnetted networks. What we should do
845
                         *      is use ICMP_ADDRESS to get the subnet mask of the problem route
846
                         *      and set both. But we don't.. [RFC1812 says routers MUST NOT
847
                         *      generate Network Redirects]
848
                         */
849
#ifdef not_a_good_idea
850
                        ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
851
                                ip, 0, icmph->un.gateway, dev,0, 0, 0);
852
#endif
853
                        /*
854
                         *      As per RFC recommendations now handle it as
855
                         *      a host redirect.
856
                         */
857
 
858
                case ICMP_REDIR_HOST:
859
                        /*
860
                         *      Add better route to host.
861
                         *      But first check that the redirect
862
                         *      comes from the old gateway..
863
                         *      And make sure it's an ok host address
864
                         *      (not some confused thing sending our
865
                         *      address)
866
                         */
867
                        NETDEBUG(printk(KERN_INFO "ICMP redirect from %s\n", in_ntoa(source)));
868
                        ip_rt_redirect(source, ip, icmph->un.gateway, dev);
869
                        break;
870
                case ICMP_REDIR_NETTOS:
871
                case ICMP_REDIR_HOSTTOS:
872
                        NETDEBUG(printk(KERN_INFO "ICMP: cannot handle TOS redirects yet!\n"));
873
                        break;
874
                default:
875
                        break;
876
        }
877
 
878
        /*
879
         *      Discard the original packet
880
         */
881
flush_it:
882
        kfree_skb(skb, FREE_READ);
883
}
884
 
885
/*
886
 *      Handle ICMP_ECHO ("ping") requests.
887
 *
888
 *      RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo requests.
889
 *      RFC 1122: 3.2.2.6 Data received in the ICMP_ECHO request MUST be included in the reply.
890
 *      RFC 1812: 4.3.3.6 SHOULD have a config option for silently ignoring echo requests, MUST have default=NOT.
891
 *      See also WRT handling of options once they are done and working.
892
 */
893
 
894
static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
895
{
896
#ifndef CONFIG_IP_IGNORE_ECHO_REQUESTS
897
        struct icmp_bxm icmp_param;
898
        icmp_param.icmph=*icmph;
899
        icmp_param.icmph.type=ICMP_ECHOREPLY;
900
        icmp_param.data_ptr=(icmph+1);
901
        icmp_param.data_len=len;
902
        if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
903
                icmp_build_xmit(&icmp_param, daddr, saddr, skb->ip_hdr->tos);
904
#endif
905
        kfree_skb(skb, FREE_READ);
906
}
907
 
908
/*
909
 *      Handle ICMP Timestamp requests.
910
 *      RFC 1122: 3.2.2.8 MAY implement ICMP timestamp requests.
911
 *                SHOULD be in the kernel for minimum random latency.
912
 *                MUST be accurate to a few minutes.
913
 *                MUST be updated at least at 15Hz.
914
 */
915
 
916
static void icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
917
{
918
        __u32 times[3];         /* So the new timestamp works on ALPHA's.. */
919
        struct icmp_bxm icmp_param;
920
 
921
        /*
922
         *      Too short.
923
         */
924
 
925
        if(len<12)
926
        {
927
                icmp_statistics.IcmpInErrors++;
928
                kfree_skb(skb, FREE_READ);
929
                return;
930
        }
931
 
932
        /*
933
         *      Fill in the current time as ms since midnight UT:
934
         */
935
 
936
        {
937
                struct timeval tv;
938
                do_gettimeofday(&tv);
939
                times[1] = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
940
        }
941
        times[2] = times[1];
942
        memcpy((void *)&times[0], icmph+1, 4);           /* Incoming stamp */
943
        icmp_param.icmph=*icmph;
944
        icmp_param.icmph.type=ICMP_TIMESTAMPREPLY;
945
        icmp_param.icmph.code=0;
946
        icmp_param.data_ptr=&times;
947
        icmp_param.data_len=12;
948
        if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
949
                icmp_build_xmit(&icmp_param, daddr, saddr, skb->ip_hdr->tos);
950
        kfree_skb(skb,FREE_READ);
951
}
952
 
953
 
954
/*
955
 *      Handle ICMP_ADDRESS_MASK requests.  (RFC950)
956
 *
957
 * RFC1122 (3.2.2.9).  A host MUST only send replies to
958
 * ADDRESS_MASK requests if it's been configured as an address mask
959
 * agent.  Receiving a request doesn't constitute implicit permission to
960
 * act as one. Of course, implementing this correctly requires (SHOULD)
961
 * a way to turn the functionality on and off.  Another one for sysctl(),
962
 * I guess. -- MS
963
 * Botched with a CONFIG option for now - Linus add scts sysctl please..
964
 */
965
 
966
static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
967
{
968
#ifdef CONFIG_IP_ADDR_AGENT     /* Don't use, broken */
969
        struct icmp_bxm icmp_param;
970
        icmp_param.icmph.type=ICMP_ADDRESSREPLY;
971
        icmp_param.icmph.code=0;
972
        icmp_param.icmph.un.echo.id = icmph->un.echo.id;
973
        icmp_param.icmph.un.echo.sequence = icmph->un.echo.sequence;
974
        icmp_param.data_ptr=&dev->pa_mask;
975
        icmp_param.data_len=4;
976
        if (ip_options_echo(&icmp_param.replyopts, NULL, daddr, saddr, skb)==0)
977
                icmp_build_xmit(&icmp_param, daddr, saddr, skb->iph->tos);
978
#endif  
979
        kfree_skb(skb, FREE_READ);
980
}
981
 
982
static void icmp_discard(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len)
983
{
984
        kfree_skb(skb, FREE_READ);
985
}
986
 
987
#ifdef CONFIG_IP_TRANSPARENT_PROXY
988
/*
989
 *      Check incoming icmp packets not addressed locally, to check whether
990
 *      they relate to a (proxying) socket on our system.
991
 *      Needed for transparent proxying.
992
 *
993
 *      This code is presently ugly and needs cleanup.
994
 *      Probably should add a chkaddr entry to ipprot to call a chk routine
995
 *      in udp.c or tcp.c...
996
 */
997
 
998
extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, struct device *dev);
999
extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, struct device *dev);
1000
 
1001
int icmp_chkaddr(struct sk_buff *skb)
1002
{
1003
        struct icmphdr *icmph=(struct icmphdr *)(skb->h.raw + skb->h.iph->ihl*4);
1004
        struct iphdr *iph = (struct iphdr *) (icmph + 1);
1005
        void (*handler)(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, __u32 saddr, __u32 daddr, int len) = icmp_pointers[icmph->type].handler;
1006
 
1007
        if (handler == icmp_unreach || handler == icmp_redirect) {
1008
                struct sock *sk;
1009
 
1010
                switch (iph->protocol) {
1011
                case IPPROTO_TCP:
1012
                        {
1013
                        struct tcphdr *th = (struct tcphdr *)(((unsigned char *)iph)+(iph->ihl<<2));
1014
 
1015
                        sk = tcp_v4_lookup(iph->saddr, th->source, iph->daddr, th->dest, skb->dev);
1016
                        if (!sk) return 0;
1017
                        if (sk->saddr != iph->saddr) return 0;
1018
                        if (sk->daddr != iph->daddr) return 0;
1019
                        if (sk->dummy_th.dest != th->dest) return 0;
1020
                        /*
1021
                         * This packet came from us.
1022
                         */
1023
                        return 1;
1024
                        }
1025
                case IPPROTO_UDP:
1026
                        {
1027
                        struct udphdr *uh = (struct udphdr *)(((unsigned char *)iph)+(iph->ihl<<2));
1028
 
1029
                        sk = udp_v4_lookup(iph->saddr, uh->source, iph->daddr, uh->dest, skb->dev);
1030
                        if (!sk) return 0;
1031
                        if (sk->saddr != iph->saddr && ip_chk_addr(iph->saddr) != IS_MYADDR)
1032
                                return 0;
1033
                        /*
1034
                         * This packet may have come from us.
1035
                         * Assume it did.
1036
                         */
1037
                        return 1;
1038
                        }
1039
                }
1040
        }
1041
        return 0;
1042
}
1043
 
1044
#endif
1045
/*
1046
 *      Deal with incoming ICMP packets.
1047
 */
1048
 
1049
int icmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
1050
         __u32 daddr, unsigned short len,
1051
         __u32 saddr, int redo, struct inet_protocol *protocol)
1052
{
1053
        struct icmphdr *icmph=(void *)skb->h.raw;
1054
#ifdef CONFIG_IP_TRANSPARENT_PROXY
1055
        int r;
1056
#endif
1057
        icmp_statistics.IcmpInMsgs++;
1058
 
1059
        if(len < sizeof(struct icmphdr))
1060
        {
1061
                icmp_statistics.IcmpInErrors++;
1062
                NETDEBUG(printk(KERN_INFO "ICMP: runt packet\n"));
1063
                kfree_skb(skb, FREE_READ);
1064
                return 0;
1065
        }
1066
 
1067
        /*
1068
         *      Validate the packet
1069
         */
1070
 
1071
        if (ip_compute_csum((unsigned char *) icmph, len))
1072
        {
1073
                /* Failed checksum! */
1074
                icmp_statistics.IcmpInErrors++;
1075
                NETDEBUG(printk(KERN_INFO "ICMP: failed checksum from %s!\n", in_ntoa(saddr)));
1076
                kfree_skb(skb, FREE_READ);
1077
                return(0);
1078
        }
1079
 
1080
        /*
1081
         *      18 is the highest 'known' ICMP type. Anything else is a mystery
1082
         *
1083
         *      RFC 1122: 3.2.2  Unknown ICMP messages types MUST be silently discarded.
1084
         */
1085
 
1086
        if(icmph->type > 18)
1087
        {
1088
                icmp_statistics.IcmpInErrors++;         /* Is this right - or do we ignore ? */
1089
                kfree_skb(skb,FREE_READ);
1090
                return(0);
1091
        }
1092
 
1093
        /*
1094
         *      Parse the ICMP message
1095
         */
1096
 
1097
#ifdef CONFIG_IP_TRANSPARENT_PROXY
1098
        /*
1099
         *      We may get non-local addresses and still want to handle them
1100
         *      locally, due to transparent proxying.
1101
         *      Thus, narrow down the test to what is really meant.
1102
         */
1103
        if (daddr!=dev->pa_addr && ((r = ip_chk_addr(daddr)) == IS_BROADCAST || r == IS_MULTICAST))
1104
#else
1105
        if (daddr!=dev->pa_addr && ip_chk_addr(daddr) != IS_MYADDR)
1106
#endif
1107
        {
1108
                /*
1109
                 *      RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be silently ignored (we don't as it is used
1110
                 *      by some network mapping tools).
1111
                 *      RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently discarded if to broadcast/multicast.
1112
                 */
1113
                if (icmph->type != ICMP_ECHO)
1114
                {
1115
                        icmp_statistics.IcmpInErrors++;
1116
                        kfree_skb(skb, FREE_READ);
1117
                        return(0);
1118
                }
1119
                /*
1120
                 *      Reply the multicast/broadcast using a legal
1121
                 *      interface - in this case the device we got
1122
                 *      it from.
1123
                 */
1124
                daddr=dev->pa_addr;
1125
        }
1126
 
1127
        len-=sizeof(struct icmphdr);
1128
        (*icmp_pointers[icmph->type].input)++;
1129
        (icmp_pointers[icmph->type].handler)(icmph,skb,skb->dev,saddr,daddr,len);
1130
        return 0;
1131
}
1132
 
1133
/*
1134
 *      This table defined limits of ICMP sending rate for various ICMP messages.
1135
 */
1136
 
1137
static struct icmp_xrlim
1138
        xrl_unreach = { 4*HZ, 80, HZ/4 },               /* Host Unreachable */
1139
        xrl_redirect = { 2*HZ, 10, HZ/2 },              /* Redirect */
1140
        xrl_generic = { 3*HZ, 30, HZ/4 };               /* All other errors */
1141
 
1142
/*
1143
 *      This table is the definition of how we handle ICMP.
1144
 */
1145
 
1146
static struct icmp_control icmp_pointers[19] = {
1147
/* ECHO REPLY (0) */
1148
 { &icmp_statistics.IcmpOutEchoReps, &icmp_statistics.IcmpInEchoReps, icmp_discard, 0, NULL },
1149
 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
1150
 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
1151
/* DEST UNREACH (3) */
1152
 { &icmp_statistics.IcmpOutDestUnreachs, &icmp_statistics.IcmpInDestUnreachs, icmp_unreach, 1, &xrl_unreach },
1153
/* SOURCE QUENCH (4) */
1154
 { &icmp_statistics.IcmpOutSrcQuenchs, &icmp_statistics.IcmpInSrcQuenchs, icmp_unreach, 1, NULL },
1155
/* REDIRECT (5) */
1156
 { &icmp_statistics.IcmpOutRedirects, &icmp_statistics.IcmpInRedirects, icmp_redirect, 1, &xrl_redirect },
1157
 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
1158
 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
1159
/* ECHO (8) */
1160
 { &icmp_statistics.IcmpOutEchos, &icmp_statistics.IcmpInEchos, icmp_echo, 0, NULL },
1161
 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
1162
 { &dummy, &icmp_statistics.IcmpInErrors, icmp_discard, 1, NULL },
1163
/* TIME EXCEEDED (11) */
1164
 { &icmp_statistics.IcmpOutTimeExcds, &icmp_statistics.IcmpInTimeExcds, icmp_unreach, 1, &xrl_generic },
1165
/* PARAMETER PROBLEM (12) */
1166
/* FIXME: RFC1122 3.2.2.5 - MUST pass PARAM_PROB messages to transport layer */
1167
 { &icmp_statistics.IcmpOutParmProbs, &icmp_statistics.IcmpInParmProbs, icmp_discard, 1, &xrl_generic },
1168
/* TIMESTAMP (13) */
1169
 { &icmp_statistics.IcmpOutTimestamps, &icmp_statistics.IcmpInTimestamps, icmp_timestamp, 0, NULL },
1170
/* TIMESTAMP REPLY (14) */
1171
 { &icmp_statistics.IcmpOutTimestampReps, &icmp_statistics.IcmpInTimestampReps, icmp_discard, 0, NULL },
1172
/* INFO (15) */
1173
 { &dummy, &dummy, icmp_discard, 0, NULL },
1174
/* INFO REPLY (16) */
1175
 { &dummy, &dummy, icmp_discard, 0, NULL },
1176
/* ADDR MASK (17) */
1177
 { &icmp_statistics.IcmpOutAddrMasks, &icmp_statistics.IcmpInAddrMasks, icmp_address, 0, NULL },
1178
/* ADDR MASK REPLY (18) */
1179
 { &icmp_statistics.IcmpOutAddrMaskReps, &icmp_statistics.IcmpInAddrMaskReps, icmp_discard, 0, NULL }
1180
};
1181
 
1182
void icmp_init(struct proto_ops *ops)
1183
{
1184
        struct sock *sk;
1185
        int err;
1186
        icmp_socket.type=SOCK_RAW;
1187
        icmp_socket.ops=ops;
1188
        if((err=ops->create(&icmp_socket, IPPROTO_ICMP))<0)
1189
                panic("Failed to create the ICMP control socket.\n");
1190
        sk=icmp_socket.data;
1191
        sk->allocation=GFP_ATOMIC;
1192
        sk->num = 256;                  /* Don't receive any data */
1193
#ifndef CONFIG_NO_ICMP_LIMIT
1194
        xrlim_init();
1195
#endif
1196
}
1197
 

powered by: WebSVN 2.1.0

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