summaryrefslogtreecommitdiffstats
path: root/include/net/sock.h
blob: be7c845918ce2bd03c1f19a9c0fd69c37277d4e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
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
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
 * 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 AF_INET socket handler.
 *
 * Version:	@(#)sock.h	1.0.4	05/13/93
 *
 * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Corey Minyard <wf-rch!minyard@relay.EU.net>
 *		Florian La Roche <flla@stud.uni-sb.de>
 *
 * Fixes:
 *		Alan Cox	:	Volatiles in skbuff pointers. See
 *					skbuff comments. May be overdone,
 *					better to prove they can be removed
 *					than the reverse.
 *		Alan Cox	:	Added a zapped field for tcp to note
 *					a socket is reset and must stay shut up
 *		Alan Cox	:	New fields for options
 *	Pauline Middelink	:	identd support
 *
 *		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 _SOCK_H
#define _SOCK_H

#include <linux/timer.h>
#include <linux/ip.h>		/* struct options */
#include <linux/in.h>		/* struct sockaddr_in */
#include <linux/tcp.h>		/* struct tcphdr */
#include <linux/config.h>

#include <linux/skbuff.h>	/* struct sk_buff */
#include "protocol.h"		/* struct inet_protocol */
#ifdef CONFIG_AX25
#include "ax25.h"
#ifdef CONFIG_NETROM
#include "netrom.h"
#endif
#endif
#ifdef CONFIG_IPX
#include "ipx.h"
#endif
#ifdef CONFIG_ATALK
#include "atalk.h"
#endif

#include <linux/igmp.h>

#define SOCK_ARRAY_SIZE	256		/* Think big (also on some systems a byte is faster */


/*
 * This structure really needs to be cleaned up.
 * Most of it is for TCP, and not used by any of
 * the other protocols.
 */
struct sock {
  struct options		*opt;
  volatile unsigned long	wmem_alloc;
  volatile unsigned long	rmem_alloc;
  unsigned long			write_seq;
  unsigned long			sent_seq;
  unsigned long			acked_seq;
  unsigned long			copied_seq;
  unsigned long			rcv_ack_seq;
  unsigned long			window_seq;
  unsigned long			fin_seq;
  unsigned long			urg_seq;
  unsigned long			urg_data;

  /*
   * Not all are volatile, but some are, so we
   * might as well say they all are.
   */
  volatile char                 inuse,
				dead,
				urginline,
				intr,
				blog,
				done,
				reuse,
				keepopen,
				linger,
				delay_acks,
				destroy,
				ack_timed,
				no_check,
				zapped,	/* In ax25 & ipx means not linked */
				broadcast,
				nonagle;
  unsigned long		        lingertime;
  int				proc;
  struct sock			*next;
  struct sock			*prev; /* Doubly linked chain.. */
  struct sock			*pair;
  struct sk_buff		* volatile send_head;
  struct sk_buff		* volatile send_tail;
  struct sk_buff_head		back_log;
  struct sk_buff		*partial;
  struct timer_list		partial_timer;
  long				retransmits;
  struct sk_buff_head		write_queue,
				receive_queue;
  struct proto			*prot;
  struct wait_queue		**sleep;
  unsigned long			daddr;
  unsigned long			saddr;
  unsigned short		max_unacked;
  unsigned short		window;
  unsigned short		bytes_rcv;
/* mss is min(mtu, max_window) */
  unsigned short		mtu;       /* mss negotiated in the syn's */
  volatile unsigned short	mss;       /* current eff. mss - can change */
  volatile unsigned short	user_mss;  /* mss requested by user in ioctl */
  volatile unsigned short	max_window;
  unsigned long 		window_clamp;
  unsigned short		num;
  volatile unsigned short	cong_window;
  volatile unsigned short	cong_count;
  volatile unsigned short	ssthresh;
  volatile unsigned short	packets_out;
  volatile unsigned short	shutdown;
  volatile unsigned long	rtt;
  volatile unsigned long	mdev;
  volatile unsigned long	rto;
/* currently backoff isn't used, but I'm maintaining it in case
 * we want to go back to a backoff formula that needs it
 */
  volatile unsigned short	backoff;
  volatile short		err;
  unsigned char			protocol;
  volatile unsigned char	state;
  volatile unsigned char	ack_backlog;
  unsigned char			max_ack_backlog;
  unsigned char			priority;
  unsigned char			debug;
  unsigned short		rcvbuf;
  unsigned short		sndbuf;
  unsigned short		type;
  unsigned char			localroute;	/* Route locally only */
#ifdef CONFIG_IPX
  ipx_address			ipx_dest_addr;
  ipx_interface			*ipx_intrfc;
  unsigned short		ipx_port;
  unsigned short		ipx_type;
#endif
#ifdef CONFIG_AX25
  ax25_cb			*ax25;
#ifdef CONFIG_NETROM
  nr_cb				*nr;
#endif
#endif
#ifdef CONFIG_ATALK
  struct atalk_sock		at;
#endif

/* IP 'private area' or will be eventually */
  int				ip_ttl;			/* TTL setting 				*/
  int				ip_tos;			/* TOS 					*/
  struct tcphdr			dummy_th;
  struct timer_list		keepalive_timer;	/* TCP keepalive hack 			*/
  struct timer_list		retransmit_timer;	/* TCP retransmit timer 		*/
  struct timer_list		ack_timer;		/* TCP delayed ack timer		*/
  int				ip_xmit_timeout;	/* Why the timeout is running 		*/
  struct rtable			*ip_route_cache;	/* Cached output route 			*/
  unsigned long			ip_route_stamp;		/* Route cache stamp 			*/
  unsigned long			ip_route_daddr;		/* Target address 			*/
  unsigned long			ip_route_saddr;		/* Source address			*/
  int				ip_route_local;		/* State of locality flag		*/
  unsigned long			ip_hcache_stamp;	/* Header cache stamp			*/
  unsigned long 		*ip_hcache_ver;		/* Pointer to version of cache		*/
  char				ip_hcache_data[16];	/* Cached header			*/
  int				ip_hcache_state;	/* Have we a cached header		*/
  unsigned char			ip_option_len;		/* Length of IP options			*/
  unsigned char			ip_option_flen;		/* Second fragment option length	*/
  unsigned char			ip_opt_next_strict;	/* Next hop is strict route		*/
  unsigned long			ip_opt_next_hop;	/* Next hop if forced			*/
  unsigned char 		*ip_opt_ptr[2];		/* IP option pointers			*/
#ifdef CONFIG_IP_MULTICAST  
  int				ip_mc_ttl;			/* Multicasting TTL 		*/
  int				ip_mc_loop;			/* Loopback 			*/
  char				ip_mc_name[MAX_ADDR_LEN];	/* Multicast device name 	*/
  struct ip_mc_socklist		*ip_mc_list;			/* Group array 			*/
#endif  

  /* This part is used for the timeout functions (timer.c). */
  int				timeout;	/* What are we waiting for? */
  struct timer_list		timer;		/* This is the TIME_WAIT/receive timer when we are doing IP */
  struct timeval		stamp;

  /* identd */
  struct socket			*socket;
  
  /* Callbacks */
  void				(*state_change)(struct sock *sk);
  void				(*data_ready)(struct sock *sk,int bytes);
  void				(*write_space)(struct sock *sk);
  void				(*error_report)(struct sock *sk);
  
};

struct proto {
  struct sk_buff *	(*wmalloc)(struct sock *sk,
				    unsigned long size, int force,
				    int priority);
  struct sk_buff *	(*rmalloc)(struct sock *sk,
				    unsigned long size, int force,
				    int priority);
  void			(*wfree)(struct sock *sk, struct sk_buff *skb,
				 unsigned long size);
  void			(*rfree)(struct sock *sk, struct sk_buff *skb,
				 unsigned long size);
  unsigned long		(*rspace)(struct sock *sk);
  unsigned long		(*wspace)(struct sock *sk);
  void			(*close)(struct sock *sk, int timeout);
  int			(*read)(struct sock *sk, unsigned char *to,
				int len, int nonblock, unsigned flags);
  int			(*write)(struct sock *sk, unsigned char *to,
				 int len, int nonblock, unsigned flags);
  int			(*sendto)(struct sock *sk,
				  unsigned char *from, int len, int noblock,
				  unsigned flags, struct sockaddr_in *usin,
				  int addr_len);
  int			(*recvfrom)(struct sock *sk,
				    unsigned char *from, int len, int noblock,
				    unsigned flags, struct sockaddr_in *usin,
				    int *addr_len);
  int			(*build_header)(struct sk_buff *skb,
					unsigned long saddr,
					unsigned long daddr,
					struct device **dev, int type,
					struct options *opt, int len, int tos, int ttl);
  int			(*connect)(struct sock *sk,
				  struct sockaddr_in *usin, int addr_len);
  struct sock *		(*accept) (struct sock *sk, int flags);
  void			(*queue_xmit)(struct sock *sk,
				      struct device *dev, struct sk_buff *skb,
				      int free);
  void			(*retransmit)(struct sock *sk, int all);
  void			(*write_wakeup)(struct sock *sk);
  void			(*read_wakeup)(struct sock *sk);
  int			(*rcv)(struct sk_buff *buff, struct device *dev,
			       struct options *opt, unsigned long daddr,
			       unsigned short len, unsigned long saddr,
			       int redo, struct inet_protocol *protocol);
  int			(*select)(struct sock *sk, int which,
				  select_table *wait);
  int			(*ioctl)(struct sock *sk, int cmd,
				 unsigned long arg);
  int			(*init)(struct sock *sk);
  void			(*shutdown)(struct sock *sk, int how);
  int			(*setsockopt)(struct sock *sk, int level, int optname,
  				 char *optval, int optlen);
  int			(*getsockopt)(struct sock *sk, int level, int optname,
  				char *optval, int *option);  	 
  unsigned short	max_header;
  unsigned long		retransmits;
  char			name[32];
  int			inuse, highestinuse;
#ifndef PACKET_C		/* Hack to save 1K for packet sockets */ 
  struct sock *		sock_array[SOCK_ARRAY_SIZE];
#endif PACKET_C  
};

#define TIME_WRITE	1
#define TIME_CLOSE	2
#define TIME_KEEPOPEN	3
#define TIME_DESTROY	4
#define TIME_DONE	5	/* used to absorb those last few packets */
#define TIME_PROBE0	6
#define SOCK_DESTROY_TIME 1000	/* about 10 seconds			*/

#define PROT_SOCK	1024	/* Sockets 0-1023 can't be bound too unless you are superuser */

#define SHUTDOWN_MASK	3
#define RCV_SHUTDOWN	1
#define SEND_SHUTDOWN	2


extern void			destroy_sock(struct sock *sk);
extern unsigned short		get_new_socknum(struct proto *, unsigned short);
extern void			put_sock(unsigned short, struct sock *); 
extern void			release_sock(struct sock *sk);
extern struct sock		*get_sock(struct proto *, unsigned short,
					  unsigned long, unsigned short,
					  unsigned long);
extern struct sock		*get_sock_mcast(struct sock *, unsigned short,
					  unsigned long, unsigned short,
					  unsigned long);
extern struct sock		*get_sock_raw(struct sock *, unsigned short,
					  unsigned long, unsigned long);

extern struct sk_buff		*sock_wmalloc(struct sock *sk,
					      unsigned long size, int force,
					      int priority);
extern struct sk_buff		*sock_rmalloc(struct sock *sk,
					      unsigned long size, int force,
					      int priority);
extern void			sock_wfree(struct sock *sk, struct sk_buff *skb,
					   unsigned long size);
extern void			sock_rfree(struct sock *sk, struct sk_buff *skb,
					   unsigned long size);
extern unsigned long		sock_rspace(struct sock *sk);
extern unsigned long		sock_wspace(struct sock *sk);

extern int			sock_setsockopt(struct sock *sk,int level,int op,char *optval,int optlen);

extern int			sock_getsockopt(struct sock *sk,int level,int op,char *optval,int *optlen);
extern struct sk_buff 		*sock_alloc_send_skb(struct sock *skb, unsigned long size, int noblock, int *errcode);

/*
 *	Queue a received datagram if it will fit. Stream and sequenced protocols
 *	can't normally use this as they need to fit buffers in and play with them.
 *
 *	Inlined as its very short and called for pretty much every packet ever
 *	received.
 */

extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
	unsigned long flags;
	if(sk->rmem_alloc + skb->mem_len >= sk->rcvbuf)
		return -ENOMEM;
	save_flags(flags);
	cli();
	sk->rmem_alloc+=skb->mem_len;
	skb->sk=sk;
	restore_flags(flags);
	skb_queue_tail(&sk->receive_queue,skb);
	if(!sk->dead)
		sk->data_ready(sk,skb->len);
	return 0;
}

/* declarations from timer.c */
extern struct sock *timer_base;

void delete_timer (struct sock *);
void reset_timer (struct sock *, int, unsigned long);
void net_timer (unsigned long);


/* Enable debug/info messages */

#define NETDEBUG(x)		x

#endif	/* _SOCK_H */