ip.h 11.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the  BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		Definitions for the IP module.
 *
 * Version:	@(#)ip.h	1.0.2	05/07/93
 *
10
 * Authors:	Ross Biro
Linus Torvalds's avatar
Linus Torvalds committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Alan Cox, <gw4pts@gw4pts.ampr.org>
 *
 * Changes:
 *		Mike McLagan    :       Routing by source
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 */
#ifndef _IP_H
#define _IP_H

#include <linux/types.h>
#include <linux/ip.h>
#include <linux/in.h>
28
#include <linux/skbuff.h>
29
30

#include <net/inet_sock.h>
Linus Torvalds's avatar
Linus Torvalds committed
31
32
33
34
35
36
37
38
39
#include <net/snmp.h>

struct sock;

struct inet_skb_parm
{
	struct ip_options	opt;		/* Compiled IP options		*/
	unsigned char		flags;

40
41
#define IPSKB_FORWARDED		1
#define IPSKB_XFRM_TUNNEL_SIZE	2
42
43
#define IPSKB_XFRM_TRANSFORMED	4
#define IPSKB_FRAG_COMPLETE	8
44
#define IPSKB_REROUTED		16
Linus Torvalds's avatar
Linus Torvalds committed
45
46
};

47
48
static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
{
49
	return ip_hdr(skb)->ihl * 4;
50
51
}

Linus Torvalds's avatar
Linus Torvalds committed
52
53
struct ipcm_cookie
{
54
	__be32			addr;
Linus Torvalds's avatar
Linus Torvalds committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
	int			oif;
	struct ip_options	*opt;
};

#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))

struct ip_ra_chain
{
	struct ip_ra_chain	*next;
	struct sock		*sk;
	void			(*destructor)(struct sock *);
};

extern struct ip_ra_chain *ip_ra_chain;
extern rwlock_t ip_ra_lock;

/* IP flags. */
#define IP_CE		0x8000		/* Flag: "Congestion"		*/
#define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
#define IP_MF		0x2000		/* Flag: "More Fragments"	*/
#define IP_OFFSET	0x1FFF		/* "Fragment Offset" part	*/

#define IP_FRAG_TIME	(30 * HZ)		/* fragment lifetime	*/

79
80
81
82
83
84
struct msghdr;
struct net_device;
struct packet_type;
struct rtable;
struct sockaddr;

Linus Torvalds's avatar
Linus Torvalds committed
85
86
87
88
89
90
91
extern int		igmp_mc_proc_init(void);

/*
 *	Functions provided by ip.c
 */

extern int		ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
92
					      __be32 saddr, __be32 daddr,
Linus Torvalds's avatar
Linus Torvalds committed
93
94
					      struct ip_options *opt);
extern int		ip_rcv(struct sk_buff *skb, struct net_device *dev,
David S. Miller's avatar
David S. Miller committed
95
			       struct packet_type *pt, struct net_device *orig_dev);
Linus Torvalds's avatar
Linus Torvalds committed
96
97
98
99
extern int		ip_local_deliver(struct sk_buff *skb);
extern int		ip_mr_input(struct sk_buff *skb);
extern int		ip_output(struct sk_buff *skb);
extern int		ip_mc_output(struct sk_buff *skb);
100
extern int		ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
Linus Torvalds's avatar
Linus Torvalds committed
101
102
extern int		ip_do_nat(struct sk_buff *skb);
extern void		ip_send_check(struct iphdr *ip);
Herbert Xu's avatar
Herbert Xu committed
103
104
extern int		__ip_local_out(struct sk_buff *skb);
extern int		ip_local_out(struct sk_buff *skb);
105
extern int		ip_queue_xmit(struct sk_buff *skb, int ipfragok);
Linus Torvalds's avatar
Linus Torvalds committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
extern void		ip_init(void);
extern int		ip_append_data(struct sock *sk,
				       int getfrag(void *from, char *to, int offset, int len,
						   int odd, struct sk_buff *skb),
				void *from, int len, int protolen,
				struct ipcm_cookie *ipc,
				struct rtable *rt,
				unsigned int flags);
