udp.h 4.7 KB
Newer Older
L
Linus Torvalds 已提交
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 UDP module.
 *
 * Version:	@(#)udp.h	1.0.2	05/07/93
 *
10
 * Authors:	Ross Biro
L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *
 * Fixes:
 *		Alan Cox	: Turned on udp checksums. I don't want to
 *				  chase 'memory corruption' bugs that aren't!
 *
 *		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 _UDP_H
#define _UDP_H

#include <linux/list.h>
26
#include <net/inet_sock.h>
L
Linus Torvalds 已提交
27 28
#include <net/sock.h>
#include <net/snmp.h>
29 30
#include <net/ip.h>
#include <linux/ipv6.h>
L
Linus Torvalds 已提交
31 32
#include <linux/seq_file.h>

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
/**
 *	struct udp_skb_cb  -  UDP(-Lite) private variables
 *
 *	@header:      private variables used by IPv4/IPv6
 *	@cscov:       checksum coverage length (UDP-Lite only)
 *	@partial_cov: if set indicates partial csum coverage
 */
struct udp_skb_cb {
	union {
		struct inet_skb_parm	h4;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
		struct inet6_skb_parm	h6;
#endif
	} header;
	__u16		cscov;
	__u8		partial_cov;
};
#define UDP_SKB_CB(__skb)	((struct udp_skb_cb *)((__skb)->cb))
L
Linus Torvalds 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

extern struct hlist_head udp_hash[UDP_HTABLE_SIZE];
extern rwlock_t udp_hash_lock;


/* Note: this must match 'valbool' in sock_setsockopt */
#define UDP_CSUM_NOXMIT		1

/* Used by SunRPC/xprt layer. */
#define UDP_CSUM_NORCV		2

/* Default, as per the RFC, is to always do csums. */
#define UDP_CSUM_DEFAULT	0

extern struct proto udp_prot;

67
struct sk_buff;
L
Linus Torvalds 已提交
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
/*
 *	Generic checksumming routines for UDP(-Lite) v4 and v6
 */
static inline u16  __udp_lib_checksum_complete(struct sk_buff *skb)
{
	if (! UDP_SKB_CB(skb)->partial_cov)
		return __skb_checksum_complete(skb);
	return  csum_fold(skb_checksum(skb, 0, UDP_SKB_CB(skb)->cscov,
			  skb->csum));
}

static __inline__ int udp_lib_checksum_complete(struct sk_buff *skb)
{
	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
		__udp_lib_checksum_complete(skb);
}

/**
 * 	udp_csum_outgoing  -  compute UDPv4/v6 checksum over fragments
 * 	@sk: 	socket we are writing to
 * 	@skb: 	sk_buff containing the filled-in UDP header
 * 	        (checksum field must be zeroed out)
 */
static inline u32 udp_csum_outgoing(struct sock *sk, struct sk_buff *skb)
{
	u32 csum = csum_partial(skb->h.raw, sizeof(struct udphdr), 0);

	skb_queue_walk(&sk->sk_write_queue, skb) {
		csum = csum_add(csum, skb->csum);
	}
	return csum;
}

/* hash routines shared between UDPv4/6 and UDP-Litev4/6 */
static inline void udp_lib_hash(struct sock *sk)
{
	BUG();
}

static inline void udp_lib_unhash(struct sock *sk)
{
	write_lock_bh(&udp_hash_lock);
	if (sk_del_node_init(sk)) {
		inet_sk(sk)->num = 0;
		sock_prot_dec_use(sk->sk_prot);
	}
	write_unlock_bh(&udp_hash_lock);
}

static inline void udp_lib_close(struct sock *sk, long timeout)
{
	sk_common_release(sk);
}


/* net/ipv4/udp.c */
125
extern int	udp_get_port(struct sock *sk, unsigned short snum,
126
			     int (*saddr_cmp)(const struct sock *, const struct sock *));
L
Linus Torvalds 已提交
127 128 129 130 131 132 133 134 135 136 137 138
extern void	udp_err(struct sk_buff *, u32);

extern int	udp_sendmsg(struct kiocb *iocb, struct sock *sk,
			    struct msghdr *msg, size_t len);

extern int	udp_rcv(struct sk_buff *skb);
extern int	udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern int	udp_disconnect(struct sock *sk, int flags);
extern unsigned int udp_poll(struct file *file, struct socket *sock,
			     poll_table *wait);

DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
139 140 141 142 143 144 145 146 147
/*
 * 	SNMP statistics for UDP and UDP-Lite
 */
#define UDP_INC_STATS_USER(field, is_udplite)			       do {   \
	if (is_udplite) SNMP_INC_STATS_USER(udplite_statistics, field);       \
	else		SNMP_INC_STATS_USER(udp_statistics, field);  }  while(0)
#define UDP_INC_STATS_BH(field, is_udplite) 			       do  {  \
	if (is_udplite) SNMP_INC_STATS_BH(udplite_statistics, field);         \
	else		SNMP_INC_STATS_BH(udp_statistics, field);    }  while(0)
L
Linus Torvalds 已提交
148 149 150 151 152 153

/* /proc */
struct udp_seq_afinfo {
	struct module		*owner;
	char			*name;
	sa_family_t		family;
154
	struct hlist_head	*hashtable;
L
Linus Torvalds 已提交
155 156 157 158 159 160
	int 			(*seq_show) (struct seq_file *m, void *v);
	struct file_operations	*seq_fops;
};

struct udp_iter_state {
	sa_family_t		family;
161
	struct hlist_head	*hashtable;
L
Linus Torvalds 已提交
162 163 164 165
	int			bucket;
	struct seq_operations	seq_ops;
};

166
#ifdef CONFIG_PROC_FS
L
Linus Torvalds 已提交
167 168
extern int udp_proc_register(struct udp_seq_afinfo *afinfo);
extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo);
169 170 171 172

extern int  udp4_proc_init(void);
extern void udp4_proc_exit(void);
#endif
L
Linus Torvalds 已提交
173
#endif	/* _UDP_H */