1 /*
2 * Linux NET3: IP/IP protocol decoder.
3 *
4 * Authors:
5 * Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
6 *
7 * Fixes:
8 * Alan Cox : Merged and made usable non modular (its so tiny its silly as
9 * a module taking up 2 pages).
10 * Alan Cox : Fixed bug with 1.3.18 and IPIP not working (now needs to set skb->h.iph)
11 * to keep ip_forward happy.
12 * Alan Cox : More fixes for 1.3.21, and firewall fix. Maybe this will work soon 8).
13 * Kai Schulte : Fixed #defines for IP_FIREWALL->FIREWALL
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 *
20 */
21
22 #include <linux/module.h>
23
24 #include <linux/config.h>
25 #include <linux/types.h>
26 #include <linux/sched.h>
27 #include <linux/kernel.h>
28 #include <linux/skbuff.h>
29 #include <linux/netdevice.h>
30 #include <linux/in.h>
31 #include <linux/tcp.h>
32 #include <linux/udp.h>
33 #include <linux/firewall.h>
34 #include <linux/config.h> /* For CONFIG_FIREWALL */
35
36 #include <net/datalink.h>
37 #include <net/sock.h>
38 #include <net/ip.h>
39 #include <net/icmp.h>
40 #include <net/protocol.h>
41 #include <net/ipip.h>
42
43 /*
44 * The IPIP protocol driver.
45 *
46 * On entry here
47 * skb->data is the original IP header
48 * skb->ip_hdr points to the initial IP header.
49 * skb->h.raw points at the new header.
50 */
51
52 int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
53 __u32 daddr, unsigned short len, __u32 saddr,
54 int redo, struct inet_protocol *protocol)
55 {
56 #ifdef CONFIG_FIREWALL
57 int err;
58 #endif
59 /* Don't unlink in the middle of a turnaround */
60 MOD_INC_USE_COUNT;
61 #ifdef TUNNEL_DEBUG
62 printk("ipip_rcv: got a packet!\n");
63 #endif
64 /*
65 * Discard the original IP header
66 */
67
68 skb_pull(skb, ((struct iphdr *)skb->data)->ihl<<2);
69
70 /*
71 * Adjust pointers
72 */
73
74 skb->h.iph=(struct iphdr *)skb->data;
75 skb->ip_hdr=(struct iphdr *)skb->data;
76 memset(skb->proto_priv, 0, sizeof(struct options));
77 if (skb->ip_hdr->ihl > 5)
78 {
79 if (ip_options_compile(NULL, skb))
80 return 0;
81 }
82
83 #ifdef CONFIG_FIREWALL
84 /*
85 * Check the firewall [well spotted Olaf]
86 */
87
88 if((err=call_in_firewall(PF_INET, skb, skb->ip_hdr))<FW_ACCEPT)
89 {
90 if(err==FW_REJECT)
91 icmp_send(skb,ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0 , dev);
92 kfree_skb(skb, FREE_READ);
93 return 0;
94 }
95 #endif
96
97 /*
98 * If you want to add LZ compressed IP or things like that here,
99 * and in drivers/net/tunnel.c are the places to add.
100 */
101
102 /* skb=lzw_uncompress(skb); */
103
104 /*
105 * Feed to IP forward.
106 */
107
108 if(ip_forward(skb, dev, 0, daddr))
109 kfree_skb(skb, FREE_READ);
110 MOD_DEC_USE_COUNT;
111 return(0);
112 }
113
114 #ifdef MODULE
115
116 static struct inet_protocol ipip_protocol = {
117 ipip_rcv, /* IPIP handler */
118 NULL, /* Will be UDP fraglist handler */
119 NULL, /* TUNNEL error control */
120 0, /* next */
121 IPPROTO_IPIP, /* protocol ID */
122 0, /* copy */
123 NULL, /* data */
124 "IPIP" /* name */
125 };
126
127
128 /*
129 * And now the modules code and kernel interface.
130 */
131
132 int init_module( void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
133 {
134 inet_add_protocol(&ipip_protocol);
135 return 0;
136 }
137
138 void cleanup_module( void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
139 {
140 if ( inet_del_protocol(&ipip_protocol) < 0 )
141 printk("ipip close: can't remove protocol\n");
142 }
143
144 #endif