extern int		ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb);
extern ssize_t		ip_append_page(struct sock *sk, struct page *page,
				int offset, size_t size, int flags);
extern int		ip_push_pending_frames(struct sock *sk);
extern void		ip_flush_pending_frames(struct sock *sk);

/* datagram.c */
extern int		ip4_datagram_connect(struct sock *sk, 
					     struct sockaddr *uaddr, int addr_len);

/*
 *	Map a multicast IP onto multicast MAC for type Token Ring.
 *      This conforms to RFC1469 Option 2 Multicasting i.e.
 *      using a functional address to transmit / receive 
 *      multicast packets.
 */

131
static inline void ip_tr_mc_map(__be32 addr, char *buf)
Linus Torvalds's avatar
Linus Torvalds committed
132
133
134
135
136
137
138
139
140
141
142
{
	buf[0]=0xC0;
	buf[1]=0x00;
	buf[2]=0x00;
	buf[3]=0x04;
	buf[4]=0x00;
	buf[5]=0x00;
}

struct ip_reply_arg {
	struct kvec iov[1];   
143
	__wsum 	    csum;
Linus Torvalds's avatar
Linus Torvalds committed
144
145
	int	    csumoffset; /* u16 offset of csum in iov[0].iov_base */
				/* -1 if not needed */ 
146
	int	    bound_dev_if;
Linus Torvalds's avatar
Linus Torvalds committed
147
148
149
150
151
152
153
154
155
156
157
158
159
}; 

void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
		   unsigned int len); 

struct ipv4_config
{
	int	log_martians;
	int	no_pmtu_disc;
};

extern struct ipv4_config ipv4_config;
DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics);
Pavel Emelyanov's avatar
Pavel Emelyanov committed
160
#define IP_INC_STATS(net, field)	do { (void)net; SNMP_INC_STATS(ip_statistics, field); } while (0)
161
#define IP_INC_STATS_BH(net, field)	do { (void)net; SNMP_INC_STATS_BH(ip_statistics, field); } while (0)
162
#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH(ip_statistics, field, val)
Linus Torvalds's avatar
Linus Torvalds committed
163
DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
164
#define NET_INC_STATS(net, field)	do { (void)net; SNMP_INC_STATS(net_statistics, field); } while (0)
165
#define NET_INC_STATS_BH(net, field)	do { (void)net; SNMP_INC_STATS_BH(net_statistics, field); } while (0)
166
#define NET_INC_STATS_USER(net, field) 	do { (void)net; SNMP_INC_STATS_USER(net_statistics, field); } while (0)
Linus Torvalds's avatar
Linus Torvalds committed
167
168
169
#define NET_ADD_STATS_BH(field, adnd)	SNMP_ADD_STATS_BH(net_statistics, field, adnd)
#define NET_ADD_STATS_USER(field, adnd)	SNMP_ADD_STATS_USER(net_statistics, field, adnd)

170
extern unsigned long snmp_fold_field(void *mib[], int offt);
171
extern int snmp_mib_init(void *ptr[2], size_t mibsize);
172
173
extern void snmp_mib_free(void *ptr[2]);

174
175
extern void inet_get_local_port_range(int *low, int *high);

Linus Torvalds's avatar
Linus Torvalds committed
176
extern int sysctl_ip_default_ttl;
177
extern int sysctl_ip_nonlocal_bind;
Linus Torvalds's avatar
Linus Torvalds committed
178

179
180
extern struct ctl_path net_ipv4_ctl_path[];

181
182
183
184
185
186
187
188
189
190
191
192
/* From inetpeer.c */
extern int inet_peer_threshold;
extern int inet_peer_minttl;
extern int inet_peer_maxttl;
extern int inet_peer_gc_mintime;
extern int inet_peer_gc_maxtime;

/* From ip_output.c */
extern int sysctl_ip_dynaddr;

extern void ipfrag_init(void);

