1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Based on net/ipv6/icmp.c
4 * Authors:
5 * Pedro Roque <roque@di.fc.ul.pt>
6 *
7 * Changes:
8 *
9 * Andi Kleen : exception handling
10 * Andi Kleen add rate limits. never reply to a icmp.
11 * add more length checks and other fixes.
12 * yoshfuji : ensure to sent parameter problem for
13 * fragments.
14 * YOSHIFUJI Hideaki @USAGI: added sysctl for icmp rate limit.
15 * Randy Dunlap and
16 * YOSHIFUJI Hideaki @USAGI: Per-interface statistics support
17 * Kazunori MIYAZAWA @USAGI: change output process to use ip6_append_data
18 *
19 * Internet Control Message Protocol (NewIP ICMP)
20 * Linux NewIP INET implementation
21 */
22 #define pr_fmt(fmt) KBUILD_MODNAME ": [%s:%d] " fmt, __func__, __LINE__
23
24 #include <net/sock.h>
25 #include <net/nip.h>
26 #include <net/protocol.h>
27 #include <net/nip_route.h>
28 #include <net/nip_addrconf.h>
29 #include <net/nndisc.h>
30 #include <linux/module.h>
31 #include <linux/errno.h>
32 #include <linux/types.h>
33 #include <linux/socket.h>
34 #include <linux/kernel.h>
35 #include <linux/net.h>
36 #include <linux/skbuff.h>
37 #include <linux/init.h>
38 #include <linux/inet.h>
39 #include <linux/netdevice.h>
40 #include <linux/nip_icmp.h>
41
42 #include "nip_hdr.h"
43 #include "tcp_nip_parameter.h"
44
nip_icmp_rcv(struct sk_buff * skb)45 int nip_icmp_rcv(struct sk_buff *skb)
46 {
47 int ret = 0;
48 struct nip_icmp_hdr *hdr;
49 u8 type;
50
51 if (!pskb_may_pull(skb, sizeof(struct nip_icmp_hdr))) {
52 nip_dbg("invalid ICMP packet");
53 return -EINVAL;
54 }
55
56 hdr = nip_icmp_header(skb);
57 type = hdr->nip_icmp_type;
58 nip_dbg("rcv newip icmp packet. type=%u", type);
59 switch (type) {
60 case NIP_ARP_NS:
61 case NIP_ARP_NA:
62 ret = nndisc_rcv(skb);
63 break;
64 default:
65 nip_dbg("nip icmp packet type error");
66 }
67 return ret;
68 }
69
nip_icmp_early_demux(struct sk_buff * skb)70 static void nip_icmp_early_demux(struct sk_buff *skb)
71 {
72 }
73
nip_icmp_err_handler(struct sk_buff * skb,struct ninet_skb_parm * opt,u8 type,u8 code,int offset,__be32 info)74 static void nip_icmp_err_handler(struct sk_buff *skb,
75 struct ninet_skb_parm *opt,
76 u8 type, u8 code,
77 int offset, __be32 info)
78 {
79 }
80
81 static const struct ninet_protocol nip_icmp_protocol = {
82 .early_demux = nip_icmp_early_demux,
83 .err_handler = nip_icmp_err_handler,
84 .handler = nip_icmp_rcv,
85 .flags = 0,
86 };
87
nip_icmp_init(void)88 int __init nip_icmp_init(void)
89 {
90 int ret;
91
92 ret = ninet_add_protocol(&nip_icmp_protocol, IPPROTO_NIP_ICMP);
93 return ret;
94 }
95