Linus Torvalds's avatar
Linus Torvalds committed
193
#ifdef CONFIG_INET
194
195
#include <net/dst.h>

Linus Torvalds's avatar
Linus Torvalds committed
196
197
198
199
200
/* The function in 2.2 was invalid, producing wrong result for
 * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
static inline
int ip_decrease_ttl(struct iphdr *iph)
{
201
202
203
	u32 check = (__force u32)iph->check;
	check += (__force u32)htons(0x0100);
	iph->check = (__force __sum16)(check + (check>=0xFFFF));
Linus Torvalds's avatar
Linus Torvalds committed
204
205
206
207
208
209
210
211
	return --iph->ttl;
}

static inline
int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
{
	return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
		(inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT &&
212
		 !(dst_metric_locked(dst, RTAX_MTU))));
Linus Torvalds's avatar
Linus Torvalds committed
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
}

extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);

static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
{
	if (iph->frag_off & htons(IP_DF)) {
		/* This is only to work around buggy Windows95/2000
		 * VJ compression implementations.  If the ID field
		 * does not change, they drop every other packet in
		 * a TCP stream using header compression.
		 */
		iph->id = (sk && inet_sk(sk)->daddr) ?
					htons(inet_sk(sk)->id++) : 0;
	} else
		__ip_select_ident(iph, dst, 0);
}

static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more)
{
	if (iph->frag_off & htons(IP_DF)) {
		if (sk && inet_sk(sk)->daddr) {
			iph->id = htons(inet_sk(sk)->id);
			inet_sk(sk)->id += 1 + more;
		} else
			iph->id = 0;
	} else
		__ip_select_ident(iph, dst, more);
}

/*
 *	Map a multicast IP onto multicast MAC for type ethernet.
 */

247
static inline void ip_eth_mc_map(__be32 naddr, char *buf)
Linus Torvalds's avatar
Linus Torvalds committed
248
{
249
	__u32 addr=ntohl(naddr);
Linus Torvalds's avatar
Linus Torvalds committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
	buf[0]=0x01;
	buf[1]=0x00;
	buf[2]=0x5e;
	buf[5]=addr&0xFF;
	addr>>=8;
	buf[4]=addr&0xFF;
	addr>>=8;
	buf[3]=addr&0x7F;
}

/*
 *	Map a multicast IP onto multicast MAC for type IP-over-InfiniBand.
 *	Leave P_Key as 0 to be filled in by driver.
 */

265
static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
Linus Torvalds's avatar
Linus Torvalds committed
266
{
267
	__u32 addr;
268
269
	unsigned char scope = broadcast[5] & 0xF;

Linus Torvalds's avatar
Linus Torvalds committed
270
271
272
273
	buf[0]  = 0;		/* Reserved */
	buf[1]  = 0xff;		/* Multicast QPN */
	buf[2]  = 0xff;
	buf[3]  = 0xff;
274
	addr    = ntohl(naddr);
Linus Torvalds's avatar
Linus Torvalds committed
275
	buf[4]  = 0xff;
276
	buf[5]  = 0x10 | scope;	/* scope from broadcast address */
Linus Torvalds's avatar
Linus Torvalds committed
277
278
	buf[6]  = 0x40;		/* IPv4 signature */
	buf[7]  = 0x1b;
279
280
	buf[8]  = broadcast[8];		/* P_Key */
	buf[9]  = broadcast[9];
Linus Torvalds's avatar
Linus Torvalds committed
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
	buf[10] = 0;
	buf[11] = 0;
	buf[12] = 0;
	buf[13] = 0;
	buf[14] = 0;
	buf[15] = 0;
	buf[19] = addr & 0xff;
	addr  >>= 8;
	buf[18] = addr & 0xff;
	addr  >>= 8;
	buf[17] = addr & 0xff;
	addr  >>= 8;
	buf[16] = addr & 0x0f;
}

#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <linux/ipv6.h>
#endif

static __inline__ void inet_reset_saddr(struct sock *sk)
{
	inet_sk(sk)->rcv_saddr = inet_sk(sk)->saddr = 0;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
	if (sk->sk_family == PF_INET6) {
		struct ipv6_pinfo *np = inet6_sk(sk);

		memset(&np->saddr, 0, sizeof(np->saddr));
		memset(&np->rcv_saddr, 0, sizeof(np->rcv_saddr));
	}
#endif
}

#endif

extern int	ip_call_ra_chain(struct sk_buff *skb);

/*
318
 *	Functions provided by ip_fragment.c
Linus Torvalds's avatar
Linus Torvalds committed
319
320
321
322
323
324
325
326
327
328
329
330
331
 */

enum ip_defrag_users
{
	IP_DEFRAG_LOCAL_DELIVER,
	IP_DEFRAG_CALL_RA_CHAIN,
	IP_DEFRAG_CONNTRACK_IN,
	IP_DEFRAG_CONNTRACK_OUT,
	IP_DEFRAG_VS_IN,
	IP_DEFRAG_VS_OUT,
	IP_DEFRAG_VS_FWD
};

332
int ip_defrag(struct sk_buff *skb, u32 user);
333
int ip_frag_mem(struct net *net);
334
int ip_frag_nqueues(struct net *net);
Linus Torvalds's avatar
Linus Torvalds committed
335
336
337
338
339
340
341
342
343
344
345

/*
 *	Functions provided by ip_forward.c
 */
 
extern int ip_forward(struct sk_buff *skb);
 
/*
 *	Functions provided by ip_options.c
 */
 
346
extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, __be32 daddr, struct rtable *rt, int is_frag);
Linus Torvalds's avatar
Linus Torvalds committed
347
348
extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb);
extern void ip_options_fragment(struct sk_buff *skb);
349
350
extern int ip_options_compile(struct net *net,
			      struct ip_options *opt, struct sk_buff *skb);
351
extern int ip_options_get(struct net *net, struct ip_options **optp,
352
			  unsigned char *data, int optlen);
353
extern int ip_options_get_from_user(struct net *net, struct ip_options **optp,
354
				    unsigned char __user *data, int optlen);
Linus Torvalds's avatar
Linus Torvalds committed
355
356
357
358
359
360
361
362
363
extern void ip_options_undo(struct ip_options * opt);
extern void ip_forward_options(struct sk_buff *skb);
extern int ip_options_rcv_srr(struct sk_buff *skb);

/*
 *	Functions provided by ip_sockglue.c
 */

extern void	ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
364
365
extern int	ip_cmsg_send(struct net *net,
			     struct msghdr *msg, struct ipcm_cookie *ipc);
Linus Torvalds's avatar
Linus Torvalds committed
366
367
extern int	ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen);
extern int	ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);
368
369
370
371
extern int	compat_ip_setsockopt(struct sock *sk, int level,
			int optname, char __user *optval, int optlen);
extern int	compat_ip_getsockopt(struct sock *sk, int level,
			int optname, char __user *optval, int __user *optlen);
Linus Torvalds's avatar
Linus Torvalds committed
372
373
374
375
extern int	ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));

extern int 	ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
extern void	ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
Al Viro's avatar
Al Viro committed
376
			      __be16 port, u32 info, u8 *payload);
Al Viro's avatar
Al Viro committed
377
extern void	ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
Linus Torvalds's avatar
Linus Torvalds committed
378
379
380
381
382
383
384
385
386
387
			       u32 info);

/* sysctl helpers - any sysctl which holds a value that ends up being
 * fed into the routing cache should use these handlers.
 */
int ipv4_doint_and_flush(ctl_table *ctl, int write,
			 struct file* filp, void __user *buffer,
			 size_t *lenp, loff_t *ppos);
int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
				  void __user *oldval, size_t __user *oldlenp,
388
				  void __user *newval, size_t newlen);
389
390
391
392
#ifdef CONFIG_PROC_FS
extern int ip_misc_proc_init(void);
#endif

Linus Torvalds's avatar
Linus Torvalds committed
393
#endif	/* _IP_H */