Creation of Cybook 2416 (actually Gen4) repository

This commit is contained in:
mlt
2009-12-18 17:10:00 +00:00
committed by godzil
commit 76f20f4d40
13791 changed files with 6812321 additions and 0 deletions

156
include/net/act_api.h Normal file
View File

@@ -0,0 +1,156 @@
#ifndef __NET_ACT_API_H
#define __NET_ACT_API_H
/*
* Public police action API for classifiers/qdiscs
*/
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
struct tcf_common {
struct tcf_common *tcfc_next;
u32 tcfc_index;
int tcfc_refcnt;
int tcfc_bindcnt;
u32 tcfc_capab;
int tcfc_action;
struct tcf_t tcfc_tm;
struct gnet_stats_basic tcfc_bstats;
struct gnet_stats_queue tcfc_qstats;
struct gnet_stats_rate_est tcfc_rate_est;
spinlock_t *tcfc_stats_lock;
spinlock_t tcfc_lock;
};
#define tcf_next common.tcfc_next
#define tcf_index common.tcfc_index
#define tcf_refcnt common.tcfc_refcnt
#define tcf_bindcnt common.tcfc_bindcnt
#define tcf_capab common.tcfc_capab
#define tcf_action common.tcfc_action
#define tcf_tm common.tcfc_tm
#define tcf_bstats common.tcfc_bstats
#define tcf_qstats common.tcfc_qstats
#define tcf_rate_est common.tcfc_rate_est
#define tcf_stats_lock common.tcfc_stats_lock
#define tcf_lock common.tcfc_lock
struct tcf_police {
struct tcf_common common;
int tcfp_result;
u32 tcfp_ewma_rate;
u32 tcfp_burst;
u32 tcfp_mtu;
u32 tcfp_toks;
u32 tcfp_ptoks;
psched_time_t tcfp_t_c;
struct qdisc_rate_table *tcfp_R_tab;
struct qdisc_rate_table *tcfp_P_tab;
};
#define to_police(pc) \
container_of(pc, struct tcf_police, common)
struct tcf_hashinfo {
struct tcf_common **htab;
unsigned int hmask;
rwlock_t *lock;
};
static inline unsigned int tcf_hash(u32 index, unsigned int hmask)
{
return index & hmask;
}
#ifdef CONFIG_NET_CLS_ACT
#define ACT_P_CREATED 1
#define ACT_P_DELETED 1
struct tcf_act_hdr {
struct tcf_common common;
};
struct tc_action {
void *priv;
struct tc_action_ops *ops;
__u32 type; /* for backward compat(TCA_OLD_COMPAT) */
__u32 order;
struct tc_action *next;
};
#define TCA_CAP_NONE 0
struct tc_action_ops {
struct tc_action_ops *next;
struct tcf_hashinfo *hinfo;
char kind[IFNAMSIZ];
__u32 type; /* TBD to match kind */
__u32 capab; /* capabilities includes 4 bit version */
struct module *owner;
int (*act)(struct sk_buff *, struct tc_action *, struct tcf_result *);
int (*get_stats)(struct sk_buff *, struct tc_action *);
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
int (*cleanup)(struct tc_action *, int bind);
int (*lookup)(struct tc_action *, u32);
int (*init)(struct rtattr *, struct rtattr *, struct tc_action *, int , int);
int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);
};
extern struct tcf_common *tcf_hash_lookup(u32 index,
struct tcf_hashinfo *hinfo);
extern void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo);
extern int tcf_hash_release(struct tcf_common *p, int bind,
struct tcf_hashinfo *hinfo);
extern int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
int type, struct tc_action *a);
extern u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo);
extern int tcf_hash_search(struct tc_action *a, u32 index);
extern struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a,
int bind, struct tcf_hashinfo *hinfo);
extern struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est,
struct tc_action *a, int size,
int bind, u32 *idx_gen,
struct tcf_hashinfo *hinfo);
extern void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo);
extern int tcf_register_action(struct tc_action_ops *a);
extern int tcf_unregister_action(struct tc_action_ops *a);
extern void tcf_action_destroy(struct tc_action *a, int bind);
extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
extern struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
extern struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
extern int tcf_action_copy_stats (struct sk_buff *,struct tc_action *, int);
#endif /* CONFIG_NET_CLS_ACT */
extern int tcf_police(struct sk_buff *skb, struct tcf_police *p);
extern void tcf_police_destroy(struct tcf_police *p);
extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est);
extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p);
extern int tcf_police_dump_stats(struct sk_buff *skb, struct tcf_police *p);
static inline int
tcf_police_release(struct tcf_police *p, int bind)
{
int ret = 0;
#ifdef CONFIG_NET_CLS_ACT
if (p) {
if (bind)
p->tcf_bindcnt--;
p->tcf_refcnt--;
if (p->tcf_refcnt <= 0 && !p->tcf_bindcnt) {
tcf_police_destroy(p);
ret = 1;
}
}
#else
if (p && --p->tcf_refcnt == 0)
tcf_police_destroy(p);
#endif /* CONFIG_NET_CLS_ACT */
return ret;
}
#endif

248
include/net/addrconf.h Normal file
View File

@@ -0,0 +1,248 @@
#ifndef _ADDRCONF_H
#define _ADDRCONF_H
#define RETRANS_TIMER HZ
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
#define TEMP_VALID_LIFETIME (7*86400)
#define TEMP_PREFERRED_LIFETIME (86400)
#define REGEN_MAX_RETRY (5)
#define MAX_DESYNC_FACTOR (600)
#define ADDR_CHECK_FREQUENCY (120*HZ)
#define IPV6_MAX_ADDRESSES 16
#include <linux/in6.h>
struct prefix_info {
__u8 type;
__u8 length;
__u8 prefix_len;
#if defined(__BIG_ENDIAN_BITFIELD)
__u8 onlink : 1,
autoconf : 1,
reserved : 6;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
__u8 reserved : 6,
autoconf : 1,
onlink : 1;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__be32 valid;
__be32 prefered;
__be32 reserved2;
struct in6_addr prefix;
};
#ifdef __KERNEL__
#include <linux/netdevice.h>
#include <net/if_inet6.h>
#include <net/ipv6.h>
#define IN6_ADDR_HSIZE 16
extern int addrconf_init(void);
extern void addrconf_cleanup(void);
extern int addrconf_add_ifaddr(void __user *arg);
extern int addrconf_del_ifaddr(void __user *arg);
extern int addrconf_set_dstaddr(void __user *arg);
extern int ipv6_chk_addr(struct in6_addr *addr,
struct net_device *dev,
int strict);
#ifdef CONFIG_IPV6_MIP6
extern int ipv6_chk_home_addr(struct in6_addr *addr);
#endif
extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr,
struct net_device *dev,
int strict);
extern int ipv6_get_saddr(struct dst_entry *dst,
struct in6_addr *daddr,
struct in6_addr *saddr);
extern int ipv6_dev_get_saddr(struct net_device *dev,
struct in6_addr *daddr,
struct in6_addr *saddr);
extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *);
extern int ipv6_rcv_saddr_equal(const struct sock *sk,
const struct sock *sk2);
extern void addrconf_join_solict(struct net_device *dev,
struct in6_addr *addr);
extern void addrconf_leave_solict(struct inet6_dev *idev,
struct in6_addr *addr);
/*
* multicast prototypes (mcast.c)
*/
extern int ipv6_sock_mc_join(struct sock *sk, int ifindex,
struct in6_addr *addr);
extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
struct in6_addr *addr);
extern void ipv6_sock_mc_close(struct sock *sk);
extern int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr,
struct in6_addr *src_addr);
extern int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr);
extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr);
extern int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr);
extern void ipv6_mc_up(struct inet6_dev *idev);
extern void ipv6_mc_down(struct inet6_dev *idev);
extern void ipv6_mc_init_dev(struct inet6_dev *idev);
extern void ipv6_mc_destroy_dev(struct inet6_dev *idev);
extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
struct in6_addr *src_addr);
extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr);
extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len);
extern int ipv6_get_hoplimit(struct net_device *dev);
/*
* anycast prototypes (anycast.c)
*/
extern int ipv6_sock_ac_join(struct sock *sk,int ifindex,struct in6_addr *addr);
extern int ipv6_sock_ac_drop(struct sock *sk,int ifindex,struct in6_addr *addr);
extern void ipv6_sock_ac_close(struct sock *sk);
extern int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex);
extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr);
extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr);
extern int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr);
/* Device notifier */
extern int register_inet6addr_notifier(struct notifier_block *nb);
extern int unregister_inet6addr_notifier(struct notifier_block *nb);
static inline struct inet6_dev *
__in6_dev_get(struct net_device *dev)
{
return rcu_dereference(dev->ip6_ptr);
}
static inline struct inet6_dev *
in6_dev_get(struct net_device *dev)
{
struct inet6_dev *idev = NULL;
rcu_read_lock();
idev = __in6_dev_get(dev);
if (idev)
atomic_inc(&idev->refcnt);
rcu_read_unlock();
return idev;
}
extern void in6_dev_finish_destroy(struct inet6_dev *idev);
static inline void
in6_dev_put(struct inet6_dev *idev)
{
if (atomic_dec_and_test(&idev->refcnt))
in6_dev_finish_destroy(idev);
}
#define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt)
#define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt)
extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
{
if (atomic_dec_and_test(&ifp->refcnt))
inet6_ifa_finish_destroy(ifp);
}
#define __in6_ifa_put(ifp) atomic_dec(&(ifp)->refcnt)
#define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt)
extern void addrconf_forwarding_on(void);
/*
* Hash function taken from net_alias.c
*/
static __inline__ u8 ipv6_addr_hash(const struct in6_addr *addr)
{
__u32 word;
/*
* We perform the hash function over the last 64 bits of the address
* This will include the IEEE address token on links that support it.
*/
word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]);
word ^= (word >> 16);
word ^= (word >> 8);
return ((word ^ (word >> 4)) & 0x0f);
}
/*
* compute link-local solicited-node multicast address
*/
static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
struct in6_addr *solicited)
{
ipv6_addr_set(solicited,
__constant_htonl(0xFF020000), 0,
__constant_htonl(0x1),
__constant_htonl(0xFF000000) | addr->s6_addr32[3]);
}
static inline void ipv6_addr_all_nodes(struct in6_addr *addr)
{
ipv6_addr_set(addr,
__constant_htonl(0xFF020000), 0, 0,
__constant_htonl(0x1));
}
static inline void ipv6_addr_all_routers(struct in6_addr *addr)
{
ipv6_addr_set(addr,
__constant_htonl(0xFF020000), 0, 0,
__constant_htonl(0x2));
}
static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
{
return (addr->s6_addr32[0] & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000);
}
static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
{
return (addr->s6_addr32[0] == htonl(0xff020000) &&
addr->s6_addr32[1] == 0 &&
addr->s6_addr32[2] == 0 &&
addr->s6_addr32[3] == htonl(0x00000001));
}
static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
{
return (addr->s6_addr32[0] == htonl(0xff020000) &&
addr->s6_addr32[1] == 0 &&
addr->s6_addr32[2] == 0 &&
addr->s6_addr32[3] == htonl(0x00000002));
}
#ifdef CONFIG_PROC_FS
extern int if6_proc_init(void);
extern void if6_proc_exit(void);
#endif
#endif
#endif

98
include/net/af_unix.h Normal file
View File

@@ -0,0 +1,98 @@
#ifndef __LINUX_NET_AFUNIX_H
#define __LINUX_NET_AFUNIX_H
#include <linux/socket.h>
#include <linux/un.h>
#include <linux/mutex.h>
#include <net/sock.h>
extern void unix_inflight(struct file *fp);
extern void unix_notinflight(struct file *fp);
extern void unix_gc(void);
#define UNIX_HASH_SIZE 256
extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
extern spinlock_t unix_table_lock;
extern atomic_t unix_tot_inflight;
static inline struct sock *first_unix_socket(int *i)
{
for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
if (!hlist_empty(&unix_socket_table[*i]))
return __sk_head(&unix_socket_table[*i]);
}
return NULL;
}
static inline struct sock *next_unix_socket(int *i, struct sock *s)
{
struct sock *next = sk_next(s);
/* More in this chain? */
if (next)
return next;
/* Look for next non-empty chain. */
for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
if (!hlist_empty(&unix_socket_table[*i]))
return __sk_head(&unix_socket_table[*i]);
}
return NULL;
}
#define forall_unix_sockets(i, s) \
for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s)))
struct unix_address {
atomic_t refcnt;
int len;
unsigned hash;
struct sockaddr_un name[0];
};
struct unix_skb_parms {
struct ucred creds; /* Skb credentials */
struct scm_fp_list *fp; /* Passed files */
#ifdef CONFIG_SECURITY_NETWORK
u32 secid; /* Security ID */
#endif
};
#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb))
#define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
#define UNIXSID(skb) (&UNIXCB((skb)).secid)
#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
#define unix_state_lock_nested(s) \
spin_lock_nested(&unix_sk(s)->lock, \
SINGLE_DEPTH_NESTING)
#ifdef __KERNEL__
/* The AF_UNIX socket */
struct unix_sock {
/* WARNING: sk has to be the first member */
struct sock sk;
struct unix_address *addr;
struct dentry *dentry;
struct vfsmount *mnt;
struct mutex readlock;
struct sock *peer;
struct sock *other;
struct sock *gc_tree;
atomic_t inflight;
spinlock_t lock;
wait_queue_head_t peer_wait;
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
#ifdef CONFIG_SYSCTL
extern int sysctl_unix_max_dgram_qlen;
extern void unix_sysctl_register(void);
extern void unix_sysctl_unregister(void);
#else
static inline void unix_sysctl_register(void) {}
static inline void unix_sysctl_unregister(void) {}
#endif
#endif
#endif

43
include/net/ah.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef _NET_AH_H
#define _NET_AH_H
#include <linux/crypto.h>
#include <net/xfrm.h>
/* This is the maximum truncated ICV length that we know of. */
#define MAX_AH_AUTH_LEN 12
struct ah_data
{
u8 *key;
int key_len;
u8 *work_icv;
int icv_full_len;
int icv_trunc_len;
struct crypto_hash *tfm;
};
static inline int ah_mac_digest(struct ah_data *ahp, struct sk_buff *skb,
u8 *auth_data)
{
struct hash_desc desc;
int err;
desc.tfm = ahp->tfm;
desc.flags = 0;
memset(auth_data, 0, ahp->icv_trunc_len);
err = crypto_hash_init(&desc);
if (unlikely(err))
goto out;
err = skb_icv_walk(skb, &desc, 0, skb->len, crypto_hash_update);
if (unlikely(err))
goto out;
err = crypto_hash_final(&desc, ahp->work_icv);
out:
return err;
}
#endif

30
include/net/arp.h Normal file
View File

@@ -0,0 +1,30 @@
/* linux/net/inet/arp.h */
#ifndef _ARP_H
#define _ARP_H
#include <linux/if_arp.h>
#include <net/neighbour.h>
#define HAVE_ARP_CREATE
extern struct neigh_table arp_tbl;
extern void arp_init(void);
extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
extern int arp_ioctl(unsigned int cmd, void __user *arg);
extern void arp_send(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
extern int arp_bind_neighbour(struct dst_entry *dst);
extern int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir);
extern void arp_ifdown(struct net_device *dev);
extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
struct net_device *dev, __be32 src_ip,
unsigned char *dest_hw, unsigned char *src_hw,
unsigned char *target_hw);
extern void arp_xmit(struct sk_buff *skb);
extern struct neigh_ops arp_broken_ops;
#endif /* _ARP_H */

62
include/net/atmclip.h Normal file
View File

@@ -0,0 +1,62 @@
/* net/atm/atmarp.h - RFC1577 ATM ARP */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
#ifndef _ATMCLIP_H
#define _ATMCLIP_H
#include <linux/netdevice.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/atmarp.h>
#include <linux/spinlock.h>
#include <net/neighbour.h>
#define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back))
#define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key)
struct sk_buff;
struct clip_vcc {
struct atm_vcc *vcc; /* VCC descriptor */
struct atmarp_entry *entry; /* ATMARP table entry, NULL if IP addr.
isn't known yet */
int xoff; /* 1 if send buffer is full */
unsigned char encap; /* 0: NULL, 1: LLC/SNAP */
unsigned long last_use; /* last send or receive operation */
unsigned long idle_timeout; /* keep open idle for so many jiffies*/
void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
/* keep old push fn for chaining */
void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb);
/* keep old pop fn for chaining */
struct clip_vcc *next; /* next VCC */
};
struct atmarp_entry {
__be32 ip; /* IP address */
struct clip_vcc *vccs; /* active VCCs; NULL if resolution is
pending */
unsigned long expires; /* entry expiration time */
struct neighbour *neigh; /* neighbour back-pointer */
};
#define PRIV(dev) ((struct clip_priv *) netdev_priv(dev))
struct clip_priv {
int number; /* for convenience ... */
spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */
struct net_device_stats stats;
struct net_device *next; /* next CLIP interface */
};
#ifdef __KERNEL__
extern struct neigh_table *clip_tbl_hook;
#endif
#endif

445
include/net/ax25.h Normal file
View File

@@ -0,0 +1,445 @@
/*
* Declarations of AX.25 type objects.
*
* Alan Cox (GW4PTS) 10/11/93
*/
#ifndef _AX25_H
#define _AX25_H
#include <linux/ax25.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <asm/atomic.h>
#define AX25_T1CLAMPLO 1
#define AX25_T1CLAMPHI (30 * HZ)
#define AX25_BPQ_HEADER_LEN 16
#define AX25_KISS_HEADER_LEN 1
#define AX25_HEADER_LEN 17
#define AX25_ADDR_LEN 7
#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN)
#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN)
/* AX.25 Protocol IDs */
#define AX25_P_ROSE 0x01
#define AX25_P_VJCOMP 0x06 /* Compressed TCP/IP packet */
/* Van Jacobsen (RFC 1144) */
#define AX25_P_VJUNCOMP 0x07 /* Uncompressed TCP/IP packet */
/* Van Jacobsen (RFC 1144) */
#define AX25_P_SEGMENT 0x08 /* Segmentation fragment */
#define AX25_P_TEXNET 0xc3 /* TEXTNET datagram protocol */
#define AX25_P_LQ 0xc4 /* Link Quality Protocol */
#define AX25_P_ATALK 0xca /* Appletalk */
#define AX25_P_ATALK_ARP 0xcb /* Appletalk ARP */
#define AX25_P_IP 0xcc /* ARPA Internet Protocol */
#define AX25_P_ARP 0xcd /* ARPA Adress Resolution */
#define AX25_P_FLEXNET 0xce /* FlexNet */
#define AX25_P_NETROM 0xcf /* NET/ROM */
#define AX25_P_TEXT 0xF0 /* No layer 3 protocol impl. */
/* AX.25 Segment control values */
#define AX25_SEG_REM 0x7F
#define AX25_SEG_FIRST 0x80
#define AX25_CBIT 0x80 /* Command/Response bit */
#define AX25_EBIT 0x01 /* HDLC Address Extension bit */
#define AX25_HBIT 0x80 /* Has been repeated bit */
#define AX25_SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */
#define AX25_ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */
#define AX25_DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */
#define AX25_COND_ACK_PENDING 0x01
#define AX25_COND_REJECT 0x02
#define AX25_COND_PEER_RX_BUSY 0x04
#define AX25_COND_OWN_RX_BUSY 0x08
#define AX25_COND_DAMA_MODE 0x10
#ifndef _LINUX_NETDEVICE_H
#include <linux/netdevice.h>
#endif
/* Upper sub-layer (LAPB) definitions */
/* Control field templates */
#define AX25_I 0x00 /* Information frames */
#define AX25_S 0x01 /* Supervisory frames */
#define AX25_RR 0x01 /* Receiver ready */
#define AX25_RNR 0x05 /* Receiver not ready */
#define AX25_REJ 0x09 /* Reject */
#define AX25_U 0x03 /* Unnumbered frames */
#define AX25_SABM 0x2f /* Set Asynchronous Balanced Mode */
#define AX25_SABME 0x6f /* Set Asynchronous Balanced Mode Extended */
#define AX25_DISC 0x43 /* Disconnect */
#define AX25_DM 0x0f /* Disconnected mode */
#define AX25_UA 0x63 /* Unnumbered acknowledge */
#define AX25_FRMR 0x87 /* Frame reject */
#define AX25_UI 0x03 /* Unnumbered information */
#define AX25_XID 0xaf /* Exchange information */
#define AX25_TEST 0xe3 /* Test */
#define AX25_PF 0x10 /* Poll/final bit for standard AX.25 */
#define AX25_EPF 0x01 /* Poll/final bit for extended AX.25 */
#define AX25_ILLEGAL 0x100 /* Impossible to be a real frame type */
#define AX25_POLLOFF 0
#define AX25_POLLON 1
/* AX25 L2 C-bit */
#define AX25_COMMAND 1
#define AX25_RESPONSE 2
/* Define Link State constants. */
enum {
AX25_STATE_0, /* Listening */
AX25_STATE_1, /* SABM sent */
AX25_STATE_2, /* DISC sent */
AX25_STATE_3, /* Established */
AX25_STATE_4 /* Recovery */
};
#define AX25_MODULUS 8 /* Standard AX.25 modulus */
#define AX25_EMODULUS 128 /* Extended AX.25 modulus */
enum {
AX25_PROTO_STD_SIMPLEX,
AX25_PROTO_STD_DUPLEX,
#ifdef CONFIG_AX25_DAMA_SLAVE
AX25_PROTO_DAMA_SLAVE,
#ifdef CONFIG_AX25_DAMA_MASTER
AX25_PROTO_DAMA_MASTER,
#define AX25_PROTO_MAX AX25_PROTO_DAMA_MASTER
#endif
#endif
__AX25_PROTO_MAX,
AX25_PROTO_MAX = __AX25_PROTO_MAX -1
};
enum {
AX25_VALUES_IPDEFMODE, /* 0=DG 1=VC */
AX25_VALUES_AXDEFMODE, /* 0=Normal 1=Extended Seq Nos */
AX25_VALUES_BACKOFF, /* 0=None 1=Linear 2=Exponential */
AX25_VALUES_CONMODE, /* Allow connected modes - 0=No 1=no "PID text" 2=all PIDs */
AX25_VALUES_WINDOW, /* Default window size for standard AX.25 */
AX25_VALUES_EWINDOW, /* Default window size for extended AX.25 */
AX25_VALUES_T1, /* Default T1 timeout value */
AX25_VALUES_T2, /* Default T2 timeout value */
AX25_VALUES_T3, /* Default T3 timeout value */
AX25_VALUES_IDLE, /* Connected mode idle timer */
AX25_VALUES_N2, /* Default N2 value */
AX25_VALUES_PACLEN, /* AX.25 MTU */
AX25_VALUES_PROTOCOL, /* Std AX.25, DAMA Slave, DAMA Master */
AX25_VALUES_DS_TIMEOUT, /* DAMA Slave timeout */
AX25_MAX_VALUES /* THIS MUST REMAIN THE LAST ENTRY OF THIS LIST */
};
#define AX25_DEF_IPDEFMODE 0 /* Datagram */
#define AX25_DEF_AXDEFMODE 0 /* Normal */
#define AX25_DEF_BACKOFF 1 /* Linear backoff */
#define AX25_DEF_CONMODE 2 /* Connected mode allowed */
#define AX25_DEF_WINDOW 2 /* Window=2 */
#define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */
#define AX25_DEF_T1 10000 /* T1=10s */
#define AX25_DEF_T2 3000 /* T2=3s */
#define AX25_DEF_T3 300000 /* T3=300s */
#define AX25_DEF_N2 10 /* N2=10 */
#define AX25_DEF_IDLE 0 /* Idle=None */
#define AX25_DEF_PACLEN 256 /* Paclen=256 */
#define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */
#define AX25_DEF_DS_TIMEOUT 180000 /* DAMA timeout 3 minutes */
typedef struct ax25_uid_assoc {
struct hlist_node uid_node;
atomic_t refcount;
uid_t uid;
ax25_address call;
} ax25_uid_assoc;
#define ax25_uid_for_each(__ax25, node, list) \
hlist_for_each_entry(__ax25, node, list, uid_node)
#define ax25_uid_hold(ax25) \
atomic_inc(&((ax25)->refcount))
static inline void ax25_uid_put(ax25_uid_assoc *assoc)
{
if (atomic_dec_and_test(&assoc->refcount)) {
kfree(assoc);
}
}
typedef struct {
ax25_address calls[AX25_MAX_DIGIS];
unsigned char repeated[AX25_MAX_DIGIS];
unsigned char ndigi;
signed char lastrepeat;
} ax25_digi;
typedef struct ax25_route {
struct ax25_route *next;
atomic_t refcount;
ax25_address callsign;
struct net_device *dev;
ax25_digi *digipeat;
char ip_mode;
} ax25_route;
static inline void ax25_hold_route(ax25_route *ax25_rt)
{
atomic_inc(&ax25_rt->refcount);
}
extern void __ax25_put_route(ax25_route *ax25_rt);
static inline void ax25_put_route(ax25_route *ax25_rt)
{
if (atomic_dec_and_test(&ax25_rt->refcount))
__ax25_put_route(ax25_rt);
}
typedef struct {
char slave; /* slave_mode? */
struct timer_list slave_timer; /* timeout timer */
unsigned short slave_timeout; /* when? */
} ax25_dama_info;
struct ctl_table;
typedef struct ax25_dev {
struct ax25_dev *next;
struct net_device *dev;
struct net_device *forward;
struct ctl_table *systable;
int values[AX25_MAX_VALUES];
#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
ax25_dama_info dama;
#endif
} ax25_dev;
typedef struct ax25_cb {
struct hlist_node ax25_node;
ax25_address source_addr, dest_addr;
ax25_digi *digipeat;
ax25_dev *ax25_dev;
unsigned char iamdigi;
unsigned char state, modulus, pidincl;
unsigned short vs, vr, va;
unsigned char condition, backoff;
unsigned char n2, n2count;
struct timer_list t1timer, t2timer, t3timer, idletimer;
unsigned long t1, t2, t3, idle, rtt;
unsigned short paclen, fragno, fraglen;
struct sk_buff_head write_queue;
struct sk_buff_head reseq_queue;
struct sk_buff_head ack_queue;
struct sk_buff_head frag_queue;
unsigned char window;
struct timer_list timer, dtimer;
struct sock *sk; /* Backlink to socket */
atomic_t refcount;
} ax25_cb;
#define ax25_sk(__sk) ((ax25_cb *)(__sk)->sk_protinfo)
#define ax25_for_each(__ax25, node, list) \
hlist_for_each_entry(__ax25, node, list, ax25_node)
#define ax25_cb_hold(__ax25) \
atomic_inc(&((__ax25)->refcount))
static __inline__ void ax25_cb_put(ax25_cb *ax25)
{
if (atomic_dec_and_test(&ax25->refcount)) {
kfree(ax25->digipeat);
kfree(ax25);
}
}
static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
{
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
skb->mac.raw = skb->data;
return htons(ETH_P_AX25);
}
/* af_ax25.c */
extern struct hlist_head ax25_list;
extern spinlock_t ax25_list_lock;
extern void ax25_cb_add(ax25_cb *);
struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
extern void ax25_destroy_socket(ax25_cb *);
extern ax25_cb * __must_check ax25_create_cb(void);
extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
/* ax25_addr.c */
extern const ax25_address ax25_bcast;
extern const ax25_address ax25_defaddr;
extern const ax25_address null_ax25_address;
extern char *ax2asc(char *buf, const ax25_address *);
extern void asc2ax(ax25_address *addr, const char *callsign);
extern int ax25cmp(const ax25_address *, const ax25_address *);
extern int ax25digicmp(const ax25_digi *, const ax25_digi *);
extern const unsigned char *ax25_addr_parse(const unsigned char *, int,
ax25_address *, ax25_address *, ax25_digi *, int *, int *);
extern int ax25_addr_build(unsigned char *, const ax25_address *,
const ax25_address *, const ax25_digi *, int, int);
extern int ax25_addr_size(const ax25_digi *);
extern void ax25_digi_invert(const ax25_digi *, ax25_digi *);
/* ax25_dev.c */
extern ax25_dev *ax25_dev_list;
extern spinlock_t ax25_dev_lock;
static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
{
return dev->ax25_ptr;
}
extern ax25_dev *ax25_addr_ax25dev(ax25_address *);
extern void ax25_dev_device_up(struct net_device *);
extern void ax25_dev_device_down(struct net_device *);
extern int ax25_fwd_ioctl(unsigned int, struct ax25_fwd_struct *);
extern struct net_device *ax25_fwd_dev(struct net_device *);
extern void ax25_dev_free(void);
/* ax25_ds_in.c */
extern int ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int);
/* ax25_ds_subr.c */
extern void ax25_ds_nr_error_recovery(ax25_cb *);
extern void ax25_ds_enquiry_response(ax25_cb *);
extern void ax25_ds_establish_data_link(ax25_cb *);
extern void ax25_dev_dama_off(ax25_dev *);
extern void ax25_dama_on(ax25_cb *);
extern void ax25_dama_off(ax25_cb *);
/* ax25_ds_timer.c */
extern void ax25_ds_set_timer(ax25_dev *);
extern void ax25_ds_del_timer(ax25_dev *);
extern void ax25_ds_timer(ax25_cb *);
extern void ax25_ds_t1_timeout(ax25_cb *);
extern void ax25_ds_heartbeat_expiry(ax25_cb *);
extern void ax25_ds_t3timer_expiry(ax25_cb *);
extern void ax25_ds_idletimer_expiry(ax25_cb *);
/* ax25_iface.c */
struct ax25_protocol {
struct ax25_protocol *next;
unsigned int pid;
int (*func)(struct sk_buff *, ax25_cb *);
};
extern void ax25_register_pid(struct ax25_protocol *ap);
extern void ax25_protocol_release(unsigned int);
struct ax25_linkfail {
struct hlist_node lf_node;
void (*func)(ax25_cb *, int);
};
extern void ax25_linkfail_register(struct ax25_linkfail *lf);
extern void ax25_linkfail_release(struct ax25_linkfail *lf);
extern int __must_check ax25_listen_register(ax25_address *,
struct net_device *);
extern void ax25_listen_release(ax25_address *, struct net_device *);
extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
extern int ax25_listen_mine(ax25_address *, struct net_device *);
extern void ax25_link_failed(ax25_cb *, int);
extern int ax25_protocol_is_registered(unsigned int);
/* ax25_in.c */
extern int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
extern int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
/* ax25_ip.c */
extern int ax25_hard_header(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int);
extern int ax25_rebuild_header(struct sk_buff *);
/* ax25_out.c */
extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
extern void ax25_output(ax25_cb *, int, struct sk_buff *);
extern void ax25_kick(ax25_cb *);
extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int);
extern void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev);
extern int ax25_check_iframes_acked(ax25_cb *, unsigned short);
/* ax25_route.c */
extern void ax25_rt_device_down(struct net_device *);
extern int ax25_rt_ioctl(unsigned int, void __user *);
extern const struct file_operations ax25_route_fops;
extern ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *);
extern void ax25_rt_free(void);
/* ax25_std_in.c */
extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int);
/* ax25_std_subr.c */
extern void ax25_std_nr_error_recovery(ax25_cb *);
extern void ax25_std_establish_data_link(ax25_cb *);
extern void ax25_std_transmit_enquiry(ax25_cb *);
extern void ax25_std_enquiry_response(ax25_cb *);
extern void ax25_std_timeout_response(ax25_cb *);
/* ax25_std_timer.c */
extern void ax25_std_heartbeat_expiry(ax25_cb *);
extern void ax25_std_t1timer_expiry(ax25_cb *);
extern void ax25_std_t2timer_expiry(ax25_cb *);
extern void ax25_std_t3timer_expiry(ax25_cb *);
extern void ax25_std_idletimer_expiry(ax25_cb *);
/* ax25_subr.c */
extern void ax25_clear_queues(ax25_cb *);
extern void ax25_frames_acked(ax25_cb *, unsigned short);
extern void ax25_requeue_frames(ax25_cb *);
extern int ax25_validate_nr(ax25_cb *, unsigned short);
extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *);
extern void ax25_send_control(ax25_cb *, int, int, int);
extern void ax25_return_dm(struct net_device *, ax25_address *, ax25_address *, ax25_digi *);
extern void ax25_calculate_t1(ax25_cb *);
extern void ax25_calculate_rtt(ax25_cb *);
extern void ax25_disconnect(ax25_cb *, int);
/* ax25_timer.c */
extern void ax25_start_heartbeat(ax25_cb *);
extern void ax25_start_t1timer(ax25_cb *);
extern void ax25_start_t2timer(ax25_cb *);
extern void ax25_start_t3timer(ax25_cb *);
extern void ax25_start_idletimer(ax25_cb *);
extern void ax25_stop_heartbeat(ax25_cb *);
extern void ax25_stop_t1timer(ax25_cb *);
extern void ax25_stop_t2timer(ax25_cb *);
extern void ax25_stop_t3timer(ax25_cb *);
extern void ax25_stop_idletimer(ax25_cb *);
extern int ax25_t1timer_running(ax25_cb *);
extern unsigned long ax25_display_timer(struct timer_list *);
/* ax25_uid.c */
extern int ax25_uid_policy;
extern ax25_uid_assoc *ax25_findbyuid(uid_t);
extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *);
extern const struct file_operations ax25_uid_fops;
extern void ax25_uid_free(void);
/* sysctl_net_ax25.c */
#ifdef CONFIG_SYSCTL
extern void ax25_register_sysctl(void);
extern void ax25_unregister_sysctl(void);
#else
static inline void ax25_register_sysctl(void) {};
static inline void ax25_unregister_sysctl(void) {};
#endif /* CONFIG_SYSCTL */
#endif

View File

@@ -0,0 +1,180 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __BLUETOOTH_H
#define __BLUETOOTH_H
#include <asm/types.h>
#include <asm/byteorder.h>
#include <linux/list.h>
#include <linux/poll.h>
#include <net/sock.h>
#ifndef AF_BLUETOOTH
#define AF_BLUETOOTH 31
#define PF_BLUETOOTH AF_BLUETOOTH
#endif
/* Reserv for core and drivers use */
#define BT_SKB_RESERVE 8
#define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1
#define BTPROTO_SCO 2
#define BTPROTO_RFCOMM 3
#define BTPROTO_BNEP 4
#define BTPROTO_CMTP 5
#define BTPROTO_HIDP 6
#define BTPROTO_AVDTP 7
#define SOL_HCI 0
#define SOL_L2CAP 6
#define SOL_SCO 17
#define SOL_RFCOMM 18
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
/* Connection and socket states */
enum {
BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
BT_OPEN,
BT_BOUND,
BT_LISTEN,
BT_CONNECT,
BT_CONNECT2,
BT_CONFIG,
BT_DISCONN,
BT_CLOSED
};
/* Endianness conversions */
#define htobs(a) __cpu_to_le16(a)
#define htobl(a) __cpu_to_le32(a)
#define btohs(a) __le16_to_cpu(a)
#define btohl(a) __le32_to_cpu(a)
/* BD Address */
typedef struct {
__u8 b[6];
} __attribute__((packed)) bdaddr_t;
#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
/* Copy, swap, convert BD Address */
static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
{
return memcmp(ba1, ba2, sizeof(bdaddr_t));
}
static inline void bacpy(bdaddr_t *dst, bdaddr_t *src)
{
memcpy(dst, src, sizeof(bdaddr_t));
}
void baswap(bdaddr_t *dst, bdaddr_t *src);
char *batostr(bdaddr_t *ba);
bdaddr_t *strtoba(char *str);
/* Common socket structures and functions */
#define bt_sk(__sk) ((struct bt_sock *) __sk)
struct bt_sock {
struct sock sk;
bdaddr_t src;
bdaddr_t dst;
struct list_head accept_q;
struct sock *parent;
};
struct bt_sock_list {
struct hlist_head head;
rwlock_t lock;
};
int bt_sock_register(int proto, struct net_proto_family *ops);
int bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
void bt_accept_enqueue(struct sock *parent, struct sock *sk);
void bt_accept_unlink(struct sock *sk);
struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */
struct bt_skb_cb {
__u8 pkt_type;
__u8 incoming;
};
#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb))
static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
{
struct sk_buff *skb;
if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) {
skb_reserve(skb, BT_SKB_RESERVE);
bt_cb(skb)->incoming = 0;
}
return skb;
}
static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len,
int nb, int *err)
{
struct sk_buff *skb;
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
skb_reserve(skb, BT_SKB_RESERVE);
bt_cb(skb)->incoming = 0;
}
return skb;
}
static inline int skb_frags_no(struct sk_buff *skb)
{
register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
register int n = 1;
for (; frag; frag=frag->next, n++);
return n;
}
int bt_err(__u16 code);
extern int hci_sock_init(void);
extern int hci_sock_cleanup(void);
extern int bt_sysfs_init(void);
extern void bt_sysfs_cleanup(void);
extern struct class *bt_class;
#endif /* __BLUETOOTH_H */

833
include/net/bluetooth/hci.h Normal file
View File

@@ -0,0 +1,833 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __HCI_H
#define __HCI_H
#define HCI_MAX_ACL_SIZE 1024
#define HCI_MAX_SCO_SIZE 255
#define HCI_MAX_EVENT_SIZE 260
#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
/* HCI dev events */
#define HCI_DEV_REG 1
#define HCI_DEV_UNREG 2
#define HCI_DEV_UP 3
#define HCI_DEV_DOWN 4
#define HCI_DEV_SUSPEND 5
#define HCI_DEV_RESUME 6
/* HCI notify events */
#define HCI_NOTIFY_CONN_ADD 1
#define HCI_NOTIFY_CONN_DEL 2
#define HCI_NOTIFY_VOICE_SETTING 3
/* HCI device types */
#define HCI_VIRTUAL 0
#define HCI_USB 1
#define HCI_PCCARD 2
#define HCI_UART 3
#define HCI_RS232 4
#define HCI_PCI 5
#define HCI_SDIO 6
/* HCI device quirks */
enum {
HCI_QUIRK_RESET_ON_INIT,
HCI_QUIRK_RAW_DEVICE,
HCI_QUIRK_FIXUP_BUFFER_SIZE
};
/* HCI device flags */
enum {
HCI_UP,
HCI_INIT,
HCI_RUNNING,
HCI_PSCAN,
HCI_ISCAN,
HCI_AUTH,
HCI_ENCRYPT,
HCI_INQUIRY,
HCI_RAW,
HCI_SECMGR
};
/* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int)
#define HCIDEVRESET _IOW('H', 203, int)
#define HCIDEVRESTAT _IOW('H', 204, int)
#define HCIGETDEVLIST _IOR('H', 210, int)
#define HCIGETDEVINFO _IOR('H', 211, int)
#define HCIGETCONNLIST _IOR('H', 212, int)
#define HCIGETCONNINFO _IOR('H', 213, int)
#define HCISETRAW _IOW('H', 220, int)
#define HCISETSCAN _IOW('H', 221, int)
#define HCISETAUTH _IOW('H', 222, int)
#define HCISETENCRYPT _IOW('H', 223, int)
#define HCISETPTYPE _IOW('H', 224, int)
#define HCISETLINKPOL _IOW('H', 225, int)
#define HCISETLINKMODE _IOW('H', 226, int)
#define HCISETACLMTU _IOW('H', 227, int)
#define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETSECMGR _IOW('H', 230, int)
#define HCIINQUIRY _IOR('H', 240, int)
/* HCI timeouts */
#define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */
#define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */
#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */
#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */
/* HCI Packet types */
#define HCI_COMMAND_PKT 0x01
#define HCI_ACLDATA_PKT 0x02
#define HCI_SCODATA_PKT 0x03
#define HCI_EVENT_PKT 0x04
#define HCI_VENDOR_PKT 0xff
/* HCI Packet types */
#define HCI_DM1 0x0008
#define HCI_DM3 0x0400
#define HCI_DM5 0x4000
#define HCI_DH1 0x0010
#define HCI_DH3 0x0800
#define HCI_DH5 0x8000
#define HCI_HV1 0x0020
#define HCI_HV2 0x0040
#define HCI_HV3 0x0080
#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
/* ACL flags */
#define ACL_CONT 0x01
#define ACL_START 0x02
#define ACL_ACTIVE_BCAST 0x04
#define ACL_PICO_BCAST 0x08
/* Baseband links */
#define SCO_LINK 0x00
#define ACL_LINK 0x01
/* LMP features */
#define LMP_3SLOT 0x01
#define LMP_5SLOT 0x02
#define LMP_ENCRYPT 0x04
#define LMP_SOFFSET 0x08
#define LMP_TACCURACY 0x10
#define LMP_RSWITCH 0x20
#define LMP_HOLD 0x40
#define LMP_SNIFF 0x80
#define LMP_PARK 0x01
#define LMP_RSSI 0x02
#define LMP_QUALITY 0x04
#define LMP_SCO 0x08
#define LMP_HV2 0x10
#define LMP_HV3 0x20
#define LMP_ULAW 0x40
#define LMP_ALAW 0x80
#define LMP_CVSD 0x01
#define LMP_PSCHEME 0x02
#define LMP_PCONTROL 0x04
#define LMP_SNIFF_SUBR 0x02
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
#define HCI_CM_HOLD 0x0001
#define HCI_CM_SNIFF 0x0002
#define HCI_CM_PARK 0x0003
/* Link policies */
#define HCI_LP_RSWITCH 0x0001
#define HCI_LP_HOLD 0x0002
#define HCI_LP_SNIFF 0x0004
#define HCI_LP_PARK 0x0008
/* Link modes */
#define HCI_LM_ACCEPT 0x8000
#define HCI_LM_MASTER 0x0001
#define HCI_LM_AUTH 0x0002
#define HCI_LM_ENCRYPT 0x0004
#define HCI_LM_TRUSTED 0x0008
#define HCI_LM_RELIABLE 0x0010
#define HCI_LM_SECURE 0x0020
/* ----- HCI Commands ---- */
/* OGF & OCF values */
/* Informational Parameters */
#define OGF_INFO_PARAM 0x04
#define OCF_READ_LOCAL_VERSION 0x0001
struct hci_rp_read_loc_version {
__u8 status;
__u8 hci_ver;
__le16 hci_rev;
__u8 lmp_ver;
__le16 manufacturer;
__le16 lmp_subver;
} __attribute__ ((packed));
#define OCF_READ_LOCAL_FEATURES 0x0003
struct hci_rp_read_local_features {
__u8 status;
__u8 features[8];
} __attribute__ ((packed));
#define OCF_READ_BUFFER_SIZE 0x0005
struct hci_rp_read_buffer_size {
__u8 status;
__le16 acl_mtu;
__u8 sco_mtu;
__le16 acl_max_pkt;
__le16 sco_max_pkt;
} __attribute__ ((packed));
#define OCF_READ_BD_ADDR 0x0009
struct hci_rp_read_bd_addr {
__u8 status;
bdaddr_t bdaddr;
} __attribute__ ((packed));
/* Host Controller and Baseband */
#define OGF_HOST_CTL 0x03
#define OCF_RESET 0x0003
#define OCF_READ_AUTH_ENABLE 0x001F
#define OCF_WRITE_AUTH_ENABLE 0x0020
#define AUTH_DISABLED 0x00
#define AUTH_ENABLED 0x01
#define OCF_READ_ENCRYPT_MODE 0x0021
#define OCF_WRITE_ENCRYPT_MODE 0x0022
#define ENCRYPT_DISABLED 0x00
#define ENCRYPT_P2P 0x01
#define ENCRYPT_BOTH 0x02
#define OCF_WRITE_CA_TIMEOUT 0x0016
#define OCF_WRITE_PG_TIMEOUT 0x0018
#define OCF_WRITE_SCAN_ENABLE 0x001A
#define SCAN_DISABLED 0x00
#define SCAN_INQUIRY 0x01
#define SCAN_PAGE 0x02
#define OCF_SET_EVENT_FLT 0x0005
struct hci_cp_set_event_flt {
__u8 flt_type;
__u8 cond_type;
__u8 condition[0];
} __attribute__ ((packed));
/* Filter types */
#define HCI_FLT_CLEAR_ALL 0x00
#define HCI_FLT_INQ_RESULT 0x01
#define HCI_FLT_CONN_SETUP 0x02
/* CONN_SETUP Condition types */
#define HCI_CONN_SETUP_ALLOW_ALL 0x00
#define HCI_CONN_SETUP_ALLOW_CLASS 0x01
#define HCI_CONN_SETUP_ALLOW_BDADDR 0x02
/* CONN_SETUP Conditions */
#define HCI_CONN_SETUP_AUTO_OFF 0x01
#define HCI_CONN_SETUP_AUTO_ON 0x02
#define OCF_READ_CLASS_OF_DEV 0x0023
struct hci_rp_read_dev_class {
__u8 status;
__u8 dev_class[3];
} __attribute__ ((packed));
#define OCF_WRITE_CLASS_OF_DEV 0x0024
struct hci_cp_write_dev_class {
__u8 dev_class[3];
} __attribute__ ((packed));
#define OCF_READ_VOICE_SETTING 0x0025
struct hci_rp_read_voice_setting {
__u8 status;
__le16 voice_setting;
} __attribute__ ((packed));
#define OCF_WRITE_VOICE_SETTING 0x0026
struct hci_cp_write_voice_setting {
__le16 voice_setting;
} __attribute__ ((packed));
#define OCF_HOST_BUFFER_SIZE 0x0033
struct hci_cp_host_buffer_size {
__le16 acl_mtu;
__u8 sco_mtu;
__le16 acl_max_pkt;
__le16 sco_max_pkt;
} __attribute__ ((packed));
/* Link Control */
#define OGF_LINK_CTL 0x01
#define OCF_CREATE_CONN 0x0005
struct hci_cp_create_conn {
bdaddr_t bdaddr;
__le16 pkt_type;
__u8 pscan_rep_mode;
__u8 pscan_mode;
__le16 clock_offset;
__u8 role_switch;
} __attribute__ ((packed));
#define OCF_CREATE_CONN_CANCEL 0x0008
struct hci_cp_create_conn_cancel {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define OCF_ACCEPT_CONN_REQ 0x0009
struct hci_cp_accept_conn_req {
bdaddr_t bdaddr;
__u8 role;
} __attribute__ ((packed));
#define OCF_REJECT_CONN_REQ 0x000a
struct hci_cp_reject_conn_req {
bdaddr_t bdaddr;
__u8 reason;
} __attribute__ ((packed));
#define OCF_DISCONNECT 0x0006
struct hci_cp_disconnect {
__le16 handle;
__u8 reason;
} __attribute__ ((packed));
#define OCF_ADD_SCO 0x0007
struct hci_cp_add_sco {
__le16 handle;
__le16 pkt_type;
} __attribute__ ((packed));
#define OCF_INQUIRY 0x0001
struct hci_cp_inquiry {
__u8 lap[3];
__u8 length;
__u8 num_rsp;
} __attribute__ ((packed));
#define OCF_INQUIRY_CANCEL 0x0002
#define OCF_EXIT_PERIODIC_INQ 0x0004
#define OCF_LINK_KEY_REPLY 0x000B
struct hci_cp_link_key_reply {
bdaddr_t bdaddr;
__u8 link_key[16];
} __attribute__ ((packed));
#define OCF_LINK_KEY_NEG_REPLY 0x000C
struct hci_cp_link_key_neg_reply {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define OCF_PIN_CODE_REPLY 0x000D
struct hci_cp_pin_code_reply {
bdaddr_t bdaddr;
__u8 pin_len;
__u8 pin_code[16];
} __attribute__ ((packed));
#define OCF_PIN_CODE_NEG_REPLY 0x000E
struct hci_cp_pin_code_neg_reply {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define OCF_CHANGE_CONN_PTYPE 0x000F
struct hci_cp_change_conn_ptype {
__le16 handle;
__le16 pkt_type;
} __attribute__ ((packed));
#define OCF_AUTH_REQUESTED 0x0011
struct hci_cp_auth_requested {
__le16 handle;
} __attribute__ ((packed));
#define OCF_SET_CONN_ENCRYPT 0x0013
struct hci_cp_set_conn_encrypt {
__le16 handle;
__u8 encrypt;
} __attribute__ ((packed));
#define OCF_CHANGE_CONN_LINK_KEY 0x0015
struct hci_cp_change_conn_link_key {
__le16 handle;
} __attribute__ ((packed));
#define OCF_READ_REMOTE_FEATURES 0x001B
struct hci_cp_read_remote_features {
__le16 handle;
} __attribute__ ((packed));
#define OCF_READ_REMOTE_VERSION 0x001D
struct hci_cp_read_remote_version {
__le16 handle;
} __attribute__ ((packed));
/* Link Policy */
#define OGF_LINK_POLICY 0x02
#define OCF_SNIFF_MODE 0x0003
struct hci_cp_sniff_mode {
__le16 handle;
__le16 max_interval;
__le16 min_interval;
__le16 attempt;
__le16 timeout;
} __attribute__ ((packed));
#define OCF_EXIT_SNIFF_MODE 0x0004
struct hci_cp_exit_sniff_mode {
__le16 handle;
} __attribute__ ((packed));
#define OCF_ROLE_DISCOVERY 0x0009
struct hci_cp_role_discovery {
__le16 handle;
} __attribute__ ((packed));
struct hci_rp_role_discovery {
__u8 status;
__le16 handle;
__u8 role;
} __attribute__ ((packed));
#define OCF_READ_LINK_POLICY 0x000C
struct hci_cp_read_link_policy {
__le16 handle;
} __attribute__ ((packed));
struct hci_rp_read_link_policy {
__u8 status;
__le16 handle;
__le16 policy;
} __attribute__ ((packed));
#define OCF_SWITCH_ROLE 0x000B
struct hci_cp_switch_role {
bdaddr_t bdaddr;
__u8 role;
} __attribute__ ((packed));
#define OCF_WRITE_LINK_POLICY 0x000D
struct hci_cp_write_link_policy {
__le16 handle;
__le16 policy;
} __attribute__ ((packed));
struct hci_rp_write_link_policy {
__u8 status;
__le16 handle;
} __attribute__ ((packed));
#define OCF_SNIFF_SUBRATE 0x0011
struct hci_cp_sniff_subrate {
__le16 handle;
__le16 max_latency;
__le16 min_remote_timeout;
__le16 min_local_timeout;
} __attribute__ ((packed));
/* Status params */
#define OGF_STATUS_PARAM 0x05
/* Testing commands */
#define OGF_TESTING_CMD 0x3E
/* Vendor specific commands */
#define OGF_VENDOR_CMD 0x3F
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
#define HCI_EV_INQUIRY_RESULT 0x02
struct inquiry_info {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
__le16 clock_offset;
} __attribute__ ((packed));
#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
struct inquiry_info_with_rssi {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 dev_class[3];
__le16 clock_offset;
__s8 rssi;
} __attribute__ ((packed));
struct inquiry_info_with_rssi_and_pscan_mode {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
__le16 clock_offset;
__s8 rssi;
} __attribute__ ((packed));
#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2F
struct extended_inquiry_info {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 dev_class[3];
__le16 clock_offset;
__s8 rssi;
__u8 data[240];
} __attribute__ ((packed));
#define HCI_EV_CONN_COMPLETE 0x03
struct hci_ev_conn_complete {
__u8 status;
__le16 handle;
bdaddr_t bdaddr;
__u8 link_type;
__u8 encr_mode;
} __attribute__ ((packed));
#define HCI_EV_CONN_REQUEST 0x04
struct hci_ev_conn_request {
bdaddr_t bdaddr;
__u8 dev_class[3];
__u8 link_type;
} __attribute__ ((packed));
#define HCI_EV_DISCONN_COMPLETE 0x05
struct hci_ev_disconn_complete {
__u8 status;
__le16 handle;
__u8 reason;
} __attribute__ ((packed));
#define HCI_EV_AUTH_COMPLETE 0x06
struct hci_ev_auth_complete {
__u8 status;
__le16 handle;
} __attribute__ ((packed));
#define HCI_EV_ENCRYPT_CHANGE 0x08
struct hci_ev_encrypt_change {
__u8 status;
__le16 handle;
__u8 encrypt;
} __attribute__ ((packed));
#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09
struct hci_ev_change_conn_link_key_complete {
__u8 status;
__le16 handle;
} __attribute__ ((packed));
#define HCI_EV_QOS_SETUP_COMPLETE 0x0D
struct hci_qos {
__u8 service_type;
__u32 token_rate;
__u32 peak_bandwidth;
__u32 latency;
__u32 delay_variation;
} __attribute__ ((packed));
struct hci_ev_qos_setup_complete {
__u8 status;
__le16 handle;
struct hci_qos qos;
} __attribute__ ((packed));
#define HCI_EV_CMD_COMPLETE 0x0E
struct hci_ev_cmd_complete {
__u8 ncmd;
__le16 opcode;
} __attribute__ ((packed));
#define HCI_EV_CMD_STATUS 0x0F
struct hci_ev_cmd_status {
__u8 status;
__u8 ncmd;
__le16 opcode;
} __attribute__ ((packed));
#define HCI_EV_NUM_COMP_PKTS 0x13
struct hci_ev_num_comp_pkts {
__u8 num_hndl;
/* variable length part */
} __attribute__ ((packed));
#define HCI_EV_ROLE_CHANGE 0x12
struct hci_ev_role_change {
__u8 status;
bdaddr_t bdaddr;
__u8 role;
} __attribute__ ((packed));
#define HCI_EV_MODE_CHANGE 0x14
struct hci_ev_mode_change {
__u8 status;
__le16 handle;
__u8 mode;
__le16 interval;
} __attribute__ ((packed));
#define HCI_EV_PIN_CODE_REQ 0x16
struct hci_ev_pin_code_req {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define HCI_EV_LINK_KEY_REQ 0x17
struct hci_ev_link_key_req {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define HCI_EV_LINK_KEY_NOTIFY 0x18
struct hci_ev_link_key_notify {
bdaddr_t bdaddr;
__u8 link_key[16];
__u8 key_type;
} __attribute__ ((packed));
#define HCI_EV_REMOTE_FEATURES 0x0B
struct hci_ev_remote_features {
__u8 status;
__le16 handle;
__u8 features[8];
} __attribute__ ((packed));
#define HCI_EV_REMOTE_VERSION 0x0C
struct hci_ev_remote_version {
__u8 status;
__le16 handle;
__u8 lmp_ver;
__le16 manufacturer;
__le16 lmp_subver;
} __attribute__ ((packed));
#define HCI_EV_CLOCK_OFFSET 0x01C
struct hci_ev_clock_offset {
__u8 status;
__le16 handle;
__le16 clock_offset;
} __attribute__ ((packed));
#define HCI_EV_PSCAN_REP_MODE 0x20
struct hci_ev_pscan_rep_mode {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
} __attribute__ ((packed));
#define HCI_EV_SNIFF_SUBRATE 0x2E
struct hci_ev_sniff_subrate {
__u8 status;
__le16 handle;
__le16 max_tx_latency;
__le16 max_rx_latency;
__le16 max_remote_timeout;
__le16 max_local_timeout;
} __attribute__ ((packed));
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xFD
struct hci_ev_stack_internal {
__u16 type;
__u8 data[0];
} __attribute__ ((packed));
#define HCI_EV_SI_DEVICE 0x01
struct hci_ev_si_device {
__u16 event;
__u16 dev_id;
} __attribute__ ((packed));
#define HCI_EV_SI_SECURITY 0x02
struct hci_ev_si_security {
__u16 event;
__u16 proto;
__u16 subproto;
__u8 incoming;
} __attribute__ ((packed));
/* ---- HCI Packet structures ---- */
#define HCI_COMMAND_HDR_SIZE 3
#define HCI_EVENT_HDR_SIZE 2
#define HCI_ACL_HDR_SIZE 4
#define HCI_SCO_HDR_SIZE 3
struct hci_command_hdr {
__le16 opcode; /* OCF & OGF */
__u8 plen;
} __attribute__ ((packed));
struct hci_event_hdr {
__u8 evt;
__u8 plen;
} __attribute__ ((packed));
struct hci_acl_hdr {
__le16 handle; /* Handle & Flags(PB, BC) */
__le16 dlen;
} __attribute__ ((packed));
struct hci_sco_hdr {
__le16 handle;
__u8 dlen;
} __attribute__ ((packed));
/* Command opcode pack/unpack */
#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10))
#define hci_opcode_ogf(op) (op >> 10)
#define hci_opcode_ocf(op) (op & 0x03ff)
/* ACL handle and flags pack/unpack */
#define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12))
#define hci_handle(h) (h & 0x0fff)
#define hci_flags(h) (h >> 12)
/* ---- HCI Sockets ---- */
/* Socket options */
#define HCI_DATA_DIR 1
#define HCI_FILTER 2
#define HCI_TIME_STAMP 3
/* CMSG flags */
#define HCI_CMSG_DIR 0x0001
#define HCI_CMSG_TSTAMP 0x0002
struct sockaddr_hci {
sa_family_t hci_family;
unsigned short hci_dev;
};
#define HCI_DEV_NONE 0xffff
struct hci_filter {
unsigned long type_mask;
unsigned long event_mask[2];
__le16 opcode;
};
struct hci_ufilter {
__u32 type_mask;
__u32 event_mask[2];
__le16 opcode;
};
#define HCI_FLT_TYPE_BITS 31
#define HCI_FLT_EVENT_BITS 63
#define HCI_FLT_OGF_BITS 63
#define HCI_FLT_OCF_BITS 127
/* ---- HCI Ioctl requests structures ---- */
struct hci_dev_stats {
__u32 err_rx;
__u32 err_tx;
__u32 cmd_tx;
__u32 evt_rx;
__u32 acl_tx;
__u32 acl_rx;
__u32 sco_tx;
__u32 sco_rx;
__u32 byte_rx;
__u32 byte_tx;
};
struct hci_dev_info {
__u16 dev_id;
char name[8];
bdaddr_t bdaddr;
__u32 flags;
__u8 type;
__u8 features[8];
__u32 pkt_type;
__u32 link_policy;
__u32 link_mode;
__u16 acl_mtu;
__u16 acl_pkts;
__u16 sco_mtu;
__u16 sco_pkts;
struct hci_dev_stats stat;
};
struct hci_conn_info {
__u16 handle;
bdaddr_t bdaddr;
__u8 type;
__u8 out;
__u16 state;
__u32 link_mode;
};
struct hci_dev_req {
__u16 dev_id;
__u32 dev_opt;
};
struct hci_dev_list_req {
__u16 dev_num;
struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
};
struct hci_conn_list_req {
__u16 dev_id;
__u16 conn_num;
struct hci_conn_info conn_info[0];
};
struct hci_conn_info_req {
bdaddr_t bdaddr;
__u8 type;
struct hci_conn_info conn_info[0];
};
struct hci_inquiry_req {
__u16 dev_id;
__u16 flags;
__u8 lap[3];
__u8 length;
__u8 num_rsp;
};
#define IREQ_CACHE_FLUSH 0x0001
#endif /* __HCI_H */

View File

@@ -0,0 +1,655 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __HCI_CORE_H
#define __HCI_CORE_H
#include <net/bluetooth/hci.h>
/* HCI upper protocols */
#define HCI_PROTO_L2CAP 0
#define HCI_PROTO_SCO 1
/* HCI Core structures */
struct inquiry_data {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
__le16 clock_offset;
__s8 rssi;
};
struct inquiry_entry {
struct inquiry_entry *next;
__u32 timestamp;
struct inquiry_data data;
};
struct inquiry_cache {
spinlock_t lock;
__u32 timestamp;
struct inquiry_entry *list;
};
struct hci_conn_hash {
struct list_head list;
spinlock_t lock;
unsigned int acl_num;
unsigned int sco_num;
};
struct hci_dev {
struct list_head list;
spinlock_t lock;
atomic_t refcnt;
char name[8];
unsigned long flags;
__u16 id;
__u8 type;
bdaddr_t bdaddr;
__u8 features[8];
__u8 hci_ver;
__u16 hci_rev;
__u16 manufacturer;
__u16 voice_setting;
__u16 pkt_type;
__u16 link_policy;
__u16 link_mode;
__u32 idle_timeout;
__u16 sniff_min_interval;
__u16 sniff_max_interval;
unsigned long quirks;
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
unsigned int acl_mtu;
unsigned int sco_mtu;
unsigned int acl_pkts;
unsigned int sco_pkts;
unsigned long cmd_last_tx;
unsigned long acl_last_tx;
unsigned long sco_last_tx;
struct tasklet_struct cmd_task;
struct tasklet_struct rx_task;
struct tasklet_struct tx_task;
struct sk_buff_head rx_q;
struct sk_buff_head raw_q;
struct sk_buff_head cmd_q;
struct sk_buff *sent_cmd;
struct semaphore req_lock;
wait_queue_head_t req_wait_q;
__u32 req_status;
__u32 req_result;
struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash;
struct hci_dev_stats stat;
struct sk_buff_head driver_init;
void *driver_data;
void *core_data;
atomic_t promisc;
struct device *parent;
struct device dev;
struct module *owner;
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
int (*send)(struct sk_buff *skb);
void (*destruct)(struct hci_dev *hdev);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
};
struct hci_conn {
struct list_head list;
atomic_t refcnt;
spinlock_t lock;
bdaddr_t dst;
__u16 handle;
__u16 state;
__u8 mode;
__u8 type;
__u8 out;
__u8 attempt;
__u8 dev_class[3];
__u8 features[8];
__u16 interval;
__u16 link_policy;
__u32 link_mode;
__u8 power_save;
unsigned long pend;
unsigned int sent;
struct sk_buff_head data_q;
struct timer_list disc_timer;
struct timer_list idle_timer;
struct work_struct work;
struct device dev;
struct hci_dev *hdev;
void *l2cap_data;
void *sco_data;
void *priv;
struct hci_conn *link;
};
extern struct hci_proto *hci_proto[];
extern struct list_head hci_dev_list;
extern struct list_head hci_cb_list;
extern rwlock_t hci_dev_list_lock;
extern rwlock_t hci_cb_list_lock;
/* ----- Inquiry cache ----- */
#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
#define inquiry_cache_lock(c) spin_lock(&c->lock)
#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
static inline void inquiry_cache_init(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
spin_lock_init(&c->lock);
c->list = NULL;
}
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
return (c->list == NULL);
}
static inline long inquiry_cache_age(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
return jiffies - c->timestamp;
}
static inline long inquiry_entry_age(struct inquiry_entry *e)
{
return jiffies - e->timestamp;
}
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
/* ----- HCI Connections ----- */
enum {
HCI_CONN_AUTH_PEND,
HCI_CONN_ENCRYPT_PEND,
HCI_CONN_RSWITCH_PEND,
HCI_CONN_MODE_CHANGE_PEND,
};
static inline void hci_conn_hash_init(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
INIT_LIST_HEAD(&h->list);
spin_lock_init(&h->lock);
h->acl_num = 0;
h->sco_num = 0;
}
static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
list_add(&c->list, &h->list);
if (c->type == ACL_LINK)
h->acl_num++;
else
h->sco_num++;
}
static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
list_del(&c->list);
if (c->type == ACL_LINK)
h->acl_num--;
else
h->sco_num--;
}
static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
__u16 handle)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct hci_conn *c;
list_for_each(p, &h->list) {
c = list_entry(p, struct hci_conn, list);
if (c->handle == handle)
return c;
}
return NULL;
}
static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
__u8 type, bdaddr_t *ba)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct hci_conn *c;
list_for_each(p, &h->list) {
c = list_entry(p, struct hci_conn, list);
if (c->type == type && !bacmp(&c->dst, ba))
return c;
}
return NULL;
}
static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
__u8 type, __u16 state)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct hci_conn *c;
list_for_each(p, &h->list) {
c = list_entry(p, struct hci_conn, list);
if (c->type == type && c->state == state)
return c;
}
return NULL;
}
void hci_acl_connect(struct hci_conn *conn);
void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
void hci_add_sco(struct hci_conn *conn, __u16 handle);
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
int hci_conn_del(struct hci_conn *conn);
void hci_conn_hash_flush(struct hci_dev *hdev);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
int hci_conn_auth(struct hci_conn *conn);
int hci_conn_encrypt(struct hci_conn *conn);
int hci_conn_change_link_key(struct hci_conn *conn);
int hci_conn_switch_role(struct hci_conn *conn, uint8_t role);
void hci_conn_enter_active_mode(struct hci_conn *conn);
void hci_conn_enter_sniff_mode(struct hci_conn *conn);
static inline void hci_conn_hold(struct hci_conn *conn)
{
atomic_inc(&conn->refcnt);
del_timer(&conn->disc_timer);
}
static inline void hci_conn_put(struct hci_conn *conn)
{
if (atomic_dec_and_test(&conn->refcnt)) {
unsigned long timeo;
if (conn->type == ACL_LINK) {
del_timer(&conn->idle_timer);
if (conn->state == BT_CONNECTED) {
timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
if (!conn->out)
timeo *= 2;
} else
timeo = msecs_to_jiffies(10);
} else
timeo = msecs_to_jiffies(10);
mod_timer(&conn->disc_timer, jiffies + timeo);
}
}
/* ----- HCI tasks ----- */
static inline void hci_sched_cmd(struct hci_dev *hdev)
{
tasklet_schedule(&hdev->cmd_task);
}
static inline void hci_sched_rx(struct hci_dev *hdev)
{
tasklet_schedule(&hdev->rx_task);
}
static inline void hci_sched_tx(struct hci_dev *hdev)
{
tasklet_schedule(&hdev->tx_task);
}
/* ----- HCI Devices ----- */
static inline void __hci_dev_put(struct hci_dev *d)
{
if (atomic_dec_and_test(&d->refcnt))
d->destruct(d);
}
static inline void hci_dev_put(struct hci_dev *d)
{
__hci_dev_put(d);
module_put(d->owner);
}
static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
{
atomic_inc(&d->refcnt);
return d;
}
static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
{
if (try_module_get(d->owner))
return __hci_dev_hold(d);
return NULL;
}
#define hci_dev_lock(d) spin_lock(&d->lock)
#define hci_dev_unlock(d) spin_unlock(&d->lock)
#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
struct hci_dev *hci_dev_get(int index);
struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
struct hci_dev *hci_alloc_dev(void);
void hci_free_dev(struct hci_dev *hdev);
int hci_register_dev(struct hci_dev *hdev);
int hci_unregister_dev(struct hci_dev *hdev);
int hci_suspend_dev(struct hci_dev *hdev);
int hci_resume_dev(struct hci_dev *hdev);
int hci_dev_open(__u16 dev);
int hci_dev_close(__u16 dev);
int hci_dev_reset(__u16 dev);
int hci_dev_reset_stat(__u16 dev);
int hci_dev_cmd(unsigned int cmd, void __user *arg);
int hci_get_dev_list(void __user *arg);
int hci_get_dev_info(void __user *arg);
int hci_get_conn_list(void __user *arg);
int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
int hci_inquiry(void __user *arg);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
/* Receive frame from HCI drivers */
static inline int hci_recv_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
&& !test_bit(HCI_INIT, &hdev->flags))) {
kfree_skb(skb);
return -ENXIO;
}
/* Incomming skb */
bt_cb(skb)->incoming = 1;
/* Time stamp */
__net_timestamp(skb);
/* Queue frame for rx task */
skb_queue_tail(&hdev->rx_q, skb);
hci_sched_rx(hdev);
return 0;
}
int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
void hci_conn_add_sysfs(struct hci_conn *conn);
void hci_conn_del_sysfs(struct hci_conn *conn);
#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
/* ----- LMP capabilities ----- */
#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH)
#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT)
#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF)
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
/* ----- HCI protocols ----- */
struct hci_proto {
char *name;
unsigned int id;
unsigned long flags;
void *priv;
int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
int (*connect_cfm) (struct hci_conn *conn, __u8 status);
int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
int (*auth_cfm) (struct hci_conn *conn, __u8 status);
int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
};
static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
{
register struct hci_proto *hp;
int mask = 0;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->connect_ind)
mask |= hp->connect_ind(hdev, bdaddr, type);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->connect_ind)
mask |= hp->connect_ind(hdev, bdaddr, type);
return mask;
}
static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
{
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->connect_cfm)
hp->connect_cfm(conn, status);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->connect_cfm)
hp->connect_cfm(conn, status);
}
static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
{
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->disconn_ind)
hp->disconn_ind(conn, reason);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->disconn_ind)
hp->disconn_ind(conn, reason);
}
static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
{
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->auth_cfm)
hp->auth_cfm(conn, status);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->auth_cfm)
hp->auth_cfm(conn, status);
}
static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
{
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->encrypt_cfm)
hp->encrypt_cfm(conn, status);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->encrypt_cfm)
hp->encrypt_cfm(conn, status);
}
int hci_register_proto(struct hci_proto *hproto);
int hci_unregister_proto(struct hci_proto *hproto);
/* ----- HCI callbacks ----- */
struct hci_cb {
struct list_head list;
char *name;
void (*auth_cfm) (struct hci_conn *conn, __u8 status);
void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
void (*key_change_cfm) (struct hci_conn *conn, __u8 status);
void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role);
};
static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
{
struct list_head *p;
hci_proto_auth_cfm(conn, status);
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
if (cb->auth_cfm)
cb->auth_cfm(conn, status);
}
read_unlock_bh(&hci_cb_list_lock);
}
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
{
struct list_head *p;
hci_proto_encrypt_cfm(conn, status);
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
if (cb->encrypt_cfm)
cb->encrypt_cfm(conn, status, encrypt);
}
read_unlock_bh(&hci_cb_list_lock);
}
static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
{
struct list_head *p;
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
if (cb->key_change_cfm)
cb->key_change_cfm(conn, status);
}
read_unlock_bh(&hci_cb_list_lock);
}
static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role)
{
struct list_head *p;
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
if (cb->role_switch_cfm)
cb->role_switch_cfm(conn, status, role);
}
read_unlock_bh(&hci_cb_list_lock);
}
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
int hci_register_notifier(struct notifier_block *nb);
int hci_unregister_notifier(struct notifier_block *nb);
int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
/* ----- HCI Sockets ----- */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
struct hci_pinfo {
struct bt_sock bt;
struct hci_dev *hdev;
struct hci_filter filter;
__u32 cmsg_mask;
};
/* HCI security filter */
#define HCI_SFLT_MAX_OGF 5
struct hci_sec_filter {
__u32 type_mask;
__u32 event_mask[2];
__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
};
/* ----- HCI requests ----- */
#define HCI_REQ_DONE 0
#define HCI_REQ_PEND 1
#define HCI_REQ_CANCELED 2
#define hci_req_lock(d) down(&d->req_lock)
#define hci_req_unlock(d) up(&d->req_lock)
void hci_req_complete(struct hci_dev *hdev, int result);
#endif /* __HCI_CORE_H */

View File

@@ -0,0 +1,238 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __L2CAP_H
#define __L2CAP_H
/* L2CAP defaults */
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
#define L2CAP_CONN_TIMEOUT (HZ * 40)
/* L2CAP socket address */
struct sockaddr_l2 {
sa_family_t l2_family;
unsigned short l2_psm;
bdaddr_t l2_bdaddr;
};
/* L2CAP socket options */
#define L2CAP_OPTIONS 0x01
struct l2cap_options {
__u16 omtu;
__u16 imtu;
__u16 flush_to;
__u8 mode;
};
#define L2CAP_CONNINFO 0x02
struct l2cap_conninfo {
__u16 hci_handle;
__u8 dev_class[3];
};
#define L2CAP_LM 0x03
#define L2CAP_LM_MASTER 0x0001
#define L2CAP_LM_AUTH 0x0002
#define L2CAP_LM_ENCRYPT 0x0004
#define L2CAP_LM_TRUSTED 0x0008
#define L2CAP_LM_RELIABLE 0x0010
#define L2CAP_LM_SECURE 0x0020
/* L2CAP command codes */
#define L2CAP_COMMAND_REJ 0x01
#define L2CAP_CONN_REQ 0x02
#define L2CAP_CONN_RSP 0x03
#define L2CAP_CONF_REQ 0x04
#define L2CAP_CONF_RSP 0x05
#define L2CAP_DISCONN_REQ 0x06
#define L2CAP_DISCONN_RSP 0x07
#define L2CAP_ECHO_REQ 0x08
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_RSP 0x0b
/* L2CAP structures */
struct l2cap_hdr {
__u16 len;
__u16 cid;
} __attribute__ ((packed));
#define L2CAP_HDR_SIZE 4
struct l2cap_cmd_hdr {
__u8 code;
__u8 ident;
__u16 len;
} __attribute__ ((packed));
#define L2CAP_CMD_HDR_SIZE 4
struct l2cap_cmd_rej {
__u16 reason;
} __attribute__ ((packed));
struct l2cap_conn_req {
__u16 psm;
__u16 scid;
} __attribute__ ((packed));
struct l2cap_conn_rsp {
__u16 dcid;
__u16 scid;
__u16 result;
__u16 status;
} __attribute__ ((packed));
/* connect result */
#define L2CAP_CR_SUCCESS 0x0000
#define L2CAP_CR_PEND 0x0001
#define L2CAP_CR_BAD_PSM 0x0002
#define L2CAP_CR_SEC_BLOCK 0x0003
#define L2CAP_CR_NO_MEM 0x0004
/* connect status */
#define L2CAP_CS_NO_INFO 0x0000
#define L2CAP_CS_AUTHEN_PEND 0x0001
#define L2CAP_CS_AUTHOR_PEND 0x0002
struct l2cap_conf_req {
__u16 dcid;
__u16 flags;
__u8 data[0];
} __attribute__ ((packed));
struct l2cap_conf_rsp {
__u16 scid;
__u16 flags;
__u16 result;
__u8 data[0];
} __attribute__ ((packed));
#define L2CAP_CONF_SUCCESS 0x00
#define L2CAP_CONF_UNACCEPT 0x01
struct l2cap_conf_opt {
__u8 type;
__u8 len;
__u8 val[0];
} __attribute__ ((packed));
#define L2CAP_CONF_OPT_SIZE 2
#define L2CAP_CONF_MTU 0x01
#define L2CAP_CONF_FLUSH_TO 0x02
#define L2CAP_CONF_QOS 0x03
#define L2CAP_CONF_RFC 0x04
#define L2CAP_CONF_MAX_SIZE 22
struct l2cap_disconn_req {
__u16 dcid;
__u16 scid;
} __attribute__ ((packed));
struct l2cap_disconn_rsp {
__u16 dcid;
__u16 scid;
} __attribute__ ((packed));
struct l2cap_info_req {
__u16 type;
__u8 data[0];
} __attribute__ ((packed));
struct l2cap_info_rsp {
__u16 type;
__u16 result;
__u8 data[0];
} __attribute__ ((packed));
/* info type */
#define L2CAP_IT_CL_MTU 0x0001
#define L2CAP_IT_FEAT_MASK 0x0002
/* info result */
#define L2CAP_IR_SUCCESS 0x0000
#define L2CAP_IR_NOTSUPP 0x0001
/* ----- L2CAP connections ----- */
struct l2cap_chan_list {
struct sock *head;
rwlock_t lock;
long num;
};
struct l2cap_conn {
struct hci_conn *hcon;
bdaddr_t *dst;
bdaddr_t *src;
unsigned int mtu;
spinlock_t lock;
struct sk_buff *rx_skb;
__u32 rx_len;
__u8 rx_ident;
__u8 tx_ident;
struct l2cap_chan_list chan_list;
};
/* ----- L2CAP channel and socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
struct l2cap_pinfo {
struct bt_sock bt;
__u16 psm;
__u16 dcid;
__u16 scid;
__u16 imtu;
__u16 omtu;
__u16 flush_to;
__u32 link_mode;
__u8 conf_state;
__u8 conf_retry;
__u16 conf_mtu;
__u8 ident;
__u16 sport;
struct l2cap_conn *conn;
struct sock *next_c;
struct sock *prev_c;
};
#define L2CAP_CONF_REQ_SENT 0x01
#define L2CAP_CONF_INPUT_DONE 0x02
#define L2CAP_CONF_OUTPUT_DONE 0x04
#define L2CAP_CONF_MAX_RETRIES 2
void l2cap_load(void);
#endif /* __L2CAP_H */

View File

@@ -0,0 +1,354 @@
/*
RFCOMM implementation for Linux Bluetooth stack (BlueZ).
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __RFCOMM_H
#define __RFCOMM_H
#define RFCOMM_PSM 3
#define RFCOMM_CONN_TIMEOUT (HZ * 30)
#define RFCOMM_DISC_TIMEOUT (HZ * 20)
#define RFCOMM_AUTH_TIMEOUT (HZ * 25)
#define RFCOMM_DEFAULT_MTU 127
#define RFCOMM_DEFAULT_CREDITS 7
#define RFCOMM_MAX_L2CAP_MTU 1013
#define RFCOMM_MAX_CREDITS 40
#define RFCOMM_SKB_HEAD_RESERVE 8
#define RFCOMM_SKB_TAIL_RESERVE 2
#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
#define RFCOMM_SABM 0x2f
#define RFCOMM_DISC 0x43
#define RFCOMM_UA 0x63
#define RFCOMM_DM 0x0f
#define RFCOMM_UIH 0xef
#define RFCOMM_TEST 0x08
#define RFCOMM_FCON 0x28
#define RFCOMM_FCOFF 0x18
#define RFCOMM_MSC 0x38
#define RFCOMM_RPN 0x24
#define RFCOMM_RLS 0x14
#define RFCOMM_PN 0x20
#define RFCOMM_NSC 0x04
#define RFCOMM_V24_FC 0x02
#define RFCOMM_V24_RTC 0x04
#define RFCOMM_V24_RTR 0x08
#define RFCOMM_V24_IC 0x40
#define RFCOMM_V24_DV 0x80
#define RFCOMM_RPN_BR_2400 0x0
#define RFCOMM_RPN_BR_4800 0x1
#define RFCOMM_RPN_BR_7200 0x2
#define RFCOMM_RPN_BR_9600 0x3
#define RFCOMM_RPN_BR_19200 0x4
#define RFCOMM_RPN_BR_38400 0x5
#define RFCOMM_RPN_BR_57600 0x6
#define RFCOMM_RPN_BR_115200 0x7
#define RFCOMM_RPN_BR_230400 0x8
#define RFCOMM_RPN_DATA_5 0x0
#define RFCOMM_RPN_DATA_6 0x1
#define RFCOMM_RPN_DATA_7 0x2
#define RFCOMM_RPN_DATA_8 0x3
#define RFCOMM_RPN_STOP_1 0
#define RFCOMM_RPN_STOP_15 1
#define RFCOMM_RPN_PARITY_NONE 0x0
#define RFCOMM_RPN_PARITY_ODD 0x1
#define RFCOMM_RPN_PARITY_EVEN 0x3
#define RFCOMM_RPN_PARITY_MARK 0x5
#define RFCOMM_RPN_PARITY_SPACE 0x7
#define RFCOMM_RPN_FLOW_NONE 0x00
#define RFCOMM_RPN_XON_CHAR 0x11
#define RFCOMM_RPN_XOFF_CHAR 0x13
#define RFCOMM_RPN_PM_BITRATE 0x0001
#define RFCOMM_RPN_PM_DATA 0x0002
#define RFCOMM_RPN_PM_STOP 0x0004
#define RFCOMM_RPN_PM_PARITY 0x0008
#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
#define RFCOMM_RPN_PM_XON 0x0020
#define RFCOMM_RPN_PM_XOFF 0x0040
#define RFCOMM_RPN_PM_FLOW 0x3F00
#define RFCOMM_RPN_PM_ALL 0x3F7F
struct rfcomm_hdr {
u8 addr;
u8 ctrl;
u8 len; // Actual size can be 2 bytes
} __attribute__ ((packed));
struct rfcomm_cmd {
u8 addr;
u8 ctrl;
u8 len;
u8 fcs;
} __attribute__ ((packed));
struct rfcomm_mcc {
u8 type;
u8 len;
} __attribute__ ((packed));
struct rfcomm_pn {
u8 dlci;
u8 flow_ctrl;
u8 priority;
u8 ack_timer;
__le16 mtu;
u8 max_retrans;
u8 credits;
} __attribute__ ((packed));
struct rfcomm_rpn {
u8 dlci;
u8 bit_rate;
u8 line_settings;
u8 flow_ctrl;
u8 xon_char;
u8 xoff_char;
__le16 param_mask;
} __attribute__ ((packed));
struct rfcomm_rls {
u8 dlci;
u8 status;
} __attribute__ ((packed));
struct rfcomm_msc {
u8 dlci;
u8 v24_sig;
} __attribute__ ((packed));
/* ---- Core structures, flags etc ---- */
struct rfcomm_session {
struct list_head list;
struct socket *sock;
unsigned long state;
unsigned long flags;
atomic_t refcnt;
int initiator;
/* Default DLC parameters */
int cfc;
uint mtu;
struct list_head dlcs;
};
struct rfcomm_dlc {
struct list_head list;
struct rfcomm_session *session;
struct sk_buff_head tx_queue;
struct timer_list timer;
spinlock_t lock;
unsigned long state;
unsigned long flags;
atomic_t refcnt;
u8 dlci;
u8 addr;
u8 priority;
u8 v24_sig;
u8 mscex;
u32 link_mode;
uint mtu;
uint cfc;
uint rx_credits;
uint tx_credits;
void *owner;
void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
void (*state_change)(struct rfcomm_dlc *d, int err);
void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
};
/* DLC and session flags */
#define RFCOMM_RX_THROTTLED 0
#define RFCOMM_TX_THROTTLED 1
#define RFCOMM_TIMED_OUT 2
#define RFCOMM_MSC_PENDING 3
#define RFCOMM_AUTH_PENDING 4
#define RFCOMM_AUTH_ACCEPT 5
#define RFCOMM_AUTH_REJECT 6
/* Scheduling flags and events */
#define RFCOMM_SCHED_STATE 0
#define RFCOMM_SCHED_RX 1
#define RFCOMM_SCHED_TX 2
#define RFCOMM_SCHED_TIMEO 3
#define RFCOMM_SCHED_AUTH 4
#define RFCOMM_SCHED_WAKEUP 31
/* MSC exchange flags */
#define RFCOMM_MSCEX_TX 1
#define RFCOMM_MSCEX_RX 2
#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
/* CFC states */
#define RFCOMM_CFC_UNKNOWN -1
#define RFCOMM_CFC_DISABLED 0
#define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS
/* ---- RFCOMM SEND RPN ---- */
int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
u8 bit_rate, u8 data_bits, u8 stop_bits,
u8 parity, u8 flow_ctrl_settings,
u8 xon_char, u8 xoff_char, u16 param_mask);
/* ---- RFCOMM DLCs (channels) ---- */
struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio);
void rfcomm_dlc_free(struct rfcomm_dlc *d);
int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
{
atomic_inc(&d->refcnt);
}
static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
{
if (atomic_dec_and_test(&d->refcnt))
rfcomm_dlc_free(d);
}
extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
{
if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
__rfcomm_dlc_throttle(d);
}
static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
{
if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
__rfcomm_dlc_unthrottle(d);
}
/* ---- RFCOMM sessions ---- */
void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
static inline void rfcomm_session_hold(struct rfcomm_session *s)
{
atomic_inc(&s->refcnt);
}
/* ---- RFCOMM sockets ---- */
struct sockaddr_rc {
sa_family_t rc_family;
bdaddr_t rc_bdaddr;
u8 rc_channel;
};
#define RFCOMM_CONNINFO 0x02
struct rfcomm_conninfo {
__u16 hci_handle;
__u8 dev_class[3];
};
#define RFCOMM_LM 0x03
#define RFCOMM_LM_MASTER 0x0001
#define RFCOMM_LM_AUTH 0x0002
#define RFCOMM_LM_ENCRYPT 0x0004
#define RFCOMM_LM_TRUSTED 0x0008
#define RFCOMM_LM_RELIABLE 0x0010
#define RFCOMM_LM_SECURE 0x0020
#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) sk)
struct rfcomm_pinfo {
struct bt_sock bt;
struct rfcomm_dlc *dlc;
u8 channel;
u32 link_mode;
};
int rfcomm_init_sockets(void);
void rfcomm_cleanup_sockets(void);
int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
/* ---- RFCOMM TTY ---- */
#define RFCOMM_MAX_DEV 256
#define RFCOMMCREATEDEV _IOW('R', 200, int)
#define RFCOMMRELEASEDEV _IOW('R', 201, int)
#define RFCOMMGETDEVLIST _IOR('R', 210, int)
#define RFCOMMGETDEVINFO _IOR('R', 211, int)
#define RFCOMMSTEALDLC _IOW('R', 220, int)
#define RFCOMM_REUSE_DLC 0
#define RFCOMM_RELEASE_ONHUP 1
#define RFCOMM_HANGUP_NOW 2
#define RFCOMM_TTY_ATTACHED 3
struct rfcomm_dev_req {
s16 dev_id;
u32 flags;
bdaddr_t src;
bdaddr_t dst;
u8 channel;
};
struct rfcomm_dev_info {
s16 id;
u32 flags;
u16 state;
bdaddr_t src;
bdaddr_t dst;
u8 channel;
};
struct rfcomm_dev_list_req {
u16 dev_num;
struct rfcomm_dev_info dev_info[0];
};
int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
int rfcomm_init_ttys(void);
void rfcomm_cleanup_ttys(void);
#endif /* __RFCOMM_H */

View File

@@ -0,0 +1,79 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __SCO_H
#define __SCO_H
/* SCO defaults */
#define SCO_DEFAULT_MTU 500
#define SCO_DEFAULT_FLUSH_TO 0xFFFF
#define SCO_CONN_TIMEOUT (HZ * 40)
#define SCO_DISCONN_TIMEOUT (HZ * 2)
#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
/* SCO socket address */
struct sockaddr_sco {
sa_family_t sco_family;
bdaddr_t sco_bdaddr;
};
/* SCO socket options */
#define SCO_OPTIONS 0x01
struct sco_options {
__u16 mtu;
};
#define SCO_CONNINFO 0x02
struct sco_conninfo {
__u16 hci_handle;
__u8 dev_class[3];
};
/* ---- SCO connections ---- */
struct sco_conn {
struct hci_conn *hcon;
bdaddr_t *dst;
bdaddr_t *src;
spinlock_t lock;
struct sock *sk;
unsigned int mtu;
};
#define sco_conn_lock(c) spin_lock(&c->lock);
#define sco_conn_unlock(c) spin_unlock(&c->lock);
/* ----- SCO socket info ----- */
#define sco_pi(sk) ((struct sco_pinfo *) sk)
struct sco_pinfo {
struct bt_sock bt;
__u32 flags;
struct sco_conn *conn;
};
#endif /* __SCO_H */

96
include/net/checksum.h Normal file
View File

@@ -0,0 +1,96 @@
/*
* 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.
*
* Checksumming functions for IP, TCP, UDP and so on
*
* Authors: Jorge Cwik, <jorge@laser.satlink.net>
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
* Borrows very liberally from tcp.c and ip.c, see those
* files for more names.
*
* 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 _CHECKSUM_H
#define _CHECKSUM_H
#include <linux/errno.h>
#include <asm/types.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
#ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
static inline
__wsum csum_and_copy_from_user (const void __user *src, void *dst,
int len, __wsum sum, int *err_ptr)
{
if (access_ok(VERIFY_READ, src, len))
return csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
if (len)
*err_ptr = -EFAULT;
return sum;
}
#endif
#ifndef HAVE_CSUM_COPY_USER
static __inline__ __wsum csum_and_copy_to_user
(const void *src, void __user *dst, int len, __wsum sum, int *err_ptr)
{
sum = csum_partial(src, len, sum);
if (access_ok(VERIFY_WRITE, dst, len)) {
if (copy_to_user(dst, src, len) == 0)
return sum;
}
if (len)
*err_ptr = -EFAULT;
return (__force __wsum)-1; /* invalid checksum */
}
#endif
static inline __wsum csum_add(__wsum csum, __wsum addend)
{
u32 res = (__force u32)csum;
res += (__force u32)addend;
return (__force __wsum)(res + (res < (__force u32)addend));
}
static inline __wsum csum_sub(__wsum csum, __wsum addend)
{
return csum_add(csum, ~addend);
}
static inline __wsum
csum_block_add(__wsum csum, __wsum csum2, int offset)
{
u32 sum = (__force u32)csum2;
if (offset&1)
sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF);
return csum_add(csum, (__force __wsum)sum);
}
static inline __wsum
csum_block_sub(__wsum csum, __wsum csum2, int offset)
{
u32 sum = (__force u32)csum2;
if (offset&1)
sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF);
return csum_sub(csum, (__force __wsum)sum);
}
static inline __wsum csum_unfold(__sum16 n)
{
return (__force __wsum)n;
}
#define CSUM_MANGLED_0 ((__force __sum16)0xffff)
#endif

254
include/net/cipso_ipv4.h Normal file
View File

@@ -0,0 +1,254 @@
/*
* CIPSO - Commercial IP Security Option
*
* This is an implementation of the CIPSO 2.2 protocol as specified in
* draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
* FIPS-188, copies of both documents can be found in the Documentation
* directory. While CIPSO never became a full IETF RFC standard many vendors
* have chosen to adopt the protocol and over the years it has become a
* de-facto standard for labeled networking.
*
* Author: Paul Moore <paul.moore@hp.com>
*
*/
/*
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _CIPSO_IPV4_H
#define _CIPSO_IPV4_H
#include <linux/types.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <net/netlabel.h>
/* known doi values */
#define CIPSO_V4_DOI_UNKNOWN 0x00000000
/* tag types */
#define CIPSO_V4_TAG_INVALID 0
#define CIPSO_V4_TAG_RBITMAP 1
#define CIPSO_V4_TAG_ENUM 2
#define CIPSO_V4_TAG_RANGE 5
#define CIPSO_V4_TAG_PBITMAP 6
#define CIPSO_V4_TAG_FREEFORM 7
/* doi mapping types */
#define CIPSO_V4_MAP_UNKNOWN 0
#define CIPSO_V4_MAP_STD 1
#define CIPSO_V4_MAP_PASS 2
/* limits */
#define CIPSO_V4_MAX_REM_LVLS 255
#define CIPSO_V4_INV_LVL 0x80000000
#define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1)
#define CIPSO_V4_MAX_REM_CATS 65534
#define CIPSO_V4_INV_CAT 0x80000000
#define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1)
/*
* CIPSO DOI definitions
*/
/* DOI definition struct */
#define CIPSO_V4_TAG_MAXCNT 5
struct cipso_v4_doi {
u32 doi;
u32 type;
union {
struct cipso_v4_std_map_tbl *std;
} map;
u8 tags[CIPSO_V4_TAG_MAXCNT];
u32 valid;
struct list_head list;
struct rcu_head rcu;
struct list_head dom_list;
};
/* Standard CIPSO mapping table */
/* NOTE: the highest order bit (i.e. 0x80000000) is an 'invalid' flag, if the
* bit is set then consider that value as unspecified, meaning the
* mapping for that particular level/category is invalid */
struct cipso_v4_std_map_tbl {
struct {
u32 *cipso;
u32 *local;
u32 cipso_size;
u32 local_size;
} lvl;
struct {
u32 *cipso;
u32 *local;
u32 cipso_size;
u32 local_size;
} cat;
};
/*
* Sysctl Variables
*/
#ifdef CONFIG_NETLABEL
extern int cipso_v4_cache_enabled;
extern int cipso_v4_cache_bucketsize;
extern int cipso_v4_rbm_optfmt;
extern int cipso_v4_rbm_strictvalid;
#endif
/*
* Helper Functions
*/
#define CIPSO_V4_OPTEXIST(x) (IPCB(x)->opt.cipso != 0)
#define CIPSO_V4_OPTPTR(x) ((x)->nh.raw + IPCB(x)->opt.cipso)
/*
* DOI List Functions
*/
#ifdef CONFIG_NETLABEL
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
int cipso_v4_doi_remove(u32 doi,
struct netlbl_audit *audit_info,
void (*callback) (struct rcu_head * head));
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
int cipso_v4_doi_walk(u32 *skip_cnt,
int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
void *cb_arg);
int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);
int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
const char *domain);
#else
static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
{
return -ENOSYS;
}
static inline int cipso_v4_doi_remove(u32 doi,
struct netlbl_audit *audit_info,
void (*callback) (struct rcu_head * head))
{
return 0;
}
static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
{
return NULL;
}
static inline int cipso_v4_doi_walk(u32 *skip_cnt,
int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
void *cb_arg)
{
return 0;
}
static inline int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def,
const char *domain)
{
return -ENOSYS;
}
static inline int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
const char *domain)
{
return 0;
}
#endif /* CONFIG_NETLABEL */
/*
* Label Mapping Cache Functions
*/
#ifdef CONFIG_NETLABEL
void cipso_v4_cache_invalidate(void);
int cipso_v4_cache_add(const struct sk_buff *skb,
const struct netlbl_lsm_secattr *secattr);
#else
static inline void cipso_v4_cache_invalidate(void)
{
return;
}
static inline int cipso_v4_cache_add(const struct sk_buff *skb,
const struct netlbl_lsm_secattr *secattr)
{
return 0;
}
#endif /* CONFIG_NETLABEL */
/*
* Protocol Handling Functions
*/
#ifdef CONFIG_NETLABEL
void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
int cipso_v4_socket_setattr(const struct socket *sock,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr);
int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
int cipso_v4_socket_getattr(const struct socket *sock,
struct netlbl_lsm_secattr *secattr);
int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
struct netlbl_lsm_secattr *secattr);
int cipso_v4_validate(unsigned char **option);
#else
static inline void cipso_v4_error(struct sk_buff *skb,
int error,
u32 gateway)
{
return;
}
static inline int cipso_v4_socket_setattr(const struct socket *sock,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}
static inline int cipso_v4_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}
static inline int cipso_v4_socket_getattr(const struct socket *sock,
struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}
static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}
static inline int cipso_v4_validate(unsigned char **option)
{
return -ENOSYS;
}
#endif /* CONFIG_NETLABEL */
#endif /* _CIPSO_IPV4_H */

42
include/net/compat.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef NET_COMPAT_H
#define NET_COMPAT_H
struct sock;
#if defined(CONFIG_COMPAT)
#include <linux/compat.h>
struct compat_msghdr {
compat_uptr_t msg_name; /* void * */
compat_int_t msg_namelen;
compat_uptr_t msg_iov; /* struct compat_iovec * */
compat_size_t msg_iovlen;
compat_uptr_t msg_control; /* void * */
compat_size_t msg_controllen;
compat_uint_t msg_flags;
};
struct compat_cmsghdr {
compat_size_t cmsg_len;
compat_int_t cmsg_level;
compat_int_t cmsg_type;
};
extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
#else /* defined(CONFIG_COMPAT) */
#define compat_msghdr msghdr /* to avoid compiler warnings */
#endif /* defined(CONFIG_COMPAT) */
extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *);
extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int);
extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned);
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);
extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
#endif /* NET_COMPAT_H */

18
include/net/datalink.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _NET_INET_DATALINK_H_
#define _NET_INET_DATALINK_H_
struct datalink_proto {
unsigned char type[8];
struct llc_sap *sap;
unsigned short header_length;
int (*rcvfunc)(struct sk_buff *, struct net_device *,
struct packet_type *, struct net_device *);
int (*request)(struct datalink_proto *, struct sk_buff *,
unsigned char *);
struct list_head node;
};
#endif

235
include/net/dn.h Normal file
View File

@@ -0,0 +1,235 @@
#ifndef _NET_DN_H
#define _NET_DN_H
#include <linux/dn.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <asm/byteorder.h>
#define dn_ntohs(x) le16_to_cpu(x)
#define dn_htons(x) cpu_to_le16(x)
struct dn_scp /* Session Control Port */
{
unsigned char state;
#define DN_O 1 /* Open */
#define DN_CR 2 /* Connect Receive */
#define DN_DR 3 /* Disconnect Reject */
#define DN_DRC 4 /* Discon. Rej. Complete*/
#define DN_CC 5 /* Connect Confirm */
#define DN_CI 6 /* Connect Initiate */
#define DN_NR 7 /* No resources */
#define DN_NC 8 /* No communication */
#define DN_CD 9 /* Connect Delivery */
#define DN_RJ 10 /* Rejected */
#define DN_RUN 11 /* Running */
#define DN_DI 12 /* Disconnect Initiate */
#define DN_DIC 13 /* Disconnect Complete */
#define DN_DN 14 /* Disconnect Notificat */
#define DN_CL 15 /* Closed */
#define DN_CN 16 /* Closed Notification */
__le16 addrloc;
__le16 addrrem;
__u16 numdat;
__u16 numoth;
__u16 numoth_rcv;
__u16 numdat_rcv;
__u16 ackxmt_dat;
__u16 ackxmt_oth;
__u16 ackrcv_dat;
__u16 ackrcv_oth;
__u8 flowrem_sw;
__u8 flowloc_sw;
#define DN_SEND 2
#define DN_DONTSEND 1
#define DN_NOCHANGE 0
__u16 flowrem_dat;
__u16 flowrem_oth;
__u16 flowloc_dat;
__u16 flowloc_oth;
__u8 services_rem;
__u8 services_loc;
__u8 info_rem;
__u8 info_loc;
__u16 segsize_rem;
__u16 segsize_loc;
__u8 nonagle;
__u8 multi_ireq;
__u8 accept_mode;
unsigned long seg_total; /* Running total of current segment */
struct optdata_dn conndata_in;
struct optdata_dn conndata_out;
struct optdata_dn discdata_in;
struct optdata_dn discdata_out;
struct accessdata_dn accessdata;
struct sockaddr_dn addr; /* Local address */
struct sockaddr_dn peer; /* Remote address */
/*
* In this case the RTT estimation is not specified in the
* docs, nor is any back off algorithm. Here we follow well
* known tcp algorithms with a few small variations.
*
* snd_window: Max number of packets we send before we wait for
* an ack to come back. This will become part of a
* more complicated scheme when we support flow
* control.
*
* nsp_srtt: Round-Trip-Time (x8) in jiffies. This is a rolling
* average.
* nsp_rttvar: Round-Trip-Time-Varience (x4) in jiffies. This is the
* varience of the smoothed average (but calculated in
* a simpler way than for normal statistical varience
* calculations).
*
* nsp_rxtshift: Backoff counter. Value is zero normally, each time
* a packet is lost is increases by one until an ack
* is received. Its used to index an array of backoff
* multipliers.
*/
#define NSP_MIN_WINDOW 1
#define NSP_MAX_WINDOW (0x07fe)
unsigned long max_window;
unsigned long snd_window;
#define NSP_INITIAL_SRTT (HZ)
unsigned long nsp_srtt;
#define NSP_INITIAL_RTTVAR (HZ*3)
unsigned long nsp_rttvar;
#define NSP_MAXRXTSHIFT 12
unsigned long nsp_rxtshift;
/*
* Output queues, one for data, one for otherdata/linkservice
*/
struct sk_buff_head data_xmit_queue;
struct sk_buff_head other_xmit_queue;
/*
* Input queue for other data
*/
struct sk_buff_head other_receive_queue;
int other_report;
/*
* Stuff to do with the slow timer
*/
unsigned long stamp; /* time of last transmit */
unsigned long persist;
int (*persist_fxn)(struct sock *sk);
unsigned long keepalive;
void (*keepalive_fxn)(struct sock *sk);
/*
* This stuff is for the fast timer for delayed acks
*/
struct timer_list delack_timer;
int delack_pending;
void (*delack_fxn)(struct sock *sk);
};
static inline struct dn_scp *DN_SK(struct sock *sk)
{
return (struct dn_scp *)(sk + 1);
}
/*
* src,dst : Source and Destination DECnet addresses
* hops : Number of hops through the network
* dst_port, src_port : NSP port numbers
* services, info : Useful data extracted from conninit messages
* rt_flags : Routing flags byte
* nsp_flags : NSP layer flags byte
* segsize : Size of segment
* segnum : Number, for data, otherdata and linkservice
* xmit_count : Number of times we've transmitted this skb
* stamp : Time stamp of most recent transmission, used in RTT calculations
* iif: Input interface number
*
* As a general policy, this structure keeps all addresses in network
* byte order, and all else in host byte order. Thus dst, src, dst_port
* and src_port are in network order. All else is in host order.
*
*/
#define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb)
struct dn_skb_cb {
__le16 dst;
__le16 src;
__u16 hops;
__le16 dst_port;
__le16 src_port;
__u8 services;
__u8 info;
__u8 rt_flags;
__u8 nsp_flags;
__u16 segsize;
__u16 segnum;
__u16 xmit_count;
unsigned long stamp;
int iif;
};
static inline __le16 dn_eth2dn(unsigned char *ethaddr)
{
return dn_htons(ethaddr[4] | (ethaddr[5] << 8));
}
static inline __le16 dn_saddr2dn(struct sockaddr_dn *saddr)
{
return *(__le16 *)saddr->sdn_nodeaddr;
}
static inline void dn_dn2eth(unsigned char *ethaddr, __le16 addr)
{
__u16 a = dn_ntohs(addr);
ethaddr[0] = 0xAA;
ethaddr[1] = 0x00;
ethaddr[2] = 0x04;
ethaddr[3] = 0x00;
ethaddr[4] = (__u8)(a & 0xff);
ethaddr[5] = (__u8)(a >> 8);
}
static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp)
{
fl->uli_u.dnports.sport = scp->addrloc;
fl->uli_u.dnports.dport = scp->addrrem;
}
extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu);
#define DN_MENUVER_ACC 0x01
#define DN_MENUVER_USR 0x02
#define DN_MENUVER_PRX 0x04
#define DN_MENUVER_UIC 0x08
extern struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr);
extern struct sock *dn_find_by_skb(struct sk_buff *skb);
#define DN_ASCBUF_LEN 9
extern char *dn_addr2asc(__u16, char *);
extern int dn_destroy_timer(struct sock *sk);
extern int dn_sockaddr2username(struct sockaddr_dn *addr, unsigned char *buf, unsigned char type);
extern int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *addr, unsigned char *type);
extern void dn_start_slow_timer(struct sock *sk);
extern void dn_stop_slow_timer(struct sock *sk);
extern __le16 decnet_address;
extern int decnet_debug_level;
extern int decnet_time_wait;
extern int decnet_dn_count;
extern int decnet_di_count;
extern int decnet_dr_count;
extern int decnet_no_fc_max_cwnd;
extern int sysctl_decnet_mem[3];
extern int sysctl_decnet_wmem[3];
extern int sysctl_decnet_rmem[3];
#endif /* _NET_DN_H */

194
include/net/dn_dev.h Normal file
View File

@@ -0,0 +1,194 @@
#ifndef _NET_DN_DEV_H
#define _NET_DN_DEV_H
struct dn_dev;
struct dn_ifaddr {
struct dn_ifaddr *ifa_next;
struct dn_dev *ifa_dev;
__le16 ifa_local;
__le16 ifa_address;
__u8 ifa_flags;
__u8 ifa_scope;
char ifa_label[IFNAMSIZ];
};
#define DN_DEV_S_RU 0 /* Run - working normally */
#define DN_DEV_S_CR 1 /* Circuit Rejected */
#define DN_DEV_S_DS 2 /* Data Link Start */
#define DN_DEV_S_RI 3 /* Routing Layer Initialize */
#define DN_DEV_S_RV 4 /* Routing Layer Verify */
#define DN_DEV_S_RC 5 /* Routing Layer Complete */
#define DN_DEV_S_OF 6 /* Off */
#define DN_DEV_S_HA 7 /* Halt */
/*
* The dn_dev_parms structure contains the set of parameters
* for each device (hence inclusion in the dn_dev structure)
* and an array is used to store the default types of supported
* device (in dn_dev.c).
*
* The type field matches the ARPHRD_ constants and is used in
* searching the list for supported devices when new devices
* come up.
*
* The mode field is used to find out if a device is broadcast,
* multipoint, or pointopoint. Please note that DECnet thinks
* different ways about devices to the rest of the kernel
* so the normal IFF_xxx flags are invalid here. For devices
* which can be any combination of the previously mentioned
* attributes, you can set this on a per device basis by
* installing an up() routine.
*
* The device state field, defines the initial state in which the
* device will come up. In the dn_dev structure, it is the actual
* state.
*
* Things have changed here. I've killed timer1 since it's a user space
* issue for a user space routing deamon to sort out. The kernel does
* not need to be bothered with it.
*
* Timers:
* t2 - Rate limit timer, min time between routing and hello messages
* t3 - Hello timer, send hello messages when it expires
*
* Callbacks:
* up() - Called to initialize device, return value can veto use of
* device with DECnet.
* down() - Called to turn device off when it goes down
* timer3() - Called once for each ifaddr when timer 3 goes off
*
* sysctl - Hook for sysctl things
*
*/
struct dn_dev_parms {
int type; /* ARPHRD_xxx */
int mode; /* Broadcast, Unicast, Mulitpoint */
#define DN_DEV_BCAST 1
#define DN_DEV_UCAST 2
#define DN_DEV_MPOINT 4
int state; /* Initial state */
int forwarding; /* 0=EndNode, 1=L1Router, 2=L2Router */
unsigned long t2; /* Default value of t2 */
unsigned long t3; /* Default value of t3 */
int priority; /* Priority to be a router */
char *name; /* Name for sysctl */
int ctl_name; /* Index for sysctl */
int (*up)(struct net_device *);
void (*down)(struct net_device *);
void (*timer3)(struct net_device *, struct dn_ifaddr *ifa);
void *sysctl;
};
struct dn_dev {
struct dn_ifaddr *ifa_list;
struct net_device *dev;
struct dn_dev_parms parms;
char use_long;
struct timer_list timer;
unsigned long t3;
struct neigh_parms *neigh_parms;
__u8 addr[ETH_ALEN];
struct neighbour *router; /* Default router on circuit */
struct neighbour *peer; /* Peer on pointopoint links */
unsigned long uptime; /* Time device went up in jiffies */
};
struct dn_short_packet
{
__u8 msgflg;
__le16 dstnode;
__le16 srcnode;
__u8 forward;
} __attribute__((packed));
struct dn_long_packet
{
__u8 msgflg;
__u8 d_area;
__u8 d_subarea;
__u8 d_id[6];
__u8 s_area;
__u8 s_subarea;
__u8 s_id[6];
__u8 nl2;
__u8 visit_ct;
__u8 s_class;
__u8 pt;
} __attribute__((packed));
/*------------------------- DRP - Routing messages ---------------------*/
struct endnode_hello_message
{
__u8 msgflg;
__u8 tiver[3];
__u8 id[6];
__u8 iinfo;
__le16 blksize;
__u8 area;
__u8 seed[8];
__u8 neighbor[6];
__le16 timer;
__u8 mpd;
__u8 datalen;
__u8 data[2];
} __attribute__((packed));
struct rtnode_hello_message
{
__u8 msgflg;
__u8 tiver[3];
__u8 id[6];
__u8 iinfo;
__le16 blksize;
__u8 priority;
__u8 area;
__le16 timer;
__u8 mpd;
} __attribute__((packed));
extern void dn_dev_init(void);
extern void dn_dev_cleanup(void);
extern int dn_dev_ioctl(unsigned int cmd, void __user *arg);
extern void dn_dev_devices_off(void);
extern void dn_dev_devices_on(void);
extern void dn_dev_init_pkt(struct sk_buff *skb);
extern void dn_dev_veri_pkt(struct sk_buff *skb);
extern void dn_dev_hello(struct sk_buff *skb);
extern void dn_dev_up(struct net_device *);
extern void dn_dev_down(struct net_device *);
extern int dn_dev_set_default(struct net_device *dev, int force);
extern struct net_device *dn_dev_get_default(void);
extern int dn_dev_bind_default(__le16 *addr);
extern int register_dnaddr_notifier(struct notifier_block *nb);
extern int unregister_dnaddr_notifier(struct notifier_block *nb);
static inline int dn_dev_islocal(struct net_device *dev, __le16 addr)
{
struct dn_dev *dn_db = dev->dn_ptr;
struct dn_ifaddr *ifa;
if (dn_db == NULL) {
printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n");
return 0;
}
for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next)
if ((addr ^ ifa->ifa_local) == 0)
return 1;
return 0;
}
#endif /* _NET_DN_DEV_H */

198
include/net/dn_fib.h Normal file
View File

@@ -0,0 +1,198 @@
#ifndef _NET_DN_FIB_H
#define _NET_DN_FIB_H
/* WARNING: The ordering of these elements must match ordering
* of RTA_* rtnetlink attribute numbers.
*/
struct dn_kern_rta
{
void *rta_dst;
void *rta_src;
int *rta_iif;
int *rta_oif;
void *rta_gw;
u32 *rta_priority;
void *rta_prefsrc;
struct rtattr *rta_mx;
struct rtattr *rta_mp;
unsigned char *rta_protoinfo;
u32 *rta_flow;
struct rta_cacheinfo *rta_ci;
struct rta_session *rta_sess;
};
struct dn_fib_res {
struct fib_rule *r;
struct dn_fib_info *fi;
unsigned char prefixlen;
unsigned char nh_sel;
unsigned char type;
unsigned char scope;
};
struct dn_fib_nh {
struct net_device *nh_dev;
unsigned nh_flags;
unsigned char nh_scope;
int nh_weight;
int nh_power;
int nh_oif;
__le16 nh_gw;
};
struct dn_fib_info {
struct dn_fib_info *fib_next;
struct dn_fib_info *fib_prev;
int fib_treeref;
atomic_t fib_clntref;
int fib_dead;
unsigned fib_flags;
int fib_protocol;
__le16 fib_prefsrc;
__u32 fib_priority;
__u32 fib_metrics[RTAX_MAX];
#define dn_fib_mtu fib_metrics[RTAX_MTU-1]
#define dn_fib_window fib_metrics[RTAX_WINDOW-1]
#define dn_fib_rtt fib_metrics[RTAX_RTT-1]
#define dn_fib_advmss fib_metrics[RTAX_ADVMSS-1]
int fib_nhs;
int fib_power;
struct dn_fib_nh fib_nh[0];
#define dn_fib_dev fib_nh[0].nh_dev
};
#define DN_FIB_RES_RESET(res) ((res).nh_sel = 0)
#define DN_FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
#define DN_FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __dn_fib_res_prefsrc(&res))
#define DN_FIB_RES_GW(res) (DN_FIB_RES_NH(res).nh_gw)
#define DN_FIB_RES_DEV(res) (DN_FIB_RES_NH(res).nh_dev)
#define DN_FIB_RES_OIF(res) (DN_FIB_RES_NH(res).nh_oif)
typedef struct {
__le16 datum;
} dn_fib_key_t;
typedef struct {
__le16 datum;
} dn_fib_hash_t;
typedef struct {
__u16 datum;
} dn_fib_idx_t;
struct dn_fib_node {
struct dn_fib_node *fn_next;
struct dn_fib_info *fn_info;
#define DN_FIB_INFO(f) ((f)->fn_info)
dn_fib_key_t fn_key;
u8 fn_type;
u8 fn_scope;
u8 fn_state;
};
struct dn_fib_table {
struct hlist_node hlist;
u32 n;
int (*insert)(struct dn_fib_table *t, struct rtmsg *r,
struct dn_kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*delete)(struct dn_fib_table *t, struct rtmsg *r,
struct dn_kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*lookup)(struct dn_fib_table *t, const struct flowi *fl,
struct dn_fib_res *res);
int (*flush)(struct dn_fib_table *t);
int (*dump)(struct dn_fib_table *t, struct sk_buff *skb, struct netlink_callback *cb);
unsigned char data[0];
};
#ifdef CONFIG_DECNET_ROUTER
/*
* dn_fib.c
*/
extern void dn_fib_init(void);
extern void dn_fib_cleanup(void);
extern int dn_fib_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg);
extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r,
struct dn_kern_rta *rta,
const struct nlmsghdr *nlh, int *errp);
extern int dn_fib_semantic_match(int type, struct dn_fib_info *fi,
const struct flowi *fl,
struct dn_fib_res *res);
extern void dn_fib_release_info(struct dn_fib_info *fi);
extern __le16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type);
extern void dn_fib_flush(void);
extern void dn_fib_select_multipath(const struct flowi *fl,
struct dn_fib_res *res);
/*
* dn_tables.c
*/
extern struct dn_fib_table *dn_fib_get_table(u32 n, int creat);
extern struct dn_fib_table *dn_fib_empty_table(void);
extern void dn_fib_table_init(void);
extern void dn_fib_table_cleanup(void);
/*
* dn_rules.c
*/
extern void dn_fib_rules_init(void);
extern void dn_fib_rules_cleanup(void);
extern unsigned dnet_addr_type(__le16 addr);
extern int dn_fib_lookup(struct flowi *fl, struct dn_fib_res *res);
/*
* rtnetlink interface
*/
extern int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb);
extern int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern int dn_fib_rtm_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb);
extern void dn_fib_free_info(struct dn_fib_info *fi);
static inline void dn_fib_info_put(struct dn_fib_info *fi)
{
if (atomic_dec_and_test(&fi->fib_clntref))
dn_fib_free_info(fi);
}
static inline void dn_fib_res_put(struct dn_fib_res *res)
{
if (res->fi)
dn_fib_info_put(res->fi);
if (res->r)
fib_rule_put(res->r);
}
#else /* Endnode */
#define dn_fib_init() do { } while(0)
#define dn_fib_cleanup() do { } while(0)
#define dn_fib_lookup(fl, res) (-ESRCH)
#define dn_fib_info_put(fi) do { } while(0)
#define dn_fib_select_multipath(fl, res) do { } while(0)
#define dn_fib_rules_policy(saddr,res,flags) (0)
#define dn_fib_res_put(res) do { } while(0)
#endif /* CONFIG_DECNET_ROUTER */
static inline __le16 dnet_make_mask(int n)
{
if (n)
return dn_htons(~((1<<(16-n))-1));
return 0;
}
#endif /* _NET_DN_FIB_H */

28
include/net/dn_neigh.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef _NET_DN_NEIGH_H
#define _NET_DN_NEIGH_H
/*
* The position of the first two fields of
* this structure are critical - SJW
*/
struct dn_neigh {
struct neighbour n;
__le16 addr;
unsigned long flags;
#define DN_NDFLAG_R1 0x0001 /* Router L1 */
#define DN_NDFLAG_R2 0x0002 /* Router L2 */
#define DN_NDFLAG_P3 0x0004 /* Phase III Node */
unsigned long blksize;
__u8 priority;
};
extern void dn_neigh_init(void);
extern void dn_neigh_cleanup(void);
extern int dn_neigh_router_hello(struct sk_buff *skb);
extern int dn_neigh_endnode_hello(struct sk_buff *skb);
extern void dn_neigh_pointopoint_hello(struct sk_buff *skb);
extern int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n);
extern struct neigh_table dn_neigh_table;
#endif /* _NET_DN_NEIGH_H */

209
include/net/dn_nsp.h Normal file
View File

@@ -0,0 +1,209 @@
#ifndef _NET_DN_NSP_H
#define _NET_DN_NSP_H
/******************************************************************************
(c) 1995-1998 E.M. Serrat emserrat@geocities.com
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
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*******************************************************************************/
/* dn_nsp.c functions prototyping */
extern void dn_nsp_send_data_ack(struct sock *sk);
extern void dn_nsp_send_oth_ack(struct sock *sk);
extern void dn_nsp_delayed_ack(struct sock *sk);
extern void dn_send_conn_ack(struct sock *sk);
extern void dn_send_conn_conf(struct sock *sk, gfp_t gfp);
extern void dn_nsp_send_disc(struct sock *sk, unsigned char type,
unsigned short reason, gfp_t gfp);
extern void dn_nsp_return_disc(struct sk_buff *skb, unsigned char type,
unsigned short reason);
extern void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval);
extern void dn_nsp_send_conninit(struct sock *sk, unsigned char flags);
extern void dn_nsp_output(struct sock *sk);
extern int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum);
extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, gfp_t gfp, int oob);
extern unsigned long dn_nsp_persist(struct sock *sk);
extern int dn_nsp_xmit_timeout(struct sock *sk);
extern int dn_nsp_rx(struct sk_buff *);
extern int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err);
#define NSP_REASON_OK 0 /* No error */
#define NSP_REASON_NR 1 /* No resources */
#define NSP_REASON_UN 2 /* Unrecognised node name */
#define NSP_REASON_SD 3 /* Node shutting down */
#define NSP_REASON_ID 4 /* Invalid destination end user */
#define NSP_REASON_ER 5 /* End user lacks resources */
#define NSP_REASON_OB 6 /* Object too busy */
#define NSP_REASON_US 7 /* Unspecified error */
#define NSP_REASON_TP 8 /* Third-Party abort */
#define NSP_REASON_EA 9 /* End user has aborted the link */
#define NSP_REASON_IF 10 /* Invalid node name format */
#define NSP_REASON_LS 11 /* Local node shutdown */
#define NSP_REASON_LL 32 /* Node lacks logical-link resources */
#define NSP_REASON_LE 33 /* End user lacks logical-link resources */
#define NSP_REASON_UR 34 /* Unacceptable RQSTRID or PASSWORD field */
#define NSP_REASON_UA 36 /* Unacceptable ACCOUNT field */
#define NSP_REASON_TM 38 /* End user timed out logical link */
#define NSP_REASON_NU 39 /* Node unreachable */
#define NSP_REASON_NL 41 /* No-link message */
#define NSP_REASON_DC 42 /* Disconnect confirm */
#define NSP_REASON_IO 43 /* Image data field overflow */
#define NSP_DISCINIT 0x38
#define NSP_DISCCONF 0x48
/*------------------------- NSP - messages ------------------------------*/
/* Data Messages */
/*---------------*/
/* Data Messages (data segment/interrupt/link service) */
struct nsp_data_seg_msg
{
__u8 msgflg;
__le16 dstaddr;
__le16 srcaddr;
} __attribute__((packed));
struct nsp_data_opt_msg
{
__le16 acknum;
__le16 segnum;
__le16 lsflgs;
} __attribute__((packed));
struct nsp_data_opt_msg1
{
__le16 acknum;
__le16 segnum;
} __attribute__((packed));
/* Acknowledgment Message (data/other data) */
struct nsp_data_ack_msg
{
__u8 msgflg;
__le16 dstaddr;
__le16 srcaddr;
__le16 acknum;
} __attribute__((packed));
/* Connect Acknowledgment Message */
struct nsp_conn_ack_msg
{
__u8 msgflg;
__le16 dstaddr;
} __attribute__((packed));
/* Connect Initiate/Retransmit Initiate/Connect Confirm */
struct nsp_conn_init_msg
{
__u8 msgflg;
#define NSP_CI 0x18 /* Connect Initiate */
#define NSP_RCI 0x68 /* Retrans. Conn Init */
__le16 dstaddr;
__le16 srcaddr;
__u8 services;
#define NSP_FC_NONE 0x00 /* Flow Control None */
#define NSP_FC_SRC 0x04 /* Seg Req. Count */
#define NSP_FC_SCMC 0x08 /* Sess. Control Mess */
#define NSP_FC_MASK 0x0c /* FC type mask */
__u8 info;
__le16 segsize;
} __attribute__((packed));
/* Disconnect Initiate/Disconnect Confirm */
struct nsp_disconn_init_msg
{
__u8 msgflg;
__le16 dstaddr;
__le16 srcaddr;
__le16 reason;
} __attribute__((packed));
struct srcobj_fmt
{
__u8 format;
__u8 task;
__le16 grpcode;
__le16 usrcode;
__u8 dlen;
} __attribute__((packed));
/*
* A collection of functions for manipulating the sequence
* numbers used in NSP. Similar in operation to the functions
* of the same name in TCP.
*/
static __inline__ int dn_before(__u16 seq1, __u16 seq2)
{
seq1 &= 0x0fff;
seq2 &= 0x0fff;
return (int)((seq1 - seq2) & 0x0fff) > 2048;
}
static __inline__ int dn_after(__u16 seq1, __u16 seq2)
{
seq1 &= 0x0fff;
seq2 &= 0x0fff;
return (int)((seq2 - seq1) & 0x0fff) > 2048;
}
static __inline__ int dn_equal(__u16 seq1, __u16 seq2)
{
return ((seq1 ^ seq2) & 0x0fff) == 0;
}
static __inline__ int dn_before_or_equal(__u16 seq1, __u16 seq2)
{
return (dn_before(seq1, seq2) || dn_equal(seq1, seq2));
}
static __inline__ void seq_add(__u16 *seq, __u16 off)
{
(*seq) += off;
(*seq) &= 0x0fff;
}
static __inline__ int seq_next(__u16 seq1, __u16 seq2)
{
return dn_equal(seq1 + 1, seq2);
}
/*
* Can we delay the ack ?
*/
static __inline__ int sendack(__u16 seq)
{
return (int)((seq & 0x1000) ? 0 : 1);
}
/*
* Is socket congested ?
*/
static __inline__ int dn_congested(struct sock *sk)
{
return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
}
#define DN_MAX_NSP_DATA_HEADER (11)
#endif /* _NET_DN_NSP_H */

111
include/net/dn_route.h Normal file
View File

@@ -0,0 +1,111 @@
#ifndef _NET_DN_ROUTE_H
#define _NET_DN_ROUTE_H
/******************************************************************************
(c) 1995-1998 E.M. Serrat emserrat@geocities.com
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
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*******************************************************************************/
extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri);
extern int dn_route_output_sock(struct dst_entry **pprt, struct flowi *, struct sock *sk, int flags);
extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
extern int dn_cache_getroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern void dn_rt_cache_flush(int delay);
/* Masks for flags field */
#define DN_RT_F_PID 0x07 /* Mask for packet type */
#define DN_RT_F_PF 0x80 /* Padding Follows */
#define DN_RT_F_VER 0x40 /* Version =0 discard packet if ==1 */
#define DN_RT_F_IE 0x20 /* Intra Ethernet, Reserved in short pkt */
#define DN_RT_F_RTS 0x10 /* Packet is being returned to sender */
#define DN_RT_F_RQR 0x08 /* Return packet to sender upon non-delivery */
/* Mask for types of routing packets */
#define DN_RT_PKT_MSK 0x06
/* Types of routing packets */
#define DN_RT_PKT_SHORT 0x02 /* Short routing packet */
#define DN_RT_PKT_LONG 0x06 /* Long routing packet */
/* Mask for control/routing selection */
#define DN_RT_PKT_CNTL 0x01 /* Set to 1 if a control packet */
/* Types of control packets */
#define DN_RT_CNTL_MSK 0x0f /* Mask for control packets */
#define DN_RT_PKT_INIT 0x01 /* Initialisation packet */
#define DN_RT_PKT_VERI 0x03 /* Verification Message */
#define DN_RT_PKT_HELO 0x05 /* Hello and Test Message */
#define DN_RT_PKT_L1RT 0x07 /* Level 1 Routing Message */
#define DN_RT_PKT_L2RT 0x09 /* Level 2 Routing Message */
#define DN_RT_PKT_ERTH 0x0b /* Ethernet Router Hello */
#define DN_RT_PKT_EEDH 0x0d /* Ethernet EndNode Hello */
/* Values for info field in hello message */
#define DN_RT_INFO_TYPE 0x03 /* Type mask */
#define DN_RT_INFO_L1RT 0x02 /* L1 Router */
#define DN_RT_INFO_L2RT 0x01 /* L2 Router */
#define DN_RT_INFO_ENDN 0x03 /* EndNode */
#define DN_RT_INFO_VERI 0x04 /* Verification Reqd. */
#define DN_RT_INFO_RJCT 0x08 /* Reject Flag, Reserved */
#define DN_RT_INFO_VFLD 0x10 /* Verification Failed, Reserved */
#define DN_RT_INFO_NOML 0x20 /* No Multicast traffic accepted */
#define DN_RT_INFO_BLKR 0x40 /* Blocking Requested */
/*
* The fl structure is what we used to look up the route.
* The rt_saddr & rt_daddr entries are the same as key.saddr & key.daddr
* except for local input routes, where the rt_saddr = fl.fld_dst and
* rt_daddr = fl.fld_src to allow the route to be used for returning
* packets to the originating host.
*/
struct dn_route {
union {
struct dst_entry dst;
} u;
struct flowi fl;
__le16 rt_saddr;
__le16 rt_daddr;
__le16 rt_gateway;
__le16 rt_local_src; /* Source used for forwarding packets */
__le16 rt_src_map;
__le16 rt_dst_map;
unsigned rt_flags;
unsigned rt_type;
};
extern void dn_route_init(void);
extern void dn_route_cleanup(void);
#include <net/sock.h>
#include <linux/if_arp.h>
static inline void dn_rt_send(struct sk_buff *skb)
{
dev_queue_xmit(skb);
}
static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst, char *src)
{
struct net_device *dev = skb->dev;
if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
dst = NULL;
if (!dev->hard_header || (dev->hard_header(skb, dev, ETH_P_DNA_RT,
dst, src, skb->len) >= 0))
dn_rt_send(skb);
else
kfree_skb(skb);
}
#endif /* _NET_DN_ROUTE_H */

54
include/net/dsfield.h Normal file
View File

@@ -0,0 +1,54 @@
/* include/net/dsfield.h - Manipulation of the Differentiated Services field */
/* Written 1998-2000 by Werner Almesberger, EPFL ICA */
#ifndef __NET_DSFIELD_H
#define __NET_DSFIELD_H
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <asm/byteorder.h>
static inline __u8 ipv4_get_dsfield(struct iphdr *iph)
{
return iph->tos;
}
static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h)
{
return ntohs(*(__be16 *) ipv6h) >> 4;
}
static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask,
__u8 value)
{
__u32 check = ntohs((__force __be16)iph->check);
__u8 dsfield;
dsfield = (iph->tos & mask) | value;
check += iph->tos;
if ((check+1) >> 16) check = (check+1) & 0xffff;
check -= dsfield;
check += check >> 16; /* adjust carry */
iph->check = (__force __sum16)htons(check);
iph->tos = dsfield;
}
static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask,
__u8 value)
{
__u16 tmp;
tmp = ntohs(*(__be16 *) ipv6h);
tmp = (tmp & ((mask << 4) | 0xf00f)) | (value << 4);
*(__be16 *) ipv6h = htons(tmp);
}
#endif

274
include/net/dst.h Normal file
View File

@@ -0,0 +1,274 @@
/*
* net/dst.h Protocol independent destination cache definitions.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
*/
#ifndef _NET_DST_H
#define _NET_DST_H
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/rcupdate.h>
#include <linux/jiffies.h>
#include <net/neighbour.h>
#include <asm/processor.h>
/*
* 0 - no debugging messages
* 1 - rare events and bugs (default)
* 2 - trace mode.
*/
#define RT_CACHE_DEBUG 0
#define DST_GC_MIN (HZ/10)
#define DST_GC_INC (HZ/2)
#define DST_GC_MAX (120*HZ)
/* Each dst_entry has reference count and sits in some parent list(s).
* When it is removed from parent list, it is "freed" (dst_free).
* After this it enters dead state (dst->obsolete > 0) and if its refcnt
* is zero, it can be destroyed immediately, otherwise it is added
* to gc list and garbage collector periodically checks the refcnt.
*/
struct sk_buff;
struct dst_entry
{
struct rcu_head rcu_head;
struct dst_entry *child;
struct net_device *dev;
short error;
short obsolete;
int flags;
#define DST_HOST 1
#define DST_NOXFRM 2
#define DST_NOPOLICY 4
#define DST_NOHASH 8
#define DST_BALANCED 0x10
unsigned long expires;
unsigned short header_len; /* more space at head required */
unsigned short nfheader_len; /* more non-fragment space at head required */
unsigned short trailer_len; /* space to reserve at tail */
u32 metrics[RTAX_MAX];
struct dst_entry *path;
unsigned long rate_last; /* rate limiting for ICMP */
unsigned long rate_tokens;
struct neighbour *neighbour;
struct hh_cache *hh;
struct xfrm_state *xfrm;
int (*input)(struct sk_buff*);
int (*output)(struct sk_buff*);
#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
#endif
struct dst_ops *ops;
unsigned long lastuse;
atomic_t __refcnt; /* client references */
int __use;
union {
struct dst_entry *next;
struct rtable *rt_next;
struct rt6_info *rt6_next;
struct dn_route *dn_next;
};
char info[0];
};
struct dst_ops
{
unsigned short family;
__be16 protocol;
unsigned gc_thresh;
int (*gc)(void);
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
struct net_device *dev, int how);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
int entry_size;
atomic_t entries;
struct kmem_cache *kmem_cachep;
};
#ifdef __KERNEL__
static inline u32
dst_metric(const struct dst_entry *dst, int metric)
{
return dst->metrics[metric-1];
}
static inline u32 dst_mtu(const struct dst_entry *dst)
{
u32 mtu = dst_metric(dst, RTAX_MTU);
/*
* Alexey put it here, so ask him about it :)
*/
barrier();
return mtu;
}
static inline u32
dst_allfrag(const struct dst_entry *dst)
{
int ret = dst_metric(dst, RTAX_FEATURES) & RTAX_FEATURE_ALLFRAG;
/* Yes, _exactly_. This is paranoia. */
barrier();
return ret;
}
static inline int
dst_metric_locked(struct dst_entry *dst, int metric)
{
return dst_metric(dst, RTAX_LOCK) & (1<<metric);
}
static inline void dst_hold(struct dst_entry * dst)
{
atomic_inc(&dst->__refcnt);
}
static inline
struct dst_entry * dst_clone(struct dst_entry * dst)
{
if (dst)
atomic_inc(&dst->__refcnt);
return dst;
}
static inline
void dst_release(struct dst_entry * dst)
{
if (dst) {
WARN_ON(atomic_read(&dst->__refcnt) < 1);
smp_mb__before_atomic_dec();
atomic_dec(&dst->__refcnt);
}
}
/* Children define the path of the packet through the
* Linux networking. Thus, destinations are stackable.
*/
static inline struct dst_entry *dst_pop(struct dst_entry *dst)
{
struct dst_entry *child = dst_clone(dst->child);
dst_release(dst);
return child;
}
extern void * dst_alloc(struct dst_ops * ops);
extern void __dst_free(struct dst_entry * dst);
extern struct dst_entry *dst_destroy(struct dst_entry * dst);
static inline void dst_free(struct dst_entry * dst)
{
if (dst->obsolete > 1)
return;
if (!atomic_read(&dst->__refcnt)) {
dst = dst_destroy(dst);
if (!dst)
return;
}
__dst_free(dst);
}
static inline void dst_rcu_free(struct rcu_head *head)
{
struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
dst_free(dst);
}
static inline void dst_confirm(struct dst_entry *dst)
{
if (dst)
neigh_confirm(dst->neighbour);
}
static inline void dst_negative_advice(struct dst_entry **dst_p)
{
struct dst_entry * dst = *dst_p;
if (dst && dst->ops->negative_advice)
*dst_p = dst->ops->negative_advice(dst);
}
static inline void dst_link_failure(struct sk_buff *skb)
{
struct dst_entry * dst = skb->dst;
if (dst && dst->ops && dst->ops->link_failure)
dst->ops->link_failure(skb);
}
static inline void dst_set_expires(struct dst_entry *dst, int timeout)
{
unsigned long expires = jiffies + timeout;
if (expires == 0)
expires = 1;
if (dst->expires == 0 || time_before(expires, dst->expires))
dst->expires = expires;
}
/* Output packet to network from transport. */
static inline int dst_output(struct sk_buff *skb)
{
return skb->dst->output(skb);
}
/* Input packet from network to transport. */
static inline int dst_input(struct sk_buff *skb)
{
int err;
for (;;) {
err = skb->dst->input(skb);
if (likely(err == 0))
return err;
/* Oh, Jamal... Seems, I will not forgive you this mess. :-) */
if (unlikely(err != NET_XMIT_BYPASS))
return err;
}
}
static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
{
if (dst->obsolete)
dst = dst->ops->check(dst, cookie);
return dst;
}
extern void dst_init(void);
struct flowi;
#ifndef CONFIG_XFRM
static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
struct sock *sk, int flags)
{
return 0;
}
#else
extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
struct sock *sk, int flags);
#endif
#endif
#endif /* _NET_DST_H */

65
include/net/esp.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef _NET_ESP_H
#define _NET_ESP_H
#include <linux/crypto.h>
#include <net/xfrm.h>
#include <asm/scatterlist.h>
#define ESP_NUM_FAST_SG 4
struct esp_data
{
struct scatterlist sgbuf[ESP_NUM_FAST_SG];
/* Confidentiality */
struct {
u8 *key; /* Key */
int key_len; /* Key length */
int padlen; /* 0..255 */
/* ivlen is offset from enc_data, where encrypted data start.
* It is logically different of crypto_tfm_alg_ivsize(tfm).
* We assume that it is either zero (no ivec), or
* >= crypto_tfm_alg_ivsize(tfm). */
int ivlen;
int ivinitted;
u8 *ivec; /* ivec buffer */
struct crypto_blkcipher *tfm; /* crypto handle */
} conf;
/* Integrity. It is active when icv_full_len != 0 */
struct {
u8 *key; /* Key */
int key_len; /* Length of the key */
u8 *work_icv;
int icv_full_len;
int icv_trunc_len;
void (*icv)(struct esp_data*,
struct sk_buff *skb,
int offset, int len, u8 *icv);
struct crypto_hash *tfm;
} auth;
};
extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len);
extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer);
extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb,
int offset, int len)
{
struct hash_desc desc;
int err;
desc.tfm = esp->auth.tfm;
desc.flags = 0;
err = crypto_hash_init(&desc);
if (unlikely(err))
return err;
err = skb_icv_walk(skb, &desc, offset, len, crypto_hash_update);
if (unlikely(err))
return err;
return crypto_hash_final(&desc, esp->auth.work_icv);
}
#endif

108
include/net/fib_rules.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef __NET_FIB_RULES_H
#define __NET_FIB_RULES_H
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/fib_rules.h>
#include <net/flow.h>
#include <net/netlink.h>
struct fib_rule
{
struct list_head list;
atomic_t refcnt;
int ifindex;
char ifname[IFNAMSIZ];
u32 mark;
u32 mark_mask;
u32 pref;
u32 flags;
u32 table;
u8 action;
struct rcu_head rcu;
};
struct fib_lookup_arg
{
void *lookup_ptr;
void *result;
struct fib_rule *rule;
};
struct fib_rules_ops
{
int family;
struct list_head list;
int rule_size;
int addr_size;
int (*action)(struct fib_rule *,
struct flowi *, int,
struct fib_lookup_arg *);
int (*match)(struct fib_rule *,
struct flowi *, int);
int (*configure)(struct fib_rule *,
struct sk_buff *,
struct nlmsghdr *,
struct fib_rule_hdr *,
struct nlattr **);
int (*compare)(struct fib_rule *,
struct fib_rule_hdr *,
struct nlattr **);
int (*fill)(struct fib_rule *, struct sk_buff *,
struct nlmsghdr *,
struct fib_rule_hdr *);
u32 (*default_pref)(void);
size_t (*nlmsg_payload)(struct fib_rule *);
int nlgroup;
struct nla_policy *policy;
struct list_head *rules_list;
struct module *owner;
};
#define FRA_GENERIC_POLICY \
[FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
[FRA_PRIORITY] = { .type = NLA_U32 }, \
[FRA_FWMARK] = { .type = NLA_U32 }, \
[FRA_FWMASK] = { .type = NLA_U32 }, \
[FRA_TABLE] = { .type = NLA_U32 }
static inline void fib_rule_get(struct fib_rule *rule)
{
atomic_inc(&rule->refcnt);
}
static inline void fib_rule_put_rcu(struct rcu_head *head)
{
struct fib_rule *rule = container_of(head, struct fib_rule, rcu);
kfree(rule);
}
static inline void fib_rule_put(struct fib_rule *rule)
{
if (atomic_dec_and_test(&rule->refcnt))
call_rcu(&rule->rcu, fib_rule_put_rcu);
}
static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
{
if (nla[FRA_TABLE])
return nla_get_u32(nla[FRA_TABLE]);
return frh->table;
}
extern int fib_rules_register(struct fib_rules_ops *);
extern int fib_rules_unregister(struct fib_rules_ops *);
extern int fib_rules_lookup(struct fib_rules_ops *,
struct flowi *, int flags,
struct fib_lookup_arg *);
extern int fib_nl_newrule(struct sk_buff *,
struct nlmsghdr *, void *);
extern int fib_nl_delrule(struct sk_buff *,
struct nlmsghdr *, void *);
extern int fib_rules_dump(struct sk_buff *,
struct netlink_callback *, int);
#endif

100
include/net/flow.h Normal file
View File

@@ -0,0 +1,100 @@
/*
*
* Generic internet FLOW.
*
*/
#ifndef _NET_FLOW_H
#define _NET_FLOW_H
#include <linux/in6.h>
#include <asm/atomic.h>
struct flowi {
int oif;
int iif;
__u32 mark;
union {
struct {
__be32 daddr;
__be32 saddr;
__u8 tos;
__u8 scope;
} ip4_u;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
__be32 flowlabel;
} ip6_u;
struct {
__le16 daddr;
__le16 saddr;
__u8 scope;
} dn_u;
} nl_u;
#define fld_dst nl_u.dn_u.daddr
#define fld_src nl_u.dn_u.saddr
#define fld_scope nl_u.dn_u.scope
#define fl6_dst nl_u.ip6_u.daddr
#define fl6_src nl_u.ip6_u.saddr
#define fl6_flowlabel nl_u.ip6_u.flowlabel
#define fl4_dst nl_u.ip4_u.daddr
#define fl4_src nl_u.ip4_u.saddr
#define fl4_tos nl_u.ip4_u.tos
#define fl4_scope nl_u.ip4_u.scope
__u8 proto;
__u8 flags;
#define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
union {
struct {
__be16 sport;
__be16 dport;
} ports;
struct {
__u8 type;
__u8 code;
} icmpt;
struct {
__le16 sport;
__le16 dport;
} dnports;
__be32 spi;
#ifdef CONFIG_IPV6_MIP6
struct {
__u8 type;
} mht;
#endif
} uli_u;
#define fl_ip_sport uli_u.ports.sport
#define fl_ip_dport uli_u.ports.dport
#define fl_icmp_type uli_u.icmpt.type
#define fl_icmp_code uli_u.icmpt.code
#define fl_ipsec_spi uli_u.spi
#ifdef CONFIG_IPV6_MIP6
#define fl_mh_type uli_u.mht.type
#endif
__u32 secid; /* used by xfrm; see secid.txt */
} __attribute__((__aligned__(BITS_PER_LONG/8)));
#define FLOW_DIR_IN 0
#define FLOW_DIR_OUT 1
#define FLOW_DIR_FWD 2
struct sock;
typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
void **objp, atomic_t **obj_refp);
extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
flow_resolve_t resolver);
extern void flow_cache_flush(void);
extern atomic_t flow_cache_genid;
#endif

49
include/net/gen_stats.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef __NET_GEN_STATS_H
#define __NET_GEN_STATS_H
#include <linux/gen_stats.h>
#include <linux/socket.h>
#include <linux/rtnetlink.h>
#include <linux/pkt_sched.h>
struct gnet_dump
{
spinlock_t * lock;
struct sk_buff * skb;
struct rtattr * tail;
/* Backward compatability */
int compat_tc_stats;
int compat_xstats;
void * xstats;
int xstats_len;
struct tc_stats tc_stats;
};
extern int gnet_stats_start_copy(struct sk_buff *skb, int type,
spinlock_t *lock, struct gnet_dump *d);
extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type,
int tc_stats_type,int xstats_type,
spinlock_t *lock, struct gnet_dump *d);
extern int gnet_stats_copy_basic(struct gnet_dump *d,
struct gnet_stats_basic *b);
extern int gnet_stats_copy_rate_est(struct gnet_dump *d,
struct gnet_stats_rate_est *r);
extern int gnet_stats_copy_queue(struct gnet_dump *d,
struct gnet_stats_queue *q);
extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
extern int gnet_stats_finish_copy(struct gnet_dump *d);
extern int gen_new_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est,
spinlock_t *stats_lock, struct rtattr *opt);
extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est);
extern int gen_replace_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est,
spinlock_t *stats_lock, struct rtattr *opt);
#endif

230
include/net/genetlink.h Normal file
View File

@@ -0,0 +1,230 @@
#ifndef __NET_GENERIC_NETLINK_H
#define __NET_GENERIC_NETLINK_H
#include <linux/genetlink.h>
#include <net/netlink.h>
/**
* struct genl_family - generic netlink family
* @id: protocol family idenfitier
* @hdrsize: length of user specific header in bytes
* @name: name of family
* @version: protocol version
* @maxattr: maximum number of attributes supported
* @attrbuf: buffer to store parsed attributes
* @ops_list: list of all assigned operations
* @family_list: family list
*/
struct genl_family
{
unsigned int id;
unsigned int hdrsize;
char name[GENL_NAMSIZ];
unsigned int version;
unsigned int maxattr;
struct nlattr ** attrbuf; /* private */
struct list_head ops_list; /* private */
struct list_head family_list; /* private */
};
/**
* struct genl_info - receiving information
* @snd_seq: sending sequence number
* @snd_pid: netlink pid of sender
* @nlhdr: netlink message header
* @genlhdr: generic netlink message header
* @userhdr: user specific header
* @attrs: netlink attributes
*/
struct genl_info
{
u32 snd_seq;
u32 snd_pid;
struct nlmsghdr * nlhdr;
struct genlmsghdr * genlhdr;
void * userhdr;
struct nlattr ** attrs;
};
/**
* struct genl_ops - generic netlink operations
* @cmd: command identifier
* @flags: flags
* @policy: attribute validation policy
* @doit: standard command callback
* @dumpit: callback for dumpers
* @done: completion callback for dumps
* @ops_list: operations list
*/
struct genl_ops
{
u8 cmd;
unsigned int flags;
struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
int (*dumpit)(struct sk_buff *skb,
struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
struct list_head ops_list;
};
extern int genl_register_family(struct genl_family *family);
extern int genl_unregister_family(struct genl_family *family);
extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
extern struct sock *genl_sock;
/**
* genlmsg_put - Add generic netlink header to netlink message
* @skb: socket buffer holding the message
* @pid: netlink pid the message is addressed to
* @seq: sequence number (usually the one of the sender)
* @family: generic netlink family
* @flags netlink message flags
* @cmd: generic netlink command
*
* Returns pointer to user specific header
*/
static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
struct genl_family *family, int flags, u8 cmd)
{
struct nlmsghdr *nlh;
struct genlmsghdr *hdr;
nlh = nlmsg_put(skb, pid, seq, family->id, GENL_HDRLEN +
family->hdrsize, flags);
if (nlh == NULL)
return NULL;
hdr = nlmsg_data(nlh);
hdr->cmd = cmd;
hdr->version = family->version;
hdr->reserved = 0;
return (char *) hdr + GENL_HDRLEN;
}
/**
* genlmsg_put_reply - Add generic netlink header to a reply message
* @skb: socket buffer holding the message
* @info: receiver info
* @family: generic netlink family
* @flags: netlink message flags
* @cmd: generic netlink command
*
* Returns pointer to user specific header
*/
static inline void *genlmsg_put_reply(struct sk_buff *skb,
struct genl_info *info,
struct genl_family *family,
int flags, u8 cmd)
{
return genlmsg_put(skb, info->snd_pid, info->snd_seq, family,
flags, cmd);
}
/**
* genlmsg_end - Finalize a generic netlink message
* @skb: socket buffer the message is stored in
* @hdr: user specific header
*/
static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
{
return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
}
/**
* genlmsg_cancel - Cancel construction of a generic netlink message
* @skb: socket buffer the message is stored in
* @hdr: generic netlink message header
*/
static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
{
return nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
}
/**
* genlmsg_multicast - multicast a netlink message
* @skb: netlink message as socket buffer
* @pid: own netlink pid to avoid sending to yourself
* @group: multicast group id
* @flags: allocation flags
*/
static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
unsigned int group, gfp_t flags)
{
return nlmsg_multicast(genl_sock, skb, pid, group, flags);
}
/**
* genlmsg_unicast - unicast a netlink message
* @skb: netlink message as socket buffer
* @pid: netlink pid of the destination socket
*/
static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
{
return nlmsg_unicast(genl_sock, skb, pid);
}
/**
* genlmsg_reply - reply to a request
* @skb: netlink message to be sent back
* @info: receiver information
*/
static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
{
return genlmsg_unicast(skb, info->snd_pid);
}
/**
* gennlmsg_data - head of message payload
* @gnlh: genetlink messsage header
*/
static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
{
return ((unsigned char *) gnlh + GENL_HDRLEN);
}
/**
* genlmsg_len - length of message payload
* @gnlh: genetlink message header
*/
static inline int genlmsg_len(const struct genlmsghdr *gnlh)
{
struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
NLMSG_HDRLEN);
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
}
/**
* genlmsg_msg_size - length of genetlink message not including padding
* @payload: length of message payload
*/
static inline int genlmsg_msg_size(int payload)
{
return GENL_HDRLEN + payload;
}
/**
* genlmsg_total_size - length of genetlink message including padding
* @payload: length of message payload
*/
static inline int genlmsg_total_size(int payload)
{
return NLMSG_ALIGN(genlmsg_msg_size(payload));
}
/**
* genlmsg_new - Allocate a new generic netlink message
* @payload: size of the message payload
* @flags: the type of memory to allocate.
*/
static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
{
return nlmsg_new(genlmsg_total_size(payload), flags);
}
#endif /* __NET_GENERIC_NETLINK_H */

67
include/net/icmp.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* 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 ICMP module.
*
* Version: @(#)icmp.h 1.0.4 05/13/93
*
* Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* 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 _ICMP_H
#define _ICMP_H
#include <linux/icmp.h>
#include <net/inet_sock.h>
#include <net/snmp.h>
struct icmp_err {
int errno;
unsigned fatal:1;
};
extern struct icmp_err icmp_err_convert[];
DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics);
#define ICMP_INC_STATS(field) SNMP_INC_STATS(icmp_statistics, field)
#define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field)
#define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field)
struct dst_entry;
struct net_proto_family;
struct sk_buff;
extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
extern int icmp_rcv(struct sk_buff *skb);
extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern void icmp_init(struct net_proto_family *ops);
/* Move into dst.h ? */
extern int xrlim_allow(struct dst_entry *dst, int timeout);
struct raw_sock {
/* inet_sock has to be the first member */
struct inet_sock inet;
struct icmp_filter filter;
};
static inline struct raw_sock *raw_sk(const struct sock *sk)
{
return (struct raw_sock *)sk;
}
extern int sysctl_icmp_echo_ignore_all;
extern int sysctl_icmp_echo_ignore_broadcasts;
extern int sysctl_icmp_ignore_bogus_error_responses;
extern int sysctl_icmp_errors_use_inbound_ifaddr;
extern int sysctl_icmp_ratelimit;
extern int sysctl_icmp_ratemask;
#endif /* _ICMP_H */

1330
include/net/ieee80211.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
/*
* Original code based on Host AP (software wireless LAN access point) driver
* for Intersil Prism2/2.5/3.
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
*
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
* <jketreno@linux.intel.com>
*
* Copyright (c) 2004, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
/*
* This file defines the interface to the ieee80211 crypto module.
*/
#ifndef IEEE80211_CRYPT_H
#define IEEE80211_CRYPT_H
#include <linux/types.h>
#include <linux/list.h>
#include <net/ieee80211.h>
#include <asm/atomic.h>
enum {
IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
};
struct sk_buff;
struct module;
struct ieee80211_crypto_ops {
const char *name;
struct list_head list;
/* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated
* private data on success */
void *(*init) (int keyidx);
/* deinitialize crypto context and free allocated private data */
void (*deinit) (void *priv);
int (*build_iv) (struct sk_buff * skb, int hdr_len,
u8 *key, int keylen, void *priv);
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
* value from decrypt_mpdu is passed as the keyidx value for
* decrypt_msdu. skb must have enough head and tail room for the
* encryption; if not, error will be returned; these functions are
* called for all MPDUs (i.e., fragments).
*/
int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
/* These functions are called for full MSDUs, i.e. full frames.
* These can be NULL if full MSDU operations are not needed. */
int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
void *priv);
int (*set_key) (void *key, int len, u8 * seq, void *priv);
int (*get_key) (void *key, int len, u8 * seq, void *priv);
/* procfs handler for printing out key information and possible
* statistics */
char *(*print_stats) (char *p, void *priv);
/* Crypto specific flag get/set for configuration settings */
unsigned long (*get_flags) (void *priv);
unsigned long (*set_flags) (unsigned long flags, void *priv);
/* maximum number of bytes added by encryption; encrypt buf is
* allocated with extra_prefix_len bytes, copy of in_buf, and
* extra_postfix_len; encrypt need not use all this space, but
* the result must start at the beginning of the buffer and correct
* length must be returned */
int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
int extra_msdu_prefix_len, extra_msdu_postfix_len;
struct module *owner;
};
struct ieee80211_crypt_data {
struct list_head list; /* delayed deletion list */
struct ieee80211_crypto_ops *ops;
void *priv;
atomic_t refcnt;
};
struct ieee80211_device;
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
void ieee80211_crypt_deinit_handler(unsigned long);
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt);
void ieee80211_crypt_quiescing(struct ieee80211_device *ieee);
#endif

View File

@@ -0,0 +1,231 @@
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
/*-
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of David Young may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
/*
* Modifications to fit into the linux IEEE 802.11 stack,
* Mike Kershaw (dragorn@kismetwireless.net)
*/
#ifndef IEEE80211RADIOTAP_H
#define IEEE80211RADIOTAP_H
#include <linux/if_ether.h>
#include <linux/kernel.h>
/* Radiotap header version (from official NetBSD feed) */
#define IEEE80211RADIOTAP_VERSION "1.5"
/* Base version of the radiotap packet header data */
#define PKTHDR_RADIOTAP_VERSION 0
/* A generic radio capture format is desirable. There is one for
* Linux, but it is neither rigidly defined (there were not even
* units given for some fields) nor easily extensible.
*
* I suggest the following extensible radio capture format. It is
* based on a bitmap indicating which fields are present.
*
* I am trying to describe precisely what the application programmer
* should expect in the following, and for that reason I tell the
* units and origin of each measurement (where it applies), or else I
* use sufficiently weaselly language ("is a monotonically nondecreasing
* function of...") that I cannot set false expectations for lawyerly
* readers.
*/
/* XXX tcpdump/libpcap do not tolerate variable-length headers,
* yet, so we pad every radiotap header to 64 bytes. Ugh.
*/
#define IEEE80211_RADIOTAP_HDRLEN 64
/* The radio capture header precedes the 802.11 header. */
struct ieee80211_radiotap_header {
u8 it_version; /* Version 0. Only increases
* for drastic changes,
* introduction of compatible
* new fields does not count.
*/
u8 it_pad;
u16 it_len; /* length of the whole
* header in bytes, including
* it_version, it_pad,
* it_len, and data fields.
*/
u32 it_present; /* A bitmap telling which
* fields are present. Set bit 31
* (0x80000000) to extend the
* bitmap by another 32 bits.
* Additional extensions are made
* by setting bit 31.
*/
};
/* Name Data type Units
* ---- --------- -----
*
* IEEE80211_RADIOTAP_TSFT u64 microseconds
*
* Value in microseconds of the MAC's 64-bit 802.11 Time
* Synchronization Function timer when the first bit of the
* MPDU arrived at the MAC. For received frames, only.
*
* IEEE80211_RADIOTAP_CHANNEL 2 x u16 MHz, bitmap
*
* Tx/Rx frequency in MHz, followed by flags (see below).
*
* IEEE80211_RADIOTAP_FHSS u16 see below
*
* For frequency-hopping radios, the hop set (first byte)
* and pattern (second byte).
*
* IEEE80211_RADIOTAP_RATE u8 500kb/s
*
* Tx/Rx data rate
*
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
* one milliwatt (dBm)
*
* RF signal power at the antenna, decibel difference from
* one milliwatt.
*
* IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
* one milliwatt (dBm)
*
* RF noise power at the antenna, decibel difference from one
* milliwatt.
*
* IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
*
* RF signal power at the antenna, decibel difference from an
* arbitrary, fixed reference.
*
* IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
*
* RF noise power at the antenna, decibel difference from an
* arbitrary, fixed reference point.
*
* IEEE80211_RADIOTAP_LOCK_QUALITY u16 unitless
*
* Quality of Barker code lock. Unitless. Monotonically
* nondecreasing with "better" lock strength. Called "Signal
* Quality" in datasheets. (Is there a standard way to measure
* this?)
*
* IEEE80211_RADIOTAP_TX_ATTENUATION u16 unitless
*
* Transmit power expressed as unitless distance from max
* power set at factory calibration. 0 is max power.
* Monotonically nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION u16 decibels (dB)
*
* Transmit power expressed as decibel distance from max power
* set at factory calibration. 0 is max power. Monotonically
* nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
* one milliwatt (dBm)
*
* Transmit power expressed as dBm (decibels from a 1 milliwatt
* reference). This is the absolute power level measured at
* the antenna port.
*
* IEEE80211_RADIOTAP_FLAGS u8 bitmap
*
* Properties of transmitted and received frames. See flags
* defined below.
*
* IEEE80211_RADIOTAP_ANTENNA u8 antenna index
*
* Unitless indication of the Rx/Tx antenna for this packet.
* The first antenna is antenna 0.
*
* IEEE80211_RADIOTAP_FCS u32 data
*
* FCS from frame in network byte order.
*/
enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TSFT = 0,
IEEE80211_RADIOTAP_FLAGS = 1,
IEEE80211_RADIOTAP_RATE = 2,
IEEE80211_RADIOTAP_CHANNEL = 3,
IEEE80211_RADIOTAP_FHSS = 4,
IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
IEEE80211_RADIOTAP_EXT = 31,
};
/* Channel flags. */
#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
/* For IEEE80211_RADIOTAP_FLAGS */
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
* during CFP
*/
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
* with short
* preamble
*/
#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
* with WEP encryption
*/
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
* with fragmentation
*/
#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
* 802.11 header and payload
* (to 32-bit boundary)
*/
/* Ugly macro to convert literal channel numbers into their mhz equivalents
* There are certianly some conditions that will break this (like feeding it '30')
* but they shouldn't arise since nothing talks on channel 30. */
#define ieee80211chan2mhz(x) \
(((x) <= 14) ? \
(((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
((x) + 1000) * 5)
#endif /* IEEE80211_RADIOTAP_H */

View File

@@ -0,0 +1,371 @@
/*
* ieee80211softmac.h - public interface to the softmac
*
* Copyright (c) 2005 Johannes Berg <johannes@sipsolutions.net>
* Joseph Jezak <josejx@gentoo.org>
* Larry Finger <Larry.Finger@lwfinger.net>
* Danny van Dyk <kugelfang@gentoo.org>
* Michael Buesch <mbuesch@freenet.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* The full GNU General Public License is included in this distribution in the
* file called COPYING.
*/
#ifndef IEEE80211SOFTMAC_H_
#define IEEE80211SOFTMAC_H_
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/list.h>
#include <net/ieee80211.h>
/* Once the API is considered more or less stable,
* this should be incremented on API incompatible changes.
*/
#define IEEE80211SOFTMAC_API 0
#define IEEE80211SOFTMAC_MAX_RATES_LEN 8
#define IEEE80211SOFTMAC_MAX_EX_RATES_LEN 255
struct ieee80211softmac_ratesinfo {
u8 count;
u8 rates[IEEE80211SOFTMAC_MAX_RATES_LEN + IEEE80211SOFTMAC_MAX_EX_RATES_LEN];
};
/* internal structures */
struct ieee80211softmac_network;
struct ieee80211softmac_scaninfo;
struct ieee80211softmac_essid {
u8 len;
char data[IW_ESSID_MAX_SIZE+1];
};
struct ieee80211softmac_wpa {
char *IE;
int IElen;
int IEbuflen;
};
/*
* Information about association
*/
struct ieee80211softmac_assoc_info {
struct mutex mutex;
/*
* This is the requested ESSID. It is written
* only by the WX handlers.
*
*/
struct ieee80211softmac_essid req_essid;
/*
* the ESSID of the network we're currently
* associated (or trying) to. This is
* updated to the network's actual ESSID
* even if the requested ESSID was 'ANY'
*/
struct ieee80211softmac_essid associate_essid;
/* BSSID we're trying to associate to */
char bssid[ETH_ALEN];
/* some flags.
* static_essid is valid if the essid is constant,
* this is for use by the wx handlers only.
*
* associating is true, if the network has been
* auth'ed on and we are in the process of associating.
*
* bssvalid is true if we found a matching network
* and saved it's BSSID into the bssid above.
*
* bssfixed is used for SIOCSIWAP.
*/
u8 static_essid;
u8 short_preamble_available;
u8 associating;
u8 associated;
u8 assoc_wait;
u8 bssvalid;
u8 bssfixed;
/* Scan retries remaining */
int scan_retry;
struct delayed_work work;
struct delayed_work timeout;
};
struct ieee80211softmac_bss_info {
/* Rates supported by the network */
struct ieee80211softmac_ratesinfo supported_rates;
/* This indicates whether frames can currently be transmitted with
* short preamble (only use this variable during TX at CCK rates) */
u8 short_preamble:1;
/* This indicates whether protection (e.g. self-CTS) should be used
* when transmitting with OFDM modulation */
u8 use_protection:1;
};
enum {
IEEE80211SOFTMAC_AUTH_OPEN_REQUEST = 1,
IEEE80211SOFTMAC_AUTH_OPEN_RESPONSE = 2,
};
enum {
IEEE80211SOFTMAC_AUTH_SHARED_REQUEST = 1,
IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE = 2,
IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE = 3,
IEEE80211SOFTMAC_AUTH_SHARED_PASS = 4,
};
/* We should make these tunable
* AUTH_TIMEOUT seems really long, but that's what it is in BSD */
#define IEEE80211SOFTMAC_AUTH_TIMEOUT (12 * HZ)
#define IEEE80211SOFTMAC_AUTH_RETRY_LIMIT 5
#define IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT 3
struct ieee80211softmac_txrates {
/* The Bit-Rate to be used for multicast frames. */
u8 mcast_rate;
/* The Bit-Rate to be used for multicast management frames. */
u8 mgt_mcast_rate;
/* The Bit-Rate to be used for any other (normal) data packet. */
u8 default_rate;
/* The Bit-Rate to be used for default fallback
* (If the device supports fallback and hardware-retry)
*/
u8 default_fallback;
/* This is the rate that the user asked for */
u8 user_rate;
};
/* Bits for txrates_change callback. */
#define IEEE80211SOFTMAC_TXRATECHG_DEFAULT (1 << 0) /* default_rate */
#define IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK (1 << 1) /* default_fallback */
#define IEEE80211SOFTMAC_TXRATECHG_MCAST (1 << 2) /* mcast_rate */
#define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST (1 << 3) /* mgt_mcast_rate */
#define IEEE80211SOFTMAC_BSSINFOCHG_RATES (1 << 0) /* supported_rates */
#define IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE (1 << 1) /* short_preamble */
#define IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION (1 << 2) /* use_protection */
struct ieee80211softmac_device {
/* 802.11 structure for data stuff */
struct ieee80211_device *ieee;
struct net_device *dev;
/* only valid if associated, then holds the Association ID */
u16 association_id;
/* the following methods are callbacks that the driver
* using this framework has to assign
*/
/* always assign these */
void (*set_bssid_filter)(struct net_device *dev, const u8 *bssid);
void (*set_channel)(struct net_device *dev, u8 channel);
/* assign if you need it, informational only */
void (*link_change)(struct net_device *dev);
/* If the hardware can do scanning, assign _all_ three of these callbacks.
* When the scan finishes, call ieee80211softmac_scan_finished().
*/
/* when called, start_scan is guaranteed to not be called again
* until you call ieee80211softmac_scan_finished.
* Return 0 if scanning could start, error otherwise.
* SOFTMAC AUTHORS: don't call this, use ieee80211softmac_start_scan */
int (*start_scan)(struct net_device *dev);
/* this should block until after ieee80211softmac_scan_finished was called
* SOFTMAC AUTHORS: don't call this, use ieee80211softmac_wait_for_scan */
void (*wait_for_scan)(struct net_device *dev);
/* stop_scan aborts a scan, but is asynchronous.
* if you want to wait for it too, use wait_for_scan
* SOFTMAC AUTHORS: don't call this, use ieee80211softmac_stop_scan */
void (*stop_scan)(struct net_device *dev);
/* we'll need something about beacons here too, for AP or ad-hoc modes */
/* Transmission rates to be used by the driver.
* The SoftMAC figures out the best possible rates.
* The driver just needs to read them.
*/
struct ieee80211softmac_txrates txrates;
/* If the driver needs to do stuff on TX rate changes, assign this
* callback. See IEEE80211SOFTMAC_TXRATECHG for change flags. */
void (*txrates_change)(struct net_device *dev,
u32 changes);
/* If the driver needs to do stuff when BSS properties change, assign
* this callback. see IEEE80211SOFTMAC_BSSINFOCHG for change flags. */
void (*bssinfo_change)(struct net_device *dev,
u32 changes);
/* private stuff follows */
/* this lock protects this structure */
spinlock_t lock;
u8 running; /* SoftMAC started? */
u8 scanning;
struct ieee80211softmac_scaninfo *scaninfo;
struct ieee80211softmac_assoc_info associnfo;
struct ieee80211softmac_bss_info bssinfo;
struct list_head auth_queue;
struct list_head events;
struct ieee80211softmac_ratesinfo ratesinfo;
int txrate_badness;
/* WPA stuff */
struct ieee80211softmac_wpa wpa;
/* we need to keep a list of network structs we copied */
struct list_head network_list;
/* This must be the last item so that it points to the data
* allocated beyond this structure by alloc_ieee80211 */
u8 priv[0];
};
extern void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm);
static inline void * ieee80211softmac_priv(struct net_device *dev)
{
return ((struct ieee80211softmac_device *)ieee80211_priv(dev))->priv;
}
extern struct net_device * alloc_ieee80211softmac(int sizeof_priv);
extern void free_ieee80211softmac(struct net_device *dev);
/* Call this function if you detect a lost TX fragment.
* (If the device indicates failure of ACK RX, for example.)
* It is wise to call this function if you are able to detect lost packets,
* because it contributes to the TX Rates auto adjustment.
*/
extern void ieee80211softmac_fragment_lost(struct net_device *dev,
u16 wireless_sequence_number);
/* Call this function before _start to tell the softmac what rates
* the hw supports. The rates parameter is copied, so you can
* free it right after calling this function.
* Note that the rates need to be sorted. */
extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates);
/* Finds the highest rate which is:
* 1. Present in ri (optionally a basic rate)
* 2. Supported by the device
* 3. Less than or equal to the user-defined rate
*/
extern u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
struct ieee80211softmac_ratesinfo *ri, int basic_only);
/* Helper function which advises you the rate at which a frame should be
* transmitted at. */
static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device *mac,
int is_multicast,
int is_mgt)
{
struct ieee80211softmac_txrates *txrates = &mac->txrates;
if (!mac->associnfo.associated)
return txrates->mgt_mcast_rate;
/* We are associated, sending unicast frame */
if (!is_multicast)
return txrates->default_rate;
/* We are associated, sending multicast frame */
if (is_mgt)
return txrates->mgt_mcast_rate;
else
return txrates->mcast_rate;
}
/* Helper function which advises you when it is safe to transmit with short
* preamble.
* You should only call this function when transmitting at CCK rates. */
static inline int ieee80211softmac_short_preamble_ok(struct ieee80211softmac_device *mac,
int is_multicast,
int is_mgt)
{
return (is_multicast && is_mgt) ? 0 : mac->bssinfo.short_preamble;
}
/* Helper function which advises you whether protection (e.g. self-CTS) is
* needed. 1 = protection needed, 0 = no protection needed
* Only use this function when transmitting with OFDM modulation. */
static inline int ieee80211softmac_protection_needed(struct ieee80211softmac_device *mac)
{
return mac->bssinfo.use_protection;
}
/* Start the SoftMAC. Call this after you initialized the device
* and it is ready to run.
*/
extern void ieee80211softmac_start(struct net_device *dev);
/* Stop the SoftMAC. Call this before you shutdown the device. */
extern void ieee80211softmac_stop(struct net_device *dev);
/*
* Event system
*/
/* valid event types */
#define IEEE80211SOFTMAC_EVENT_ANY -1 /*private use only*/
#define IEEE80211SOFTMAC_EVENT_SCAN_FINISHED 0
#define IEEE80211SOFTMAC_EVENT_ASSOCIATED 1
#define IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED 2
#define IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT 3
#define IEEE80211SOFTMAC_EVENT_AUTHENTICATED 4
#define IEEE80211SOFTMAC_EVENT_AUTH_FAILED 5
#define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT 6
#define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND 7
#define IEEE80211SOFTMAC_EVENT_DISASSOCIATED 8
/* keep this updated! */
#define IEEE80211SOFTMAC_EVENT_LAST 8
/*
* If you want to be notified of certain events, you can call
* ieee80211softmac_notify[_atomic] with
* - event set to one of the constants below
* - fun set to a function pointer of the appropriate type
* - context set to the context data you want passed
* The return value is 0, or an error.
*/
typedef void (*notify_function_ptr)(struct net_device *dev, int event_type, void *context);
#define ieee80211softmac_notify(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_KERNEL);
#define ieee80211softmac_notify_atomic(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_ATOMIC);
extern int ieee80211softmac_notify_gfp(struct net_device *dev,
int event, notify_function_ptr fun, void *context, gfp_t gfp_mask);
/* To clear pending work (for ifconfig down, etc.) */
extern void
ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm);
#endif /* IEEE80211SOFTMAC_H_ */

View File

@@ -0,0 +1,99 @@
/*
* This file contains the prototypes for the wireless extension
* handlers that the softmac API provides. Include this file to
* use the wx handlers, you can assign these directly.
*
* Copyright (c) 2005 Johannes Berg <johannes@sipsolutions.net>
* Joseph Jezak <josejx@gentoo.org>
* Larry Finger <Larry.Finger@lwfinger.net>
* Danny van Dyk <kugelfang@gentoo.org>
* Michael Buesch <mbuesch@freenet.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* The full GNU General Public License is included in this distribution in the
* file called COPYING.
*/
#ifndef _IEEE80211SOFTMAC_WX_H
#define _IEEE80211SOFTMAC_WX_H
#include <net/ieee80211softmac.h>
#include <net/iw_handler.h>
extern int
ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_get_scan_results(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_set_essid(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_get_essid(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_set_rate(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_get_rate(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_get_wap(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_set_wap(struct net_device *net_dev,
struct iw_request_info *info,
union iwreq_data *data,
char *extra);
extern int
ieee80211softmac_wx_set_genie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu,
char *extra);
extern int
ieee80211softmac_wx_get_genie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu,
char *extra);
extern int
ieee80211softmac_wx_set_mlme(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu,
char *extra);
#endif /* _IEEE80211SOFTMAC_WX */

286
include/net/if_inet6.h Normal file
View File

@@ -0,0 +1,286 @@
/*
* inet6 interface/address list definitions
* Linux INET6 implementation
*
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
*
* 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 _NET_IF_INET6_H
#define _NET_IF_INET6_H
#include <net/snmp.h>
#include <linux/ipv6.h>
/* inet6_dev.if_flags */
#define IF_RA_OTHERCONF 0x80
#define IF_RA_MANAGED 0x40
#define IF_RA_RCVD 0x20
#define IF_RS_SENT 0x10
#define IF_READY 0x80000000
/* prefix flags */
#define IF_PREFIX_ONLINK 0x01
#define IF_PREFIX_AUTOCONF 0x02
#ifdef __KERNEL__
struct inet6_ifaddr
{
struct in6_addr addr;
__u32 prefix_len;
__u32 valid_lft;
__u32 prefered_lft;
unsigned long cstamp; /* created timestamp */
unsigned long tstamp; /* updated timestamp */
atomic_t refcnt;
spinlock_t lock;
__u8 probes;
__u8 flags;
__u16 scope;
struct timer_list timer;
struct inet6_dev *idev;
struct rt6_info *rt;
struct inet6_ifaddr *lst_next; /* next addr in addr_lst */
struct inet6_ifaddr *if_next; /* next addr in inet6_dev */
#ifdef CONFIG_IPV6_PRIVACY
struct inet6_ifaddr *tmp_next; /* next addr in tempaddr_lst */
struct inet6_ifaddr *ifpub;
int regen_count;
#endif
int dead;
};
struct ip6_sf_socklist
{
unsigned int sl_max;
unsigned int sl_count;
struct in6_addr sl_addr[0];
};
#define IP6_SFLSIZE(count) (sizeof(struct ip6_sf_socklist) + \
(count) * sizeof(struct in6_addr))
#define IP6_SFBLOCK 10 /* allocate this many at once */
struct ipv6_mc_socklist
{
struct in6_addr addr;
int ifindex;
struct ipv6_mc_socklist *next;
rwlock_t sflock;
unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
struct ip6_sf_socklist *sflist;
};
struct ip6_sf_list
{
struct ip6_sf_list *sf_next;
struct in6_addr sf_addr;
unsigned long sf_count[2]; /* include/exclude counts */
unsigned char sf_gsresp; /* include in g & s response? */
unsigned char sf_oldin; /* change state */
unsigned char sf_crcount; /* retrans. left to send */
};
#define MAF_TIMER_RUNNING 0x01
#define MAF_LAST_REPORTER 0x02
#define MAF_LOADED 0x04
#define MAF_NOREPORT 0x08
#define MAF_GSQUERY 0x10
struct ifmcaddr6
{
struct in6_addr mca_addr;
struct inet6_dev *idev;
struct ifmcaddr6 *next;
struct ip6_sf_list *mca_sources;
struct ip6_sf_list *mca_tomb;
unsigned int mca_sfmode;
unsigned long mca_sfcount[2];
struct timer_list mca_timer;
unsigned mca_flags;
int mca_users;
atomic_t mca_refcnt;
spinlock_t mca_lock;
unsigned char mca_crcount;
unsigned long mca_cstamp;
unsigned long mca_tstamp;
};
/* Anycast stuff */
struct ipv6_ac_socklist
{
struct in6_addr acl_addr;
int acl_ifindex;
struct ipv6_ac_socklist *acl_next;
};
struct ifacaddr6
{
struct in6_addr aca_addr;
struct inet6_dev *aca_idev;
struct rt6_info *aca_rt;
struct ifacaddr6 *aca_next;
int aca_users;
atomic_t aca_refcnt;
spinlock_t aca_lock;
unsigned long aca_cstamp;
unsigned long aca_tstamp;
};
#define IFA_HOST IPV6_ADDR_LOOPBACK
#define IFA_LINK IPV6_ADDR_LINKLOCAL
#define IFA_SITE IPV6_ADDR_SITELOCAL
#define IFA_GLOBAL 0x0000U
struct ipv6_devstat {
struct proc_dir_entry *proc_dir_entry;
DEFINE_SNMP_STAT(struct ipstats_mib, ipv6);
DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
};
struct inet6_dev
{
struct net_device *dev;
struct inet6_ifaddr *addr_list;
struct ifmcaddr6 *mc_list;
struct ifmcaddr6 *mc_tomb;
rwlock_t mc_lock;
unsigned long mc_v1_seen;
unsigned long mc_maxdelay;
unsigned char mc_qrv;
unsigned char mc_gq_running;
unsigned char mc_ifc_count;
struct timer_list mc_gq_timer; /* general query timer */
struct timer_list mc_ifc_timer; /* interface change timer */
struct ifacaddr6 *ac_list;
rwlock_t lock;
atomic_t refcnt;
__u32 if_flags;
int dead;
#ifdef CONFIG_IPV6_PRIVACY
u8 rndid[8];
struct timer_list regen_timer;
struct inet6_ifaddr *tempaddr_list;
#endif
struct neigh_parms *nd_parms;
struct inet6_dev *next;
struct ipv6_devconf cnf;
struct ipv6_devstat stats;
unsigned long tstamp; /* ipv6InterfaceTable update timestamp */
struct rcu_head rcu;
};
extern struct ipv6_devconf ipv6_devconf;
static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
{
/*
* +-------+-------+-------+-------+-------+-------+
* | 33 | 33 | DST13 | DST14 | DST15 | DST16 |
* +-------+-------+-------+-------+-------+-------+
*/
buf[0]= 0x33;
buf[1]= 0x33;
memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32));
}
static inline void ipv6_tr_mc_map(struct in6_addr *addr, char *buf)
{
/* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */
if (((addr->s6_addr[0] == 0xFF) &&
((addr->s6_addr[1] == 0x01) || (addr->s6_addr[1] == 0x02)) &&
(addr->s6_addr16[1] == 0) &&
(addr->s6_addr32[1] == 0) &&
(addr->s6_addr32[2] == 0) &&
(addr->s6_addr16[6] == 0) &&
(addr->s6_addr[15] == 1)) ||
((addr->s6_addr[0] == 0xFF) &&
(addr->s6_addr[1] == 0x02) &&
(addr->s6_addr16[1] == 0) &&
(addr->s6_addr32[1] == 0) &&
(addr->s6_addr16[4] == 0) &&
(addr->s6_addr[10] == 0) &&
(addr->s6_addr[11] == 1) &&
(addr->s6_addr[12] == 0xff)))
{
buf[0]=0xC0;
buf[1]=0x00;
buf[2]=0x01;
buf[3]=0x00;
buf[4]=0x00;
buf[5]=0x00;
/* All routers FF0x::2 */
} else if ((addr->s6_addr[0] ==0xff) &&
((addr->s6_addr[1] & 0xF0) == 0) &&
(addr->s6_addr16[1] == 0) &&
(addr->s6_addr32[1] == 0) &&
(addr->s6_addr32[2] == 0) &&
(addr->s6_addr16[6] == 0) &&
(addr->s6_addr[15] == 2))
{
buf[0]=0xC0;
buf[1]=0x00;
buf[2]=0x02;
buf[3]=0x00;
buf[4]=0x00;
buf[5]=0x00;
} else {
unsigned char i ;
i = addr->s6_addr[15] & 7 ;
buf[0]=0xC0;
buf[1]=0x00;
buf[2]=0x00;
buf[3]=0x01 << i ;
buf[4]=0x00;
buf[5]=0x00;
}
}
static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf)
{
buf[0] = 0x00;
}
static inline void ipv6_ib_mc_map(struct in6_addr *addr, char *buf)
{
buf[0] = 0; /* Reserved */
buf[1] = 0xff; /* Multicast QPN */
buf[2] = 0xff;
buf[3] = 0xff;
buf[4] = 0xff;
buf[5] = 0x12; /* link local scope */
buf[6] = 0x60; /* IPv6 signature */
buf[7] = 0x1b;
buf[8] = 0; /* P_Key */
buf[9] = 0;
memcpy(buf + 10, addr->s6_addr + 6, 10);
}
#endif
#endif

View File

@@ -0,0 +1,42 @@
/*
* NET Generic infrastructure for INET6 connection oriented protocols.
*
* Authors: Many people, see the TCPv6 sources
*
* From code originally in TCPv6
*
* 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 _INET6_CONNECTION_SOCK_H
#define _INET6_CONNECTION_SOCK_H
#include <linux/types.h>
struct in6_addr;
struct inet_bind_bucket;
struct request_sock;
struct sk_buff;
struct sock;
struct sockaddr;
extern int inet6_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb);
extern struct request_sock *inet6_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport,
const struct in6_addr *raddr,
const struct in6_addr *laddr,
const int iif);
extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
struct request_sock *req,
const unsigned long timeout);
extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok);
#endif /* _INET6_CONNECTION_SOCK_H */

View File

@@ -0,0 +1,90 @@
/*
* 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.
*
* Authors: Lotsa people, from code originally in tcp
*
* 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 _INET6_HASHTABLES_H
#define _INET6_HASHTABLES_H
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#include <linux/in6.h>
#include <linux/ipv6.h>
#include <linux/types.h>
#include <net/ipv6.h>
struct inet_hashinfo;
/* I have no idea if this is a good hash for v6 or not. -DaveM */
static inline unsigned int inet6_ehashfn(const struct in6_addr *laddr, const u16 lport,
const struct in6_addr *faddr, const __be16 fport)
{
unsigned int hashent = (lport ^ (__force u16)fport);
hashent ^= (__force u32)(laddr->s6_addr32[3] ^ faddr->s6_addr32[3]);
hashent ^= hashent >> 16;
hashent ^= hashent >> 8;
return hashent;
}
static inline int inet6_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct ipv6_pinfo *np = inet6_sk(sk);
const struct in6_addr *laddr = &np->rcv_saddr;
const struct in6_addr *faddr = &np->daddr;
const __u16 lport = inet->num;
const __be16 fport = inet->dport;
return inet6_ehashfn(laddr, lport, faddr, fport);
}
extern void __inet6_hash(struct inet_hashinfo *hashinfo, struct sock *sk);
/*
* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
* we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
*
* The sockhash lock must be held as a reader here.
*/
extern struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif);
extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
const struct in6_addr *daddr,
const unsigned short hnum,
const int dif);
static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif)
{
struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
daddr, hnum, dif);
if (sk)
return sk;
return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
}
extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr, const __be16 sport,
const struct in6_addr *daddr, const __be16 dport,
const int dif);
#endif /* defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) */
#endif /* _INET6_HASHTABLES_H */

48
include/net/inet_common.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef _INET_COMMON_H
#define _INET_COMMON_H
extern const struct proto_ops inet_stream_ops;
extern const struct proto_ops inet_dgram_ops;
/*
* INET4 prototypes used by INET6
*/
struct msghdr;
struct sock;
struct sockaddr;
struct socket;
extern void inet_remove_sock(struct sock *sk1);
extern void inet_put_sock(unsigned short num,
struct sock *sk);
extern int inet_release(struct socket *sock);
extern int inet_stream_connect(struct socket *sock,
struct sockaddr * uaddr,
int addr_len, int flags);
extern int inet_dgram_connect(struct socket *sock,
struct sockaddr * uaddr,
int addr_len, int flags);
extern int inet_accept(struct socket *sock,
struct socket *newsock, int flags);
extern int inet_sendmsg(struct kiocb *iocb,
struct socket *sock,
struct msghdr *msg,
size_t size);
extern int inet_shutdown(struct socket *sock, int how);
extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
extern int inet_listen(struct socket *sock, int backlog);
extern void inet_sock_destruct(struct sock *sk);
extern int inet_bind(struct socket *sock,
struct sockaddr *uaddr, int addr_len);
extern int inet_getname(struct socket *sock,
struct sockaddr *uaddr,
int *uaddr_len, int peer);
extern int inet_ioctl(struct socket *sock,
unsigned int cmd, unsigned long arg);
#endif

View File

@@ -0,0 +1,341 @@
/*
* NET Generic infrastructure for INET connection oriented protocols.
*
* Definitions for inet_connection_sock
*
* Authors: Many people, see the TCP sources
*
* From code originally in TCP
*
* 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 _INET_CONNECTION_SOCK_H
#define _INET_CONNECTION_SOCK_H
#include <linux/compiler.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/poll.h>
#include <net/inet_sock.h>
#include <net/request_sock.h>
#define INET_CSK_DEBUG 1
/* Cancel timers, when they are not required. */
#undef INET_CSK_CLEAR_TIMERS
struct inet_bind_bucket;
struct inet_hashinfo;
struct tcp_congestion_ops;
/*
* Pointers to address related TCP functions
* (i.e. things that depend on the address family)
*/
struct inet_connection_sock_af_ops {
int (*queue_xmit)(struct sk_buff *skb, int ipfragok);
void (*send_check)(struct sock *sk, int len,
struct sk_buff *skb);
int (*rebuild_header)(struct sock *sk);
int (*conn_request)(struct sock *sk, struct sk_buff *skb);
struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct dst_entry *dst);
int (*remember_stamp)(struct sock *sk);
u16 net_header_len;
u16 sockaddr_len;
int (*setsockopt)(struct sock *sk, int level, int optname,
char __user *optval, int optlen);
int (*getsockopt)(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
int (*compat_setsockopt)(struct sock *sk,
int level, int optname,
char __user *optval, int optlen);
int (*compat_getsockopt)(struct sock *sk,
int level, int optname,
char __user *optval, int __user *optlen);
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
};
/** inet_connection_sock - INET connection oriented sock
*
* @icsk_accept_queue: FIFO of established children
* @icsk_bind_hash: Bind node
* @icsk_timeout: Timeout
* @icsk_retransmit_timer: Resend (no ack)
* @icsk_rto: Retransmit timeout
* @icsk_pmtu_cookie Last pmtu seen by socket
* @icsk_ca_ops Pluggable congestion control hook
* @icsk_af_ops Operations which are AF_INET{4,6} specific
* @icsk_ca_state: Congestion control state
* @icsk_retransmits: Number of unrecovered [RTO] timeouts
* @icsk_pending: Scheduled timer event
* @icsk_backoff: Backoff
* @icsk_syn_retries: Number of allowed SYN (or equivalent) retries
* @icsk_probes_out: unanswered 0 window probes
* @icsk_ext_hdr_len: Network protocol overhead (IP/IPv6 options)
* @icsk_ack: Delayed ACK control data
* @icsk_mtup; MTU probing control data
*/
struct inet_connection_sock {
/* inet_sock has to be the first member! */
struct inet_sock icsk_inet;
struct request_sock_queue icsk_accept_queue;
struct inet_bind_bucket *icsk_bind_hash;
unsigned long icsk_timeout;
struct timer_list icsk_retransmit_timer;
struct timer_list icsk_delack_timer;
__u32 icsk_rto;
__u32 icsk_pmtu_cookie;
const struct tcp_congestion_ops *icsk_ca_ops;
const struct inet_connection_sock_af_ops *icsk_af_ops;
unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
__u8 icsk_ca_state;
__u8 icsk_retransmits;
__u8 icsk_pending;
__u8 icsk_backoff;
__u8 icsk_syn_retries;
__u8 icsk_probes_out;
__u16 icsk_ext_hdr_len;
struct {
__u8 pending; /* ACK is pending */
__u8 quick; /* Scheduled number of quick acks */
__u8 pingpong; /* The session is interactive */
__u8 blocked; /* Delayed ACK was blocked by socket lock */
__u32 ato; /* Predicted tick of soft clock */
unsigned long timeout; /* Currently scheduled timeout */
__u32 lrcvtime; /* timestamp of last received data packet */
__u16 last_seg_size; /* Size of last incoming segment */
__u16 rcv_mss; /* MSS used for delayed ACK decisions */
} icsk_ack;
struct {
int enabled;
/* Range of MTUs to search */
int search_high;
int search_low;
/* Information on the current probe. */
int probe_size;
} icsk_mtup;
u32 icsk_ca_priv[16];
#define ICSK_CA_PRIV_SIZE (16 * sizeof(u32))
};
#define ICSK_TIME_RETRANS 1 /* Retransmit timer */
#define ICSK_TIME_DACK 2 /* Delayed ack timer */
#define ICSK_TIME_PROBE0 3 /* Zero window probe timer */
#define ICSK_TIME_KEEPOPEN 4 /* Keepalive timer */
static inline struct inet_connection_sock *inet_csk(const struct sock *sk)
{
return (struct inet_connection_sock *)sk;
}
static inline void *inet_csk_ca(const struct sock *sk)
{
return (void *)inet_csk(sk)->icsk_ca_priv;
}
extern struct sock *inet_csk_clone(struct sock *sk,
const struct request_sock *req,
const gfp_t priority);
enum inet_csk_ack_state_t {
ICSK_ACK_SCHED = 1,
ICSK_ACK_TIMER = 2,
ICSK_ACK_PUSHED = 4,
ICSK_ACK_PUSHED2 = 8
};
extern void inet_csk_init_xmit_timers(struct sock *sk,
void (*retransmit_handler)(unsigned long),
void (*delack_handler)(unsigned long),
void (*keepalive_handler)(unsigned long));
extern void inet_csk_clear_xmit_timers(struct sock *sk);
static inline void inet_csk_schedule_ack(struct sock *sk)
{
inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_SCHED;
}
static inline int inet_csk_ack_scheduled(const struct sock *sk)
{
return inet_csk(sk)->icsk_ack.pending & ICSK_ACK_SCHED;
}
static inline void inet_csk_delack_init(struct sock *sk)
{
memset(&inet_csk(sk)->icsk_ack, 0, sizeof(inet_csk(sk)->icsk_ack));
}
extern void inet_csk_delete_keepalive_timer(struct sock *sk);
extern void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long timeout);
#ifdef INET_CSK_DEBUG
extern const char inet_csk_timer_bug_msg[];
#endif
static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what)
{
struct inet_connection_sock *icsk = inet_csk(sk);
if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
icsk->icsk_pending = 0;
#ifdef INET_CSK_CLEAR_TIMERS
sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
#endif
} else if (what == ICSK_TIME_DACK) {
icsk->icsk_ack.blocked = icsk->icsk_ack.pending = 0;
#ifdef INET_CSK_CLEAR_TIMERS
sk_stop_timer(sk, &icsk->icsk_delack_timer);
#endif
}
#ifdef INET_CSK_DEBUG
else {
pr_debug("%s", inet_csk_timer_bug_msg);
}
#endif
}
/*
* Reset the retransmission timer
*/
static inline void inet_csk_reset_xmit_timer(struct sock *sk, const int what,
unsigned long when,
const unsigned long max_when)
{
struct inet_connection_sock *icsk = inet_csk(sk);
if (when > max_when) {
#ifdef INET_CSK_DEBUG
pr_debug("reset_xmit_timer: sk=%p %d when=0x%lx, caller=%p\n",
sk, what, when, current_text_addr());
#endif
when = max_when;
}
if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
icsk->icsk_pending = what;
icsk->icsk_timeout = jiffies + when;
sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
} else if (what == ICSK_TIME_DACK) {
icsk->icsk_ack.pending |= ICSK_ACK_TIMER;
icsk->icsk_ack.timeout = jiffies + when;
sk_reset_timer(sk, &icsk->icsk_delack_timer, icsk->icsk_ack.timeout);
}
#ifdef INET_CSK_DEBUG
else {
pr_debug("%s", inet_csk_timer_bug_msg);
}
#endif
}
extern struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
extern struct request_sock *inet_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport,
const __be32 raddr,
const __be32 laddr);
extern int inet_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb);
extern int inet_csk_get_port(struct inet_hashinfo *hashinfo,
struct sock *sk, unsigned short snum,
int (*bind_conflict)(const struct sock *sk,
const struct inet_bind_bucket *tb));
extern struct dst_entry* inet_csk_route_req(struct sock *sk,
const struct request_sock *req);
static inline void inet_csk_reqsk_queue_add(struct sock *sk,
struct request_sock *req,
struct sock *child)
{
reqsk_queue_add(&inet_csk(sk)->icsk_accept_queue, req, sk, child);
}
extern void inet_csk_reqsk_queue_hash_add(struct sock *sk,
struct request_sock *req,
unsigned long timeout);
static inline void inet_csk_reqsk_queue_removed(struct sock *sk,
struct request_sock *req)
{
if (reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req) == 0)
inet_csk_delete_keepalive_timer(sk);
}
static inline void inet_csk_reqsk_queue_added(struct sock *sk,
const unsigned long timeout)
{
if (reqsk_queue_added(&inet_csk(sk)->icsk_accept_queue) == 0)
inet_csk_reset_keepalive_timer(sk, timeout);
}
static inline int inet_csk_reqsk_queue_len(const struct sock *sk)
{
return reqsk_queue_len(&inet_csk(sk)->icsk_accept_queue);
}
static inline int inet_csk_reqsk_queue_young(const struct sock *sk)
{
return reqsk_queue_len_young(&inet_csk(sk)->icsk_accept_queue);
}
static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
{
return reqsk_queue_is_full(&inet_csk(sk)->icsk_accept_queue);
}
static inline void inet_csk_reqsk_queue_unlink(struct sock *sk,
struct request_sock *req,
struct request_sock **prev)
{
reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req, prev);
}
static inline void inet_csk_reqsk_queue_drop(struct sock *sk,
struct request_sock *req,
struct request_sock **prev)
{
inet_csk_reqsk_queue_unlink(sk, req, prev);
inet_csk_reqsk_queue_removed(sk, req);
reqsk_free(req);
}
extern void inet_csk_reqsk_queue_prune(struct sock *parent,
const unsigned long interval,
const unsigned long timeout,
const unsigned long max_rto);
extern void inet_csk_destroy_sock(struct sock *sk);
/*
* LISTEN is a special case for poll..
*/
static inline unsigned int inet_csk_listen_poll(const struct sock *sk)
{
return !reqsk_queue_empty(&inet_csk(sk)->icsk_accept_queue) ?
(POLLIN | POLLRDNORM) : 0;
}
extern int inet_csk_listen_start(struct sock *sk, const int nr_table_entries);
extern void inet_csk_listen_stop(struct sock *sk);
extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
extern int inet_csk_ctl_sock_create(struct socket **sock,
unsigned short family,
unsigned short type,
unsigned char protocol);
extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen);
#endif /* _INET_CONNECTION_SOCK_H */

130
include/net/inet_ecn.h Normal file
View File

@@ -0,0 +1,130 @@
#ifndef _INET_ECN_H_
#define _INET_ECN_H_
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <net/inet_sock.h>
#include <net/dsfield.h>
enum {
INET_ECN_NOT_ECT = 0,
INET_ECN_ECT_1 = 1,
INET_ECN_ECT_0 = 2,
INET_ECN_CE = 3,
INET_ECN_MASK = 3,
};
static inline int INET_ECN_is_ce(__u8 dsfield)
{
return (dsfield & INET_ECN_MASK) == INET_ECN_CE;
}
static inline int INET_ECN_is_not_ect(__u8 dsfield)
{
return (dsfield & INET_ECN_MASK) == INET_ECN_NOT_ECT;
}
static inline int INET_ECN_is_capable(__u8 dsfield)
{
return (dsfield & INET_ECN_ECT_0);
}
static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner)
{
outer &= ~INET_ECN_MASK;
outer |= !INET_ECN_is_ce(inner) ? (inner & INET_ECN_MASK) :
INET_ECN_ECT_0;
return outer;
}
#define INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; } while (0)
#define INET_ECN_dontxmit(sk) \
do { inet_sk(sk)->tos &= ~INET_ECN_MASK; } while (0)
#define IP6_ECN_flow_init(label) do { \
(label) &= ~htonl(INET_ECN_MASK << 20); \
} while (0)
#define IP6_ECN_flow_xmit(sk, label) do { \
if (INET_ECN_is_capable(inet_sk(sk)->tos)) \
(label) |= htonl(INET_ECN_ECT_0 << 20); \
} while (0)
static inline int IP_ECN_set_ce(struct iphdr *iph)
{
u32 check = (__force u32)iph->check;
u32 ecn = (iph->tos + 1) & INET_ECN_MASK;
/*
* After the last operation we have (in binary):
* INET_ECN_NOT_ECT => 01
* INET_ECN_ECT_1 => 10
* INET_ECN_ECT_0 => 11
* INET_ECN_CE => 00
*/
if (!(ecn & 2))
return !ecn;
/*
* The following gives us:
* INET_ECN_ECT_1 => check += htons(0xFFFD)
* INET_ECN_ECT_0 => check += htons(0xFFFE)
*/
check += (__force u16)htons(0xFFFB) + (__force u16)htons(ecn);
iph->check = (__force __sum16)(check + (check>=0xFFFF));
iph->tos |= INET_ECN_CE;
return 1;
}
static inline void IP_ECN_clear(struct iphdr *iph)
{
iph->tos &= ~INET_ECN_MASK;
}
static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
{
u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK;
ipv4_change_dsfield(inner, INET_ECN_MASK, dscp);
}
struct ipv6hdr;
static inline int IP6_ECN_set_ce(struct ipv6hdr *iph)
{
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
return 0;
*(__be32*)iph |= htonl(INET_ECN_CE << 20);
return 1;
}
static inline void IP6_ECN_clear(struct ipv6hdr *iph)
{
*(__be32*)iph &= ~htonl(INET_ECN_MASK << 20);
}
static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner)
{
u32 dscp = ipv6_get_dsfield(outer) & ~INET_ECN_MASK;
ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
}
static inline int INET_ECN_set_ce(struct sk_buff *skb)
{
switch (skb->protocol) {
case __constant_htons(ETH_P_IP):
if (skb->nh.raw + sizeof(struct iphdr) <= skb->tail)
return IP_ECN_set_ce(skb->nh.iph);
break;
case __constant_htons(ETH_P_IPV6):
if (skb->nh.raw + sizeof(struct ipv6hdr) <= skb->tail)
return IP6_ECN_set_ce(skb->nh.ipv6h);
break;
}
return 0;
}
#endif

View File

@@ -0,0 +1,422 @@
/*
* 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.
*
* Authors: Lotsa people, from code originally in tcp
*
* 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 _INET_HASHTABLES_H
#define _INET_HASHTABLES_H
#include <linux/interrupt.h>
#include <linux/ipv6.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <net/inet_connection_sock.h>
#include <net/inet_sock.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <asm/atomic.h>
#include <asm/byteorder.h>
/* This is for all connections with a full identity, no wildcards.
* One chain is dedicated to TIME_WAIT sockets.
* I'll experiment with dynamic table growth later.
*/
struct inet_ehash_bucket {
rwlock_t lock;
struct hlist_head chain;
struct hlist_head twchain;
};
/* There are a few simple rules, which allow for local port reuse by
* an application. In essence:
*
* 1) Sockets bound to different interfaces may share a local port.
* Failing that, goto test 2.
* 2) If all sockets have sk->sk_reuse set, and none of them are in
* TCP_LISTEN state, the port may be shared.
* Failing that, goto test 3.
* 3) If all sockets are bound to a specific inet_sk(sk)->rcv_saddr local
* address, and none of them are the same, the port may be
* shared.
* Failing this, the port cannot be shared.
*
* The interesting point, is test #2. This is what an FTP server does
* all day. To optimize this case we use a specific flag bit defined
* below. As we add sockets to a bind bucket list, we perform a
* check of: (newsk->sk_reuse && (newsk->sk_state != TCP_LISTEN))
* As long as all sockets added to a bind bucket pass this test,
* the flag bit will be set.
* The resulting situation is that tcp_v[46]_verify_bind() can just check
* for this flag bit, if it is set and the socket trying to bind has
* sk->sk_reuse set, we don't even have to walk the owners list at all,
* we return that it is ok to bind this socket to the requested local port.
*
* Sounds like a lot of work, but it is worth it. In a more naive
* implementation (ie. current FreeBSD etc.) the entire list of ports
* must be walked for each data port opened by an ftp server. Needless
* to say, this does not scale at all. With a couple thousand FTP
* users logged onto your box, isn't it nice to know that new data
* ports are created in O(1) time? I thought so. ;-) -DaveM
*/
struct inet_bind_bucket {
unsigned short port;
signed short fastreuse;
struct hlist_node node;
struct hlist_head owners;
};
#define inet_bind_bucket_for_each(tb, node, head) \
hlist_for_each_entry(tb, node, head, node)
struct inet_bind_hashbucket {
spinlock_t lock;
struct hlist_head chain;
};
/* This is for listening sockets, thus all sockets which possess wildcards. */
#define INET_LHTABLE_SIZE 32 /* Yes, really, this is all you need. */
struct inet_hashinfo {
/* This is for sockets with full identity only. Sockets here will
* always be without wildcards and will have the following invariant:
*
* TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE
*
* TIME_WAIT sockets use a separate chain (twchain).
*/
struct inet_ehash_bucket *ehash;
/* Ok, let's try this, I give up, we do need a local binding
* TCP hash as well as the others for fast bind/connect.
*/
struct inet_bind_hashbucket *bhash;
int bhash_size;
unsigned int ehash_size;
/* All sockets in TCP_LISTEN state will be in here. This is the only
* table where wildcard'd TCP sockets can exist. Hash function here
* is just local port number.
*/
struct hlist_head listening_hash[INET_LHTABLE_SIZE];
/* All the above members are written once at bootup and
* never written again _or_ are predominantly read-access.
*
* Now align to a new cache line as all the following members
* are often dirty.
*/
rwlock_t lhash_lock ____cacheline_aligned;
atomic_t lhash_users;
wait_queue_head_t lhash_wait;
struct kmem_cache *bind_bucket_cachep;
};
static inline struct inet_ehash_bucket *inet_ehash_bucket(
struct inet_hashinfo *hashinfo,
unsigned int hash)
{
return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)];
}
extern struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep,
struct inet_bind_hashbucket *head,
const unsigned short snum);
extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
struct inet_bind_bucket *tb);
static inline int inet_bhashfn(const __u16 lport, const int bhash_size)
{
return lport & (bhash_size - 1);
}
extern void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
const unsigned short snum);
/* These can have wildcards, don't try too hard. */
static inline int inet_lhashfn(const unsigned short num)
{
return num & (INET_LHTABLE_SIZE - 1);
}
static inline int inet_sk_listen_hashfn(const struct sock *sk)
{
return inet_lhashfn(inet_sk(sk)->num);
}
/* Caller must disable local BH processing. */
static inline void __inet_inherit_port(struct inet_hashinfo *table,
struct sock *sk, struct sock *child)
{
const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size);
struct inet_bind_hashbucket *head = &table->bhash[bhash];
struct inet_bind_bucket *tb;
spin_lock(&head->lock);
tb = inet_csk(sk)->icsk_bind_hash;
sk_add_bind_node(child, &tb->owners);
inet_csk(child)->icsk_bind_hash = tb;
spin_unlock(&head->lock);
}
static inline void inet_inherit_port(struct inet_hashinfo *table,
struct sock *sk, struct sock *child)
{
local_bh_disable();
__inet_inherit_port(table, sk, child);
local_bh_enable();
}
extern void inet_put_port(struct inet_hashinfo *table, struct sock *sk);
extern void inet_listen_wlock(struct inet_hashinfo *hashinfo);
/*
* - We may sleep inside this lock.
* - If sleeping is not required (or called from BH),
* use plain read_(un)lock(&inet_hashinfo.lhash_lock).
*/
static inline void inet_listen_lock(struct inet_hashinfo *hashinfo)
{
/* read_lock synchronizes to candidates to writers */
read_lock(&hashinfo->lhash_lock);
atomic_inc(&hashinfo->lhash_users);
read_unlock(&hashinfo->lhash_lock);
}
static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo)
{
if (atomic_dec_and_test(&hashinfo->lhash_users))
wake_up(&hashinfo->lhash_wait);
}
static inline void __inet_hash(struct inet_hashinfo *hashinfo,
struct sock *sk, const int listen_possible)
{
struct hlist_head *list;
rwlock_t *lock;
BUG_TRAP(sk_unhashed(sk));
if (listen_possible && sk->sk_state == TCP_LISTEN) {
list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
lock = &hashinfo->lhash_lock;
inet_listen_wlock(hashinfo);
} else {
struct inet_ehash_bucket *head;
sk->sk_hash = inet_sk_ehashfn(sk);
head = inet_ehash_bucket(hashinfo, sk->sk_hash);
list = &head->chain;
lock = &head->lock;
write_lock(lock);
}
__sk_add_node(sk, list);
sock_prot_inc_use(sk->sk_prot);
write_unlock(lock);
if (listen_possible && sk->sk_state == TCP_LISTEN)
wake_up(&hashinfo->lhash_wait);
}
static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
{
if (sk->sk_state != TCP_CLOSE) {
local_bh_disable();
__inet_hash(hashinfo, sk, 1);
local_bh_enable();
}
}
static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk)
{
rwlock_t *lock;
if (sk_unhashed(sk))
goto out;
if (sk->sk_state == TCP_LISTEN) {
local_bh_disable();
inet_listen_wlock(hashinfo);
lock = &hashinfo->lhash_lock;
} else {
lock = &inet_ehash_bucket(hashinfo, sk->sk_hash)->lock;
write_lock_bh(lock);
}
if (__sk_del_node_init(sk))
sock_prot_dec_use(sk->sk_prot);
write_unlock_bh(lock);
out:
if (sk->sk_state == TCP_LISTEN)
wake_up(&hashinfo->lhash_wait);
}
static inline int inet_iif(const struct sk_buff *skb)
{
return ((struct rtable *)skb->dst)->rt_iif;
}
extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
const __be32 daddr,
const unsigned short hnum,
const int dif);
static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
__be32 daddr, __be16 dport, int dif)
{
return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
}
/* Socket demux engine toys. */
/* What happens here is ugly; there's a pair of adjacent fields in
struct inet_sock; __be16 dport followed by __u16 num. We want to
search by pair, so we combine the keys into a single 32bit value
and compare with 32bit value read from &...->dport. Let's at least
make sure that it's not mixed with anything else...
On 64bit targets we combine comparisons with pair of adjacent __be32
fields in the same way.
*/
typedef __u32 __bitwise __portpair;
#ifdef __BIG_ENDIAN
#define INET_COMBINED_PORTS(__sport, __dport) \
((__force __portpair)(((__force __u32)(__be16)(__sport) << 16) | (__u32)(__dport)))
#else /* __LITTLE_ENDIAN */
#define INET_COMBINED_PORTS(__sport, __dport) \
((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
#endif
#if (BITS_PER_LONG == 64)
typedef __u64 __bitwise __addrpair;
#ifdef __BIG_ENDIAN
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
const __addrpair __name = (__force __addrpair) ( \
(((__force __u64)(__be32)(__saddr)) << 32) | \
((__force __u64)(__be32)(__daddr)));
#else /* __LITTLE_ENDIAN */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
const __addrpair __name = (__force __addrpair) ( \
(((__force __u64)(__be32)(__daddr)) << 32) | \
((__force __u64)(__be32)(__saddr)));
#endif /* __BIG_ENDIAN */
#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
(((__sk)->sk_hash == (__hash)) && \
((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
(((__sk)->sk_hash == (__hash)) && \
((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr)
#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
(((__sk)->sk_hash == (__hash)) && \
(inet_sk(__sk)->daddr == (__saddr)) && \
(inet_sk(__sk)->rcv_saddr == (__daddr)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
(((__sk)->sk_hash == (__hash)) && \
(inet_twsk(__sk)->tw_daddr == (__saddr)) && \
(inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \
((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#endif /* 64-bit arch */
/*
* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
* not check it for lookups anymore, thanks Alexey. -DaveM
*
* Local BH must be disabled here.
*/
static inline struct sock *
__inet_lookup_established(struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum,
const int dif)
{
INET_ADDR_COOKIE(acookie, saddr, daddr)
const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
struct sock *sk;
const struct hlist_node *node;
/* Optimize here for direct hit, only listening connections can
* have wildcards anyways.
*/
unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
prefetch(head->chain.first);
read_lock(&head->lock);
sk_for_each(sk, node, &head->chain) {
if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
goto hit; /* You sunk my battleship! */
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
sk_for_each(sk, node, &head->twchain) {
if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
goto hit;
}
sk = NULL;
out:
read_unlock(&head->lock);
return sk;
hit:
sock_hold(sk);
goto out;
}
static inline struct sock *
inet_lookup_established(struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
return __inet_lookup_established(hashinfo, saddr, sport, daddr,
ntohs(dport), dif);
}
static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
u16 hnum = ntohs(dport);
struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
hnum, dif);
return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif);
}
static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
struct sock *sk;
local_bh_disable();
sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif);
local_bh_enable();
return sk;
}
extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk);
#endif /* _INET_HASHTABLES_H */

190
include/net/inet_sock.h Normal file
View File

@@ -0,0 +1,190 @@
/*
* 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 inet_sock
*
* Authors: Many, reorganised here by
* Arnaldo Carvalho de Melo <acme@mandriva.com>
*
* 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 _INET_SOCK_H
#define _INET_SOCK_H
#include <linux/string.h>
#include <linux/types.h>
#include <net/flow.h>
#include <net/sock.h>
#include <net/request_sock.h>
/** struct ip_options - IP Options
*
* @faddr - Saved first hop address
* @is_data - Options in __data, rather than skb
* @is_strictroute - Strict source route
* @srr_is_hit - Packet destination addr was our one
* @is_changed - IP checksum more not valid
* @rr_needaddr - Need to record addr of outgoing dev
* @ts_needtime - Need to record timestamp
* @ts_needaddr - Need to record addr of outgoing dev
*/
struct ip_options {
__be32 faddr;
unsigned char optlen;
unsigned char srr;
unsigned char rr;
unsigned char ts;
unsigned char is_data:1,
is_strictroute:1,
srr_is_hit:1,
is_changed:1,
rr_needaddr:1,
ts_needtime:1,
ts_needaddr:1;
unsigned char router_alert;
unsigned char cipso;
unsigned char __pad2;
unsigned char __data[0];
};
#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
struct inet_request_sock {
struct request_sock req;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
u16 inet6_rsk_offset;
/* 2 bytes hole, try to pack */
#endif
__be32 loc_addr;
__be32 rmt_addr;
__be16 rmt_port;
u16 snd_wscale : 4,
rcv_wscale : 4,
tstamp_ok : 1,
sack_ok : 1,
wscale_ok : 1,
ecn_ok : 1,
acked : 1;
struct ip_options *opt;
};
static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
{
return (struct inet_request_sock *)sk;
}
struct ip_mc_socklist;
struct ipv6_pinfo;
struct rtable;
/** struct inet_sock - representation of INET sockets
*
* @sk - ancestor class
* @pinet6 - pointer to IPv6 control block
* @daddr - Foreign IPv4 addr
* @rcv_saddr - Bound local IPv4 addr
* @dport - Destination port
* @num - Local port
* @saddr - Sending source
* @uc_ttl - Unicast TTL
* @sport - Source port
* @id - ID counter for DF pkts
* @tos - TOS
* @mc_ttl - Multicasting TTL
* @is_icsk - is this an inet_connection_sock?
* @mc_index - Multicast device index
* @mc_list - Group array
* @cork - info to build ip hdr on each ip frag while socket is corked
*/
struct inet_sock {
/* sk and pinet6 has to be the first two members of inet_sock */
struct sock sk;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct ipv6_pinfo *pinet6;
#endif
/* Socket demultiplex comparisons on incoming packets. */
__be32 daddr;
__be32 rcv_saddr;
__be16 dport;
__u16 num;
__be32 saddr;
__s16 uc_ttl;
__u16 cmsg_flags;
struct ip_options *opt;
__be16 sport;
__u16 id;
__u8 tos;
__u8 mc_ttl;
__u8 pmtudisc;
__u8 recverr:1,
is_icsk:1,
freebind:1,
hdrincl:1,
mc_loop:1;
int mc_index;
__be32 mc_addr;
struct ip_mc_socklist *mc_list;
struct {
unsigned int flags;
unsigned int fragsize;
struct ip_options *opt;
struct rtable *rt;
int length; /* Total length of all frames */
__be32 addr;
struct flowi fl;
} cork;
};
#define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */
#define IPCORK_ALLFRAG 2 /* always fragment (for ipv6 for now) */
static inline struct inet_sock *inet_sk(const struct sock *sk)
{
return (struct inet_sock *)sk;
}
static inline void __inet_sk_copy_descendant(struct sock *sk_to,
const struct sock *sk_from,
const int ancestor_size)
{
memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
sk_from->sk_prot->obj_size - ancestor_size);
}
#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
static inline void inet_sk_copy_descendant(struct sock *sk_to,
const struct sock *sk_from)
{
__inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
}
#endif
extern int inet_sk_rebuild_header(struct sock *sk);
static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
const __be32 faddr, const __be16 fport)
{
unsigned int h = ((__force __u32)laddr ^ lport) ^ ((__force __u32)faddr ^ (__force __u32)fport);
h ^= h >> 16;
h ^= h >> 8;
return h;
}
static inline int inet_sk_ehashfn(const struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const __be32 laddr = inet->rcv_saddr;
const __u16 lport = inet->num;
const __be32 faddr = inet->daddr;
const __be16 fport = inet->dport;
return inet_ehashfn(laddr, lport, faddr, fport);
}
#endif /* _INET_SOCK_H */

View File

@@ -0,0 +1,224 @@
/*
* 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 a generic INET TIMEWAIT sock
*
* From code originally in net/tcp.h
*
* 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 _INET_TIMEWAIT_SOCK_
#define _INET_TIMEWAIT_SOCK_
#include <linux/list.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <net/inet_sock.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <net/timewait_sock.h>
#include <asm/atomic.h>
struct inet_hashinfo;
#define INET_TWDR_RECYCLE_SLOTS_LOG 5
#define INET_TWDR_RECYCLE_SLOTS (1 << INET_TWDR_RECYCLE_SLOTS_LOG)
/*
* If time > 4sec, it is "slow" path, no recycling is required,
* so that we select tick to get range about 4 seconds.
*/
#if HZ <= 16 || HZ > 4096
# error Unsupported: HZ <= 16 or HZ > 4096
#elif HZ <= 32
# define INET_TWDR_RECYCLE_TICK (5 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#elif HZ <= 64
# define INET_TWDR_RECYCLE_TICK (6 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#elif HZ <= 128
# define INET_TWDR_RECYCLE_TICK (7 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#elif HZ <= 256
# define INET_TWDR_RECYCLE_TICK (8 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#elif HZ <= 512
# define INET_TWDR_RECYCLE_TICK (9 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#elif HZ <= 1024
# define INET_TWDR_RECYCLE_TICK (10 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#elif HZ <= 2048
# define INET_TWDR_RECYCLE_TICK (11 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#else
# define INET_TWDR_RECYCLE_TICK (12 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
#endif
/* TIME_WAIT reaping mechanism. */
#define INET_TWDR_TWKILL_SLOTS 8 /* Please keep this a power of 2. */
#define INET_TWDR_TWKILL_QUOTA 100
struct inet_timewait_death_row {
/* Short-time timewait calendar */
int twcal_hand;
unsigned long twcal_jiffie;
struct timer_list twcal_timer;
struct hlist_head twcal_row[INET_TWDR_RECYCLE_SLOTS];
spinlock_t death_lock;
int tw_count;
int period;
u32 thread_slots;
struct work_struct twkill_work;
struct timer_list tw_timer;
int slot;
struct hlist_head cells[INET_TWDR_TWKILL_SLOTS];
struct inet_hashinfo *hashinfo;
int sysctl_tw_recycle;
int sysctl_max_tw_buckets;
};
extern void inet_twdr_hangman(unsigned long data);
extern void inet_twdr_twkill_work(struct work_struct *work);
extern void inet_twdr_twcal_tick(unsigned long data);
#if (BITS_PER_LONG == 64)
#define INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES 8
#else
#define INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES 4
#endif
struct inet_bind_bucket;
/*
* This is a TIME_WAIT sock. It works around the memory consumption
* problems of sockets in such a state on heavily loaded servers, but
* without violating the protocol specification.
*/
struct inet_timewait_sock {
/*
* Now struct sock also uses sock_common, so please just
* don't add nothing before this first member (__tw_common) --acme
*/
struct sock_common __tw_common;
#define tw_family __tw_common.skc_family
#define tw_state __tw_common.skc_state
#define tw_reuse __tw_common.skc_reuse
#define tw_bound_dev_if __tw_common.skc_bound_dev_if
#define tw_node __tw_common.skc_node
#define tw_bind_node __tw_common.skc_bind_node
#define tw_refcnt __tw_common.skc_refcnt
#define tw_hash __tw_common.skc_hash
#define tw_prot __tw_common.skc_prot
volatile unsigned char tw_substate;
/* 3 bits hole, try to pack */
unsigned char tw_rcv_wscale;
/* Socket demultiplex comparisons on incoming packets. */
/* these five are in inet_sock */
__be16 tw_sport;
__be32 tw_daddr __attribute__((aligned(INET_TIMEWAIT_ADDRCMP_ALIGN_BYTES)));
__be32 tw_rcv_saddr;
__be16 tw_dport;
__u16 tw_num;
/* And these are ours. */
__u8 tw_ipv6only:1;
/* 15 bits hole, try to pack */
__u16 tw_ipv6_offset;
int tw_timeout;
unsigned long tw_ttd;
struct inet_bind_bucket *tw_tb;
struct hlist_node tw_death_node;
};
static inline void inet_twsk_add_node(struct inet_timewait_sock *tw,
struct hlist_head *list)
{
hlist_add_head(&tw->tw_node, list);
}
static inline void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
struct hlist_head *list)
{
hlist_add_head(&tw->tw_bind_node, list);
}
static inline int inet_twsk_dead_hashed(const struct inet_timewait_sock *tw)
{
return !hlist_unhashed(&tw->tw_death_node);
}
static inline void inet_twsk_dead_node_init(struct inet_timewait_sock *tw)
{
tw->tw_death_node.pprev = NULL;
}
static inline void __inet_twsk_del_dead_node(struct inet_timewait_sock *tw)
{
__hlist_del(&tw->tw_death_node);
inet_twsk_dead_node_init(tw);
}
static inline int inet_twsk_del_dead_node(struct inet_timewait_sock *tw)
{
if (inet_twsk_dead_hashed(tw)) {
__inet_twsk_del_dead_node(tw);
return 1;
}
return 0;
}
#define inet_twsk_for_each(tw, node, head) \
hlist_for_each_entry(tw, node, head, tw_node)
#define inet_twsk_for_each_inmate(tw, node, jail) \
hlist_for_each_entry(tw, node, jail, tw_death_node)
#define inet_twsk_for_each_inmate_safe(tw, node, safe, jail) \
hlist_for_each_entry_safe(tw, node, safe, jail, tw_death_node)
static inline struct inet_timewait_sock *inet_twsk(const struct sock *sk)
{
return (struct inet_timewait_sock *)sk;
}
static inline __be32 inet_rcv_saddr(const struct sock *sk)
{
return likely(sk->sk_state != TCP_TIME_WAIT) ?
inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
}
static inline void inet_twsk_put(struct inet_timewait_sock *tw)
{
if (atomic_dec_and_test(&tw->tw_refcnt)) {
struct module *owner = tw->tw_prot->owner;
twsk_destructor((struct sock *)tw);
#ifdef SOCK_REFCNT_DEBUG
printk(KERN_DEBUG "%s timewait_sock %p released\n",
tw->tw_prot->name, tw);
#endif
kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
module_put(owner);
}
}
extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
const int state);
extern void __inet_twsk_kill(struct inet_timewait_sock *tw,
struct inet_hashinfo *hashinfo);
extern void __inet_twsk_hashdance(struct inet_timewait_sock *tw,
struct sock *sk,
struct inet_hashinfo *hashinfo);
extern void inet_twsk_schedule(struct inet_timewait_sock *tw,
struct inet_timewait_death_row *twdr,
const int timeo, const int timewait_len);
extern void inet_twsk_deschedule(struct inet_timewait_sock *tw,
struct inet_timewait_death_row *twdr);
#endif /* _INET_TIMEWAIT_SOCK_ */

55
include/net/inetpeer.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* INETPEER - A storage for permanent information about peers
*
* Version: $Id: inetpeer.h,v 1.1.1.1 2007/06/12 07:27:16 eyryu Exp $
*
* Authors: Andrey V. Savochkin <saw@msu.ru>
*/
#ifndef _NET_INETPEER_H
#define _NET_INETPEER_H
#include <linux/types.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
struct inet_peer
{
/* group together avl_left,avl_right,v4daddr to speedup lookups */
struct inet_peer *avl_left, *avl_right;
__be32 v4daddr; /* peer's address */
__u16 avl_height;
__u16 ip_id_count; /* IP ID for the next packet */
struct inet_peer *unused_next, **unused_prevp;
__u32 dtime; /* the time of last use of not
* referenced entries */
atomic_t refcnt;
atomic_t rid; /* Frag reception counter */
__u32 tcp_ts;
unsigned long tcp_ts_stamp;
};
void inet_initpeers(void) __init;
/* can be called with or without local BH being disabled */
struct inet_peer *inet_getpeer(__be32 daddr, int create);
/* can be called from BH context or outside */
extern void inet_putpeer(struct inet_peer *p);
extern spinlock_t inet_peer_idlock;
/* can be called with or without local BH being disabled */
static inline __u16 inet_getid(struct inet_peer *p, int more)
{
__u16 id;
spin_lock_bh(&inet_peer_idlock);
id = p->ip_id_count;
p->ip_id_count += 1 + more;
spin_unlock_bh(&inet_peer_idlock);
return id;
}
#endif /* _NET_INETPEER_H */

386
include/net/ip.h Normal file
View File

@@ -0,0 +1,386 @@
/*
* 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
*
* Authors: Ross Biro
* 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>
#include <net/inet_sock.h>
#include <net/snmp.h>
struct sock;
struct inet_skb_parm
{
struct ip_options opt; /* Compiled IP options */
unsigned char flags;
#define IPSKB_FORWARDED 1
#define IPSKB_XFRM_TUNNEL_SIZE 2
#define IPSKB_XFRM_TRANSFORMED 4
#define IPSKB_FRAG_COMPLETE 8
#define IPSKB_REROUTED 16
};
struct ipcm_cookie
{
__be32 addr;
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 */
struct msghdr;
struct net_device;
struct packet_type;
struct rtable;
struct sk_buff;
struct sockaddr;
extern void ip_mc_dropsocket(struct sock *);
extern void ip_mc_dropdevice(struct net_device *dev);
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,
__be32 saddr, __be32 daddr,
struct ip_options *opt);
extern int ip_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
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);
extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
extern int ip_do_nat(struct sk_buff *skb);
extern void ip_send_check(struct iphdr *ip);
extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok);
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.
*/
static inline void ip_tr_mc_map(__be32 addr, char *buf)
{
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];
__wsum csum;
int csumoffset; /* u16 offset of csum in iov[0].iov_base */
/* -1 if not needed */
};
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);
#define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field)
#define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field)
#define IP_INC_STATS_USER(field) SNMP_INC_STATS_USER(ip_statistics, field)
DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
#define NET_INC_STATS(field) SNMP_INC_STATS(net_statistics, field)
#define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field)
#define NET_INC_STATS_USER(field) SNMP_INC_STATS_USER(net_statistics, field)
#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)
extern int sysctl_local_port_range[2];
extern int sysctl_ip_default_ttl;
extern int sysctl_ip_nonlocal_bind;
/* From ip_fragment.c */
extern int sysctl_ipfrag_high_thresh;
extern int sysctl_ipfrag_low_thresh;
extern int sysctl_ipfrag_time;
extern int sysctl_ipfrag_secret_interval;
extern int sysctl_ipfrag_max_dist;
/* 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);
#ifdef CONFIG_INET
#include <net/dst.h>
/* 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)
{
u32 check = (__force u32)iph->check;
check += (__force u32)htons(0x0100);
iph->check = (__force __sum16)(check + (check>=0xFFFF));
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 &&
!(dst_metric(dst, RTAX_LOCK)&(1<<RTAX_MTU))));
}
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.
*/
static inline void ip_eth_mc_map(__be32 naddr, char *buf)
{
__u32 addr=ntohl(naddr);
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.
*/
static inline void ip_ib_mc_map(__be32 naddr, char *buf)
{
__u32 addr;
buf[0] = 0; /* Reserved */
buf[1] = 0xff; /* Multicast QPN */
buf[2] = 0xff;
buf[3] = 0xff;
addr = ntohl(naddr);
buf[4] = 0xff;
buf[5] = 0x12; /* link local scope */
buf[6] = 0x40; /* IPv4 signature */
buf[7] = 0x1b;
buf[8] = 0; /* P_Key */
buf[9] = 0;
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);
/*
* Functions provided by ip_fragment.o
*/
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
};
struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
extern int ip_frag_nqueues;
extern atomic_t ip_frag_mem;
/*
* Functions provided by ip_forward.c
*/
extern int ip_forward(struct sk_buff *skb);
extern int ip_net_unreachable(struct sk_buff *skb);
/*
* Functions provided by ip_options.c
*/
extern void ip_options_build(struct sk_buff *skb, struct ip_options *opt, __be32 daddr, struct rtable *rt, int is_frag);
extern int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb);
extern void ip_options_fragment(struct sk_buff *skb);
extern int ip_options_compile(struct ip_options *opt, struct sk_buff *skb);
extern int ip_options_get(struct ip_options **optp,
unsigned char *data, int optlen);
extern int ip_options_get_from_user(struct ip_options **optp,
unsigned char __user *data, int optlen);
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);
extern int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc);
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);
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);
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,
__be16 port, u32 info, u8 *payload);
extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
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,
void __user *newval, size_t newlen);
#ifdef CONFIG_PROC_FS
extern int ip_misc_proc_init(void);
#endif
extern struct ctl_table ipv4_table[];
#endif /* _IP_H */

View File

@@ -0,0 +1,94 @@
/*
* 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.
*
* Checksumming functions for IPv6
*
* Authors: Jorge Cwik, <jorge@laser.satlink.net>
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
* Borrows very liberally from tcp.c and ip.c, see those
* files for more names.
*
* 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.
*/
/*
* Fixes:
*
* Ralf Baechle : generic ipv6 checksum
* <ralf@waldorf-gmbh.de>
*/
#ifndef _CHECKSUM_IPV6_H
#define _CHECKSUM_IPV6_H
#include <asm/types.h>
#include <asm/byteorder.h>
#include <net/ip.h>
#include <asm/checksum.h>
#include <linux/in6.h>
#ifndef _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum csum)
{
int carry;
__u32 ulen;
__u32 uproto;
__u32 sum = (__force u32)csum;
sum += (__force u32)saddr->s6_addr32[0];
carry = (sum < (__force u32)saddr->s6_addr32[0]);
sum += carry;
sum += (__force u32)saddr->s6_addr32[1];
carry = (sum < (__force u32)saddr->s6_addr32[1]);
sum += carry;
sum += (__force u32)saddr->s6_addr32[2];
carry = (sum < (__force u32)saddr->s6_addr32[2]);
sum += carry;
sum += (__force u32)saddr->s6_addr32[3];
carry = (sum < (__force u32)saddr->s6_addr32[3]);
sum += carry;
sum += (__force u32)daddr->s6_addr32[0];
carry = (sum < (__force u32)daddr->s6_addr32[0]);
sum += carry;
sum += (__force u32)daddr->s6_addr32[1];
carry = (sum < (__force u32)daddr->s6_addr32[1]);
sum += carry;
sum += (__force u32)daddr->s6_addr32[2];
carry = (sum < (__force u32)daddr->s6_addr32[2]);
sum += carry;
sum += (__force u32)daddr->s6_addr32[3];
carry = (sum < (__force u32)daddr->s6_addr32[3]);
sum += carry;
ulen = (__force u32)htonl((__u32) len);
sum += ulen;
carry = (sum < ulen);
sum += carry;
uproto = (__force u32)htonl(proto);
sum += uproto;
carry = (sum < uproto);
sum += carry;
return csum_fold((__force __wsum)sum);
}
#endif
#endif

226
include/net/ip6_fib.h Normal file
View File

@@ -0,0 +1,226 @@
/*
* Linux INET6 implementation
*
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
* 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 _IP6_FIB_H
#define _IP6_FIB_H
#ifdef __KERNEL__
#include <linux/ipv6_route.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
#include <net/dst.h>
#include <net/flow.h>
#include <net/netlink.h>
struct rt6_info;
struct fib6_config
{
u32 fc_table;
u32 fc_metric;
int fc_dst_len;
int fc_src_len;
int fc_ifindex;
u32 fc_flags;
u32 fc_protocol;
struct in6_addr fc_dst;
struct in6_addr fc_src;
struct in6_addr fc_gateway;
unsigned long fc_expires;
struct nlattr *fc_mx;
int fc_mx_len;
struct nl_info fc_nlinfo;
};
struct fib6_node
{
struct fib6_node *parent;
struct fib6_node *left;
struct fib6_node *right;
#ifdef CONFIG_IPV6_SUBTREES
struct fib6_node *subtree;
#endif
struct rt6_info *leaf;
__u16 fn_bit; /* bit key */
__u16 fn_flags;
__u32 fn_sernum;
struct rt6_info *rr_ptr;
};
#ifndef CONFIG_IPV6_SUBTREES
#define FIB6_SUBTREE(fn) NULL
#else
#define FIB6_SUBTREE(fn) ((fn)->subtree)
#endif
/*
* routing information
*
*/
struct rt6key
{
struct in6_addr addr;
int plen;
};
struct fib6_table;
struct rt6_info
{
union {
struct dst_entry dst;
} u;
struct inet6_dev *rt6i_idev;
#define rt6i_dev u.dst.dev
#define rt6i_nexthop u.dst.neighbour
#define rt6i_expires u.dst.expires
struct fib6_node *rt6i_node;
struct in6_addr rt6i_gateway;
u32 rt6i_flags;
u32 rt6i_metric;
atomic_t rt6i_ref;
struct fib6_table *rt6i_table;
struct rt6key rt6i_dst;
struct rt6key rt6i_src;
u8 rt6i_protocol;
};
static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
{
return ((struct rt6_info *)dst)->rt6i_idev;
}
struct fib6_walker_t
{
struct fib6_walker_t *prev, *next;
struct fib6_node *root, *node;
struct rt6_info *leaf;
unsigned char state;
unsigned char prune;
int (*func)(struct fib6_walker_t *);
void *args;
};
struct rt6_statistics {
__u32 fib_nodes;
__u32 fib_route_nodes;
__u32 fib_rt_alloc; /* permanent routes */
__u32 fib_rt_entries; /* rt entries in table */
__u32 fib_rt_cache; /* cache routes */
__u32 fib_discarded_routes;
};
#define RTN_TL_ROOT 0x0001
#define RTN_ROOT 0x0002 /* tree root node */
#define RTN_RTINFO 0x0004 /* node with valid routing info */
/*
* priority levels (or metrics)
*
*/
#define RTPRI_FIREWALL 8 /* Firewall control information */
#define RTPRI_FLOW 16 /* Flow based forwarding rules */
#define RTPRI_KERN_CTL 32 /* Kernel control routes */
#define RTPRI_USER_MIN 256 /* Mimimum user priority */
#define RTPRI_USER_MAX 1024 /* Maximum user priority */
#define RTPRI_KERN_DFLT 4096 /* Kernel default routes */
#define MAX_FLOW_BACKTRACE 32
typedef void (*f_pnode)(struct fib6_node *fn, void *);
struct fib6_table {
struct hlist_node tb6_hlist;
u32 tb6_id;
rwlock_t tb6_lock;
struct fib6_node tb6_root;
};
#define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC
#define RT6_TABLE_MAIN RT_TABLE_MAIN
#define RT6_TABLE_DFLT RT6_TABLE_MAIN
#define RT6_TABLE_INFO RT6_TABLE_MAIN
#define RT6_TABLE_PREFIX RT6_TABLE_MAIN
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
#define FIB6_TABLE_MIN 1
#define FIB6_TABLE_MAX RT_TABLE_MAX
#define RT6_TABLE_LOCAL RT_TABLE_LOCAL
#else
#define FIB6_TABLE_MIN RT_TABLE_MAIN
#define FIB6_TABLE_MAX FIB6_TABLE_MIN
#define RT6_TABLE_LOCAL RT6_TABLE_MAIN
#endif
typedef struct rt6_info *(*pol_lookup_t)(struct fib6_table *,
struct flowi *, int);
/*
* exported functions
*/
extern struct fib6_table * fib6_get_table(u32 id);
extern struct fib6_table * fib6_new_table(u32 id);
extern struct dst_entry * fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup);
extern struct fib6_node *fib6_lookup(struct fib6_node *root,
struct in6_addr *daddr,
struct in6_addr *saddr);
struct fib6_node *fib6_locate(struct fib6_node *root,
struct in6_addr *daddr, int dst_len,
struct in6_addr *saddr, int src_len);
extern void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
int prune, void *arg);
extern int fib6_add(struct fib6_node *root,
struct rt6_info *rt,
struct nl_info *info);
extern int fib6_del(struct rt6_info *rt,
struct nl_info *info);
extern void inet6_rt_notify(int event, struct rt6_info *rt,
struct nl_info *info);
extern void fib6_run_gc(unsigned long dummy);
extern void fib6_gc_cleanup(void);
extern void fib6_init(void);
extern void fib6_rules_init(void);
extern void fib6_rules_cleanup(void);
extern int fib6_rules_dump(struct sk_buff *,
struct netlink_callback *);
#endif
#endif

171
include/net/ip6_route.h Normal file
View File

@@ -0,0 +1,171 @@
#ifndef _NET_IP6_ROUTE_H
#define _NET_IP6_ROUTE_H
#define IP6_RT_PRIO_FW 16
#define IP6_RT_PRIO_USER 1024
#define IP6_RT_PRIO_ADDRCONF 256
#define IP6_RT_PRIO_KERN 512
#define IP6_RT_FLOW_MASK 0x00ff
struct route_info {
__u8 type;
__u8 length;
__u8 prefix_len;
#if defined(__BIG_ENDIAN_BITFIELD)
__u8 reserved_h:3,
route_pref:2,
reserved_l:3;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
__u8 reserved_l:3,
route_pref:2,
reserved_h:3;
#endif
__be32 lifetime;
__u8 prefix[0]; /* 0,8 or 16 */
};
#ifdef __KERNEL__
#include <net/flow.h>
#include <net/ip6_fib.h>
#include <net/sock.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#define RT6_LOOKUP_F_IFACE 0x1
#define RT6_LOOKUP_F_REACHABLE 0x2
#define RT6_LOOKUP_F_HAS_SADDR 0x4
extern struct rt6_info ip6_null_entry;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
extern struct rt6_info ip6_prohibit_entry;
extern struct rt6_info ip6_blk_hole_entry;
#endif
extern int ip6_rt_gc_interval;
extern void ip6_route_input(struct sk_buff *skb);
extern struct dst_entry * ip6_route_output(struct sock *sk,
struct flowi *fl);
extern void ip6_route_init(void);
extern void ip6_route_cleanup(void);
extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg);
extern int ip6_route_add(struct fib6_config *cfg);
extern int ip6_ins_rt(struct rt6_info *);
extern int ip6_del_rt(struct rt6_info *);
extern int ip6_rt_addr_add(struct in6_addr *addr,
struct net_device *dev,
int anycast);
extern int ip6_rt_addr_del(struct in6_addr *addr,
struct net_device *dev);
extern void rt6_sndmsg(int type, struct in6_addr *dst,
struct in6_addr *src,
struct in6_addr *gw,
struct net_device *dev,
int dstlen, int srclen,
int metric, __u32 flags);
extern struct rt6_info *rt6_lookup(struct in6_addr *daddr,
struct in6_addr *saddr,
int oif, int flags);
extern struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
struct neighbour *neigh,
struct in6_addr *addr,
int (*output)(struct sk_buff *));
extern int ndisc_dst_gc(int *more);
extern void fib6_force_start_gc(void);
extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
const struct in6_addr *addr,
int anycast);
/*
* support functions for ND
*
*/
extern struct rt6_info * rt6_get_dflt_router(struct in6_addr *addr,
struct net_device *dev);
extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr,
struct net_device *dev,
unsigned int pref);
extern void rt6_purge_dflt_routers(void);
extern int rt6_route_rcv(struct net_device *dev,
u8 *opt, int len,
struct in6_addr *gwaddr);
extern void rt6_redirect(struct in6_addr *dest,
struct in6_addr *src,
struct in6_addr *saddr,
struct neighbour *neigh,
u8 *lladdr,
int on_link);
extern void rt6_pmtu_discovery(struct in6_addr *daddr,
struct in6_addr *saddr,
struct net_device *dev,
u32 pmtu);
struct nlmsghdr;
struct netlink_callback;
extern int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
extern int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet6_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
struct rt6_rtnl_dump_arg
{
struct sk_buff *skb;
struct netlink_callback *cb;
};
extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
extern void rt6_ifdown(struct net_device *dev);
extern void rt6_mtu_change(struct net_device *dev, unsigned mtu);
extern rwlock_t rt6_lock;
/*
* Store a destination cache entry in a socket
*/
static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
struct in6_addr *daddr, struct in6_addr *saddr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *) dst;
sk_setup_caps(sk, dst);
np->daddr_cache = daddr;
#ifdef CONFIG_IPV6_SUBTREES
np->saddr_cache = saddr;
#endif
np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
}
static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
struct in6_addr *daddr, struct in6_addr *saddr)
{
write_lock(&sk->sk_dst_lock);
__ip6_dst_store(sk, dst, daddr, saddr);
write_unlock(&sk->sk_dst_lock);
}
static inline int ipv6_unicast_destination(struct sk_buff *skb)
{
struct rt6_info *rt = (struct rt6_info *) skb->dst;
return rt->rt6i_flags & RTF_LOCAL;
}
#endif
#endif

40
include/net/ip6_tunnel.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* $Id: ip6_tunnel.h,v 1.1.1.1 2007/06/12 07:27:16 eyryu Exp $
*/
#ifndef _NET_IP6_TUNNEL_H
#define _NET_IP6_TUNNEL_H
#include <linux/ipv6.h>
#include <linux/netdevice.h>
#include <linux/ip6_tunnel.h>
/* capable of sending packets */
#define IP6_TNL_F_CAP_XMIT 0x10000
/* capable of receiving packets */
#define IP6_TNL_F_CAP_RCV 0x20000
#define IP6_TNL_MAX 128
/* IPv6 tunnel */
struct ip6_tnl {
struct ip6_tnl *next; /* next tunnel in list */
struct net_device *dev; /* virtual device associated with tunnel */
struct net_device_stats stat; /* statistics for tunnel device */
int recursion; /* depth of hard_start_xmit recursion */
struct ip6_tnl_parm parms; /* tunnel configuration paramters */
struct flowi fl; /* flowi template for xmit */
struct dst_entry *dst_cache; /* cached dst */
u32 dst_cookie;
};
/* Tunnel encapsulation limit destination sub-option */
struct ipv6_tlv_tnl_enc_lim {
__u8 type; /* type-code for option */
__u8 length; /* option length */
__u8 encap_limit; /* tunnel encapsulation limit */
} __attribute__ ((packed));
#endif

287
include/net/ip_fib.h Normal file
View File

@@ -0,0 +1,287 @@
/*
* 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 Forwarding Information Base.
*
* Authors: A.N.Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
* 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 _NET_IP_FIB_H
#define _NET_IP_FIB_H
#include <net/flow.h>
#include <linux/seq_file.h>
#include <net/fib_rules.h>
struct fib_config {
u8 fc_dst_len;
u8 fc_tos;
u8 fc_protocol;
u8 fc_scope;
u8 fc_type;
/* 3 bytes unused */
u32 fc_table;
__be32 fc_dst;
__be32 fc_gw;
int fc_oif;
u32 fc_flags;
u32 fc_priority;
__be32 fc_prefsrc;
struct nlattr *fc_mx;
struct rtnexthop *fc_mp;
int fc_mx_len;
int fc_mp_len;
u32 fc_flow;
u32 fc_mp_alg;
u32 fc_nlflags;
struct nl_info fc_nlinfo;
};
struct fib_info;
struct fib_nh {
struct net_device *nh_dev;
struct hlist_node nh_hash;
struct fib_info *nh_parent;
unsigned nh_flags;
unsigned char nh_scope;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int nh_weight;
int nh_power;
#endif
#ifdef CONFIG_NET_CLS_ROUTE
__u32 nh_tclassid;
#endif
int nh_oif;
__be32 nh_gw;
};
/*
* This structure contains data shared by many of routes.
*/
struct fib_info {
struct hlist_node fib_hash;
struct hlist_node fib_lhash;
int fib_treeref;
atomic_t fib_clntref;
int fib_dead;
unsigned fib_flags;
int fib_protocol;
__be32 fib_prefsrc;
u32 fib_priority;
u32 fib_metrics[RTAX_MAX];
#define fib_mtu fib_metrics[RTAX_MTU-1]
#define fib_window fib_metrics[RTAX_WINDOW-1]
#define fib_rtt fib_metrics[RTAX_RTT-1]
#define fib_advmss fib_metrics[RTAX_ADVMSS-1]
int fib_nhs;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power;
#endif
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
u32 fib_mp_alg;
#endif
struct fib_nh fib_nh[0];
#define fib_dev fib_nh[0].nh_dev
};
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule;
#endif
struct fib_result {
unsigned char prefixlen;
unsigned char nh_sel;
unsigned char type;
unsigned char scope;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
__be32 network;
__be32 netmask;
#endif
struct fib_info *fi;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule *r;
#endif
};
struct fib_result_nl {
__be32 fl_addr; /* To be looked up*/
u32 fl_mark;
unsigned char fl_tos;
unsigned char fl_scope;
unsigned char tb_id_in;
unsigned char tb_id; /* Results */
unsigned char prefixlen;
unsigned char nh_sel;
unsigned char type;
unsigned char scope;
int err;
};
#ifdef CONFIG_IP_ROUTE_MULTIPATH
#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
#define FIB_RES_RESET(res) ((res).nh_sel = 0)
#else /* CONFIG_IP_ROUTE_MULTIPATH */
#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
#define FIB_RES_RESET(res)
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
#define FIB_RES_NETWORK(res) ((res).network)
#define FIB_RES_NETMASK(res) ((res).netmask)
#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
#define FIB_RES_NETWORK(res) (0)
#define FIB_RES_NETMASK(res) (0)
#endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
unsigned tb_stamp;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *, struct fib_config *);
int (*tb_delete)(struct fib_table *, struct fib_config *);
int (*tb_dump)(struct fib_table *table, struct sk_buff *skb,
struct netlink_callback *cb);
int (*tb_flush)(struct fib_table *table);
void (*tb_select_default)(struct fib_table *table,
const struct flowi *flp, struct fib_result *res);
unsigned char tb_data[0];
};
#ifndef CONFIG_IP_MULTIPLE_TABLES
extern struct fib_table *ip_fib_local_table;
extern struct fib_table *ip_fib_main_table;
static inline struct fib_table *fib_get_table(u32 id)
{
if (id != RT_TABLE_LOCAL)
return ip_fib_main_table;
return ip_fib_local_table;
}
static inline struct fib_table *fib_new_table(u32 id)
{
return fib_get_table(id);
}
static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
{
if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
return -ENETUNREACH;
return 0;
}
static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
{
if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
}
#else /* CONFIG_IP_MULTIPLE_TABLES */
#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
extern int fib_lookup(struct flowi *flp, struct fib_result *res);
extern struct fib_table *fib_new_table(u32 id);
extern struct fib_table *fib_get_table(u32 id);
extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
#endif /* CONFIG_IP_MULTIPLE_TABLES */
/* Exported by fib_frontend.c */
extern struct nla_policy rtm_ipv4_policy[];
extern void ip_fib_init(void);
extern int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
struct net_device *dev, __be32 *spec_dst, u32 *itag);
extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
struct rtentry;
/* Exported by fib_semantics.c */
extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
extern int fib_sync_up(struct net_device *dev);
extern __be32 __fib_res_prefsrc(struct fib_result *res);
/* Exported by fib_hash.c */
extern struct fib_table *fib_hash_init(u32 id);
#ifdef CONFIG_IP_MULTIPLE_TABLES
extern int fib4_rules_dump(struct sk_buff *skb, struct netlink_callback *cb);
extern void __init fib4_rules_init(void);
#ifdef CONFIG_NET_CLS_ROUTE
extern u32 fib_rules_tclass(struct fib_result *res);
#endif
#endif
static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
{
#ifdef CONFIG_NET_CLS_ROUTE
#ifdef CONFIG_IP_MULTIPLE_TABLES
u32 rtag;
#endif
*itag = FIB_RES_NH(*res).nh_tclassid<<16;
#ifdef CONFIG_IP_MULTIPLE_TABLES
rtag = fib_rules_tclass(res);
if (*itag == 0)
*itag = (rtag<<16);
*itag |= (rtag>>16);
#endif
#endif
}
extern void free_fib_info(struct fib_info *fi);
static inline void fib_info_put(struct fib_info *fi)
{
if (atomic_dec_and_test(&fi->fib_clntref))
free_fib_info(fi);
}
static inline void fib_res_put(struct fib_result *res)
{
if (res->fi)
fib_info_put(res->fi);
#ifdef CONFIG_IP_MULTIPLE_TABLES
if (res->r)
fib_rule_put(res->r);
#endif
}
#ifdef CONFIG_PROC_FS
extern int fib_proc_init(void);
extern void fib_proc_exit(void);
#endif
#endif /* _NET_FIB_H */

96
include/net/ip_mp_alg.h Normal file
View File

@@ -0,0 +1,96 @@
/* ip_mp_alg.h: IPV4 multipath algorithm support.
*
* Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
* Copyright (C) 2005 David S. Miller <davem@davemloft.net>
*/
#ifndef _NET_IP_MP_ALG_H
#define _NET_IP_MP_ALG_H
#include <linux/ip_mp_alg.h>
#include <net/flow.h>
#include <net/route.h>
struct fib_nh;
struct ip_mp_alg_ops {
void (*mp_alg_select_route)(const struct flowi *flp,
struct rtable *rth, struct rtable **rp);
void (*mp_alg_flush)(void);
void (*mp_alg_set_nhinfo)(__be32 network, __be32 netmask,
unsigned char prefixlen,
const struct fib_nh *nh);
void (*mp_alg_remove)(struct rtable *rth);
};
extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg);
extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg);
extern struct ip_mp_alg_ops *ip_mp_alg_table[];
static inline int multipath_select_route(const struct flowi *flp,
struct rtable *rth,
struct rtable **rp)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
/* mp_alg_select_route _MUST_ be implemented */
if (ops && (rth->u.dst.flags & DST_BALANCED)) {
ops->mp_alg_select_route(flp, rth, rp);
return 1;
}
#endif
return 0;
}
static inline void multipath_flush(void)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
int i;
for (i = IP_MP_ALG_NONE; i <= IP_MP_ALG_MAX; i++) {
struct ip_mp_alg_ops *ops = ip_mp_alg_table[i];
if (ops && ops->mp_alg_flush)
ops->mp_alg_flush();
}
#endif
}
static inline void multipath_set_nhinfo(struct rtable *rth,
__be32 network, __be32 netmask,
unsigned char prefixlen,
const struct fib_nh *nh)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
if (ops && ops->mp_alg_set_nhinfo)
ops->mp_alg_set_nhinfo(network, netmask, prefixlen, nh);
#endif
}
static inline void multipath_remove(struct rtable *rth)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
if (ops && ops->mp_alg_remove &&
(rth->u.dst.flags & DST_BALANCED))
ops->mp_alg_remove(rth);
#endif
}
static inline int multipath_comparekeys(const struct flowi *flp1,
const struct flowi *flp2)
{
return flp1->fl4_dst == flp2->fl4_dst &&
flp1->fl4_src == flp2->fl4_src &&
flp1->oif == flp2->oif &&
flp1->mark == flp2->mark &&
!((flp1->fl4_tos ^ flp2->fl4_tos) &
(IPTOS_RT_MASK | RTO_ONLINK));
}
#endif /* _NET_IP_MP_ALG_H */

1009
include/net/ip_vs.h Normal file

File diff suppressed because it is too large Load Diff

14
include/net/ipcomp.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef _NET_IPCOMP_H
#define _NET_IPCOMP_H
#include <linux/crypto.h>
#include <linux/types.h>
#define IPCOMP_SCRATCH_SIZE 65400
struct ipcomp_data {
u16 threshold;
struct crypto_comp **tfms;
};
#endif

27
include/net/ipconfig.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* $Id: ipconfig.h,v 1.1.1.1 2007/06/12 07:27:16 eyryu Exp $
*
* Copyright (C) 1997 Martin Mares
*
* Automatic IP Layer Configuration
*/
/* The following are initdata: */
extern int ic_proto_enabled; /* Protocols enabled (see IC_xxx) */
extern int ic_set_manually; /* IPconfig parameters set manually */
extern __be32 ic_myaddr; /* My IP address */
extern __be32 ic_gateway; /* Gateway IP address */
extern __be32 ic_servaddr; /* Boot server IP address */
extern __be32 root_server_addr; /* Address of NFS server */
extern u8 root_server_path[]; /* Path to mount as root */
/* bits in ic_proto_{enabled,used} */
#define IC_PROTO 0xFF /* Protocols mask: */
#define IC_BOOTP 0x01 /* BOOTP (or DHCP, see below) */
#define IC_RARP 0x02 /* RARP */
#define IC_USE_DHCP 0x100 /* If on, use DHCP instead of BOOTP */

47
include/net/ipip.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef __NET_IPIP_H
#define __NET_IPIP_H 1
#include <linux/if_tunnel.h>
/* Keep error state on tunnel for 30 sec */
#define IPTUNNEL_ERR_TIMEO (30*HZ)
struct ip_tunnel
{
struct ip_tunnel *next;
struct net_device *dev;
struct net_device_stats stat;
int recursion; /* Depth of hard_start_xmit recursion */
int err_count; /* Number of arrived ICMP errors */
unsigned long err_time; /* Time when the last ICMP error arrived */
/* These four fields used only by GRE */
__u32 i_seqno; /* The last seen seqno */
__u32 o_seqno; /* The last output seqno */
int hlen; /* Precalculated GRE header length */
int mlink;
struct ip_tunnel_parm parms;
};
#define IPTUNNEL_XMIT() do { \
int err; \
int pkt_len = skb->len; \
\
skb->ip_summed = CHECKSUM_NONE; \
iph->tot_len = htons(skb->len); \
ip_select_ident(iph, &rt->u.dst, NULL); \
ip_send_check(iph); \
\
err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
if (net_xmit_eval(err) == 0) { \
stats->tx_bytes += pkt_len; \
stats->tx_packets++; \
} else { \
stats->tx_errors++; \
stats->tx_aborted_errors++; \
} \
} while (0)
#endif

621
include/net/ipv6.h Normal file
View File

@@ -0,0 +1,621 @@
/*
* Linux INET6 implementation
*
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
* $Id: ipv6.h,v 1.1.1.1 2007/06/12 07:27:16 eyryu Exp $
*
* 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 _NET_IPV6_H
#define _NET_IPV6_H
#include <linux/ipv6.h>
#include <linux/hardirq.h>
#include <net/ndisc.h>
#include <net/flow.h>
#include <net/snmp.h>
#define SIN6_LEN_RFC2133 24
#define IPV6_MAXPLEN 65535
/*
* NextHeader field of IPv6 header
*/
#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */
#define NEXTHDR_TCP 6 /* TCP segment. */
#define NEXTHDR_UDP 17 /* UDP message. */
#define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */
#define NEXTHDR_ROUTING 43 /* Routing header. */
#define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */
#define NEXTHDR_ESP 50 /* Encapsulating security payload. */
#define NEXTHDR_AUTH 51 /* Authentication header. */
#define NEXTHDR_ICMP 58 /* ICMP for IPv6. */
#define NEXTHDR_NONE 59 /* No next header */
#define NEXTHDR_DEST 60 /* Destination options header. */
#define NEXTHDR_MOBILITY 135 /* Mobility header. */
#define NEXTHDR_MAX 255
#define IPV6_DEFAULT_HOPLIMIT 64
#define IPV6_DEFAULT_MCASTHOPS 1
/*
* Addr type
*
* type - unicast | multicast
* scope - local | site | global
* v4 - compat
* v4mapped
* any
* loopback
*/
#define IPV6_ADDR_ANY 0x0000U
#define IPV6_ADDR_UNICAST 0x0001U
#define IPV6_ADDR_MULTICAST 0x0002U
#define IPV6_ADDR_LOOPBACK 0x0010U
#define IPV6_ADDR_LINKLOCAL 0x0020U
#define IPV6_ADDR_SITELOCAL 0x0040U
#define IPV6_ADDR_COMPATv4 0x0080U
#define IPV6_ADDR_SCOPE_MASK 0x00f0U
#define IPV6_ADDR_MAPPED 0x1000U
#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
/*
* Addr scopes
*/
#ifdef __KERNEL__
#define IPV6_ADDR_MC_SCOPE(a) \
((a)->s6_addr[1] & 0x0f) /* nonstandard */
#define __IPV6_ADDR_SCOPE_INVALID -1
#endif
#define IPV6_ADDR_SCOPE_NODELOCAL 0x01
#define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
#define IPV6_ADDR_SCOPE_SITELOCAL 0x05
#define IPV6_ADDR_SCOPE_ORGLOCAL 0x08
#define IPV6_ADDR_SCOPE_GLOBAL 0x0e
/*
* fragmentation header
*/
struct frag_hdr {
__u8 nexthdr;
__u8 reserved;
__be16 frag_off;
__be32 identification;
};
#define IP6_MF 0x0001
#ifdef __KERNEL__
#include <net/sock.h>
/* sysctls */
extern int sysctl_ipv6_bindv6only;
extern int sysctl_mld_max_msf;
/* MIBs */
DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);
#define IP6_INC_STATS(idev,field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(_idev->stats.ipv6, field); \
SNMP_INC_STATS(ipv6_statistics, field); \
})
#define IP6_INC_STATS_BH(idev,field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS_BH(_idev->stats.ipv6, field); \
SNMP_INC_STATS_BH(ipv6_statistics, field); \
})
#define IP6_INC_STATS_USER(idev,field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS_USER(_idev->stats.ipv6, field); \
SNMP_INC_STATS_USER(ipv6_statistics, field); \
})
DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
#define ICMP6_INC_STATS(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS(idev->stats.icmpv6, field); \
SNMP_INC_STATS(icmpv6_statistics, field); \
})
#define ICMP6_INC_STATS_BH(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS_BH((_idev)->stats.icmpv6, field); \
SNMP_INC_STATS_BH(icmpv6_statistics, field); \
})
#define ICMP6_INC_STATS_USER(idev, field) ({ \
struct inet6_dev *_idev = (idev); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS_USER(_idev->stats.icmpv6, field); \
SNMP_INC_STATS_USER(icmpv6_statistics, field); \
})
#define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \
struct inet6_dev *_idev = idev; \
__typeof__(offset) _offset = (offset); \
if (likely(_idev != NULL)) \
SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \
SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \
})
DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
#define UDP6_INC_STATS_BH(field, is_udplite) do { \
if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field); \
else SNMP_INC_STATS_BH(udp_stats_in6, field); } while(0)
#define UDP6_INC_STATS_USER(field, is_udplite) do { \
if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \
else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0)
int snmp6_register_dev(struct inet6_dev *idev);
int snmp6_unregister_dev(struct inet6_dev *idev);
int snmp6_alloc_dev(struct inet6_dev *idev);
int snmp6_free_dev(struct inet6_dev *idev);
int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
void snmp6_mib_free(void *ptr[2]);
struct ip6_ra_chain
{
struct ip6_ra_chain *next;
struct sock *sk;
int sel;
void (*destructor)(struct sock *);
};
extern struct ip6_ra_chain *ip6_ra_chain;
extern rwlock_t ip6_ra_lock;
/*
This structure is prepared by protocol, when parsing
ancillary data and passed to IPv6.
*/
struct ipv6_txoptions
{
/* Length of this structure */
int tot_len;
/* length of extension headers */
__u16 opt_flen; /* after fragment hdr */
__u16 opt_nflen; /* before fragment hdr */
struct ipv6_opt_hdr *hopopt;
struct ipv6_opt_hdr *dst0opt;
struct ipv6_rt_hdr *srcrt; /* Routing Header */
struct ipv6_opt_hdr *dst1opt;
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
};
struct ip6_flowlabel
{
struct ip6_flowlabel *next;
__be32 label;
struct in6_addr dst;
struct ipv6_txoptions *opt;
atomic_t users;
unsigned long linger;
u8 share;
u32 owner;
unsigned long lastuse;
unsigned long expires;
};
#define IPV6_FLOWINFO_MASK __constant_htonl(0x0FFFFFFF)
#define IPV6_FLOWLABEL_MASK __constant_htonl(0x000FFFFF)
struct ipv6_fl_socklist
{
struct ipv6_fl_socklist *next;
struct ip6_flowlabel *fl;
};
extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label);
extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
struct ip6_flowlabel * fl,
struct ipv6_txoptions * fopt);
extern void fl6_free_socklist(struct sock *sk);
extern int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen);
extern void ip6_flowlabel_init(void);
extern void ip6_flowlabel_cleanup(void);
static inline void fl6_sock_release(struct ip6_flowlabel *fl)
{
if (fl)
atomic_dec(&fl->users);
}
extern int ip6_ra_control(struct sock *sk, int sel,
void (*destructor)(struct sock *));
extern int ipv6_parse_hopopts(struct sk_buff **skbp);
extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
int newtype,
struct ipv6_opt_hdr __user *newopt,
int newoptlen);
struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
struct ipv6_txoptions *opt);
extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
extern int ip6_frag_nqueues;
extern atomic_t ip6_frag_mem;
#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
/*
* Function prototype for build_xmit
*/
typedef int (*inet_getfrag_t) (const void *data,
struct in6_addr *addr,
char *,
unsigned int, unsigned int);
extern int __ipv6_addr_type(const struct in6_addr *addr);
static inline int ipv6_addr_type(const struct in6_addr *addr)
{
return __ipv6_addr_type(addr) & 0xffff;
}
static inline int ipv6_addr_scope(const struct in6_addr *addr)
{
return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
}
static inline int __ipv6_addr_src_scope(int type)
{
return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16));
}
static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
{
return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
}
static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
{
return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr));
}
static inline int
ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
const struct in6_addr *a2)
{
unsigned int i;
for (i = 0; i < 4; i++)
if ((a1->s6_addr32[i] ^ a2->s6_addr32[i]) & m->s6_addr32[i])
return 1;
return 0;
}
static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
{
memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr));
}
static inline void ipv6_addr_prefix(struct in6_addr *pfx,
const struct in6_addr *addr,
int plen)
{
/* caller must guarantee 0 <= plen <= 128 */
int o = plen >> 3,
b = plen & 0x7;
memcpy(pfx->s6_addr, addr, o);
if (b != 0) {
pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
o++;
}
if (o < 16)
memset(pfx->s6_addr + o, 0, 16 - o);
}
#ifndef __HAVE_ARCH_ADDR_SET
static inline void ipv6_addr_set(struct in6_addr *addr,
__be32 w1, __be32 w2,
__be32 w3, __be32 w4)
{
addr->s6_addr32[0] = w1;
addr->s6_addr32[1] = w2;
addr->s6_addr32[2] = w3;
addr->s6_addr32[3] = w4;
}
#endif
static inline int ipv6_addr_equal(const struct in6_addr *a1,
const struct in6_addr *a2)
{
return (a1->s6_addr32[0] == a2->s6_addr32[0] &&
a1->s6_addr32[1] == a2->s6_addr32[1] &&
a1->s6_addr32[2] == a2->s6_addr32[2] &&
a1->s6_addr32[3] == a2->s6_addr32[3]);
}
static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,
unsigned int prefixlen)
{
unsigned pdw, pbi;
/* check complete u32 in prefix */
pdw = prefixlen >> 5;
if (pdw && memcmp(a1, a2, pdw << 2))
return 0;
/* check incomplete u32 in prefix */
pbi = prefixlen & 0x1f;
if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
return 0;
return 1;
}
static inline int ipv6_prefix_equal(const struct in6_addr *a1,
const struct in6_addr *a2,
unsigned int prefixlen)
{
return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32,
prefixlen);
}
static inline int ipv6_addr_any(const struct in6_addr *a)
{
return ((a->s6_addr32[0] | a->s6_addr32[1] |
a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
}
/*
* find the first different bit between two addresses
* length of address must be a multiple of 32bits
*/
static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen)
{
const __be32 *a1 = token1, *a2 = token2;
int i;
addrlen >>= 2;
for (i = 0; i < addrlen; i++) {
__be32 xb = a1[i] ^ a2[i];
if (xb)
return i * 32 + 32 - fls(ntohl(xb));
}
/*
* we should *never* get to this point since that
* would mean the addrs are equal
*
* However, we do get to it 8) And exacly, when
* addresses are equal 8)
*
* ip route add 1111::/128 via ...
* ip route add 1111::/64 via ...
* and we are here.
*
* Ideally, this function should stop comparison
* at prefix length. It does not, but it is still OK,
* if returned value is greater than prefix length.
* --ANK (980803)
*/
return (addrlen << 5);
}
static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2)
{
return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
}
/*
* Prototypes exported by ipv6
*/
/*
* rcv function (called from netdevice level)
*/
extern int ipv6_rcv(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
extern int ip6_rcv_finish(struct sk_buff *skb);
/*
* upper-layer output functions
*/
extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb,
struct flowi *fl,
struct ipv6_txoptions *opt,
int ipfragok);
extern int ip6_nd_hdr(struct sock *sk,
struct sk_buff *skb,
struct net_device *dev,
struct in6_addr *saddr,
struct in6_addr *daddr,
int proto, int len);
extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
extern int ip6_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
void *from,
int length,
int transhdrlen,
int hlimit,
int tclass,
struct ipv6_txoptions *opt,
struct flowi *fl,
struct rt6_info *rt,
unsigned int flags);
extern int ip6_push_pending_frames(struct sock *sk);
extern void ip6_flush_pending_frames(struct sock *sk);
extern int ip6_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);
extern int ip6_sk_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);
/*
* skb processing functions
*/
extern int ip6_output(struct sk_buff *skb);
extern int ip6_forward(struct sk_buff *skb);
extern int ip6_input(struct sk_buff *skb);
extern int ip6_mc_input(struct sk_buff *skb);
/*
* Extension header (options) processing
*/
extern u8 * ipv6_build_nfrag_opts(struct sk_buff *skb,
u8 *prev_hdr,
struct ipv6_txoptions *opt,
struct in6_addr *daddr,
u32 jumbolen);
extern u8 * ipv6_build_frag_opts(struct sk_buff *skb,
u8 *prev_hdr,
struct ipv6_txoptions *opt);
extern void ipv6_push_nfrag_opts(struct sk_buff *skb,
struct ipv6_txoptions *opt,
u8 *proto,
struct in6_addr **daddr_p);
extern void ipv6_push_frag_opts(struct sk_buff *skb,
struct ipv6_txoptions *opt,
u8 *proto);
extern int ipv6_skip_exthdr(const struct sk_buff *, int start,
u8 *nexthdrp);
extern int ipv6_ext_hdr(u8 nexthdr);
extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk,
struct ipv6_rt_hdr *hdr);
/*
* socket options (ipv6_sockglue.c)
*/
extern int ipv6_setsockopt(struct sock *sk, int level,
int optname,
char __user *optval,
int optlen);
extern int ipv6_getsockopt(struct sock *sk, int level,
int optname,
char __user *optval,
int __user *optlen);
extern int compat_ipv6_setsockopt(struct sock *sk,
int level,
int optname,
char __user *optval,
int optlen);
extern int compat_ipv6_getsockopt(struct sock *sk,
int level,
int optname,
char __user *optval,
int __user *optlen);
extern void ipv6_packet_init(void);
extern void ipv6_packet_cleanup(void);
extern int ip6_datagram_connect(struct sock *sk,
struct sockaddr *addr, int addr_len);
extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
u32 info, u8 *payload);
extern void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info);
extern int inet6_release(struct socket *sock);
extern int inet6_bind(struct socket *sock, struct sockaddr *uaddr,
int addr_len);
extern int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
int *uaddr_len, int peer);
extern int inet6_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg);
extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk);
/*
* reassembly.c
*/
extern int sysctl_ip6frag_high_thresh;
extern int sysctl_ip6frag_low_thresh;
extern int sysctl_ip6frag_time;
extern int sysctl_ip6frag_secret_interval;
extern const struct proto_ops inet6_stream_ops;
extern const struct proto_ops inet6_dgram_ops;
struct group_source_req;
struct group_filter;
extern int ip6_mc_source(int add, int omode, struct sock *sk,
struct group_source_req *pgsr);
extern int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf);
extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
struct group_filter __user *optval,
int __user *optlen);
#ifdef CONFIG_PROC_FS
extern int ac6_proc_init(void);
extern void ac6_proc_exit(void);
extern int raw6_proc_init(void);
extern void raw6_proc_exit(void);
extern int tcp6_proc_init(void);
extern void tcp6_proc_exit(void);
extern int udp6_proc_init(void);
extern void udp6_proc_exit(void);
extern int udplite6_proc_init(void);
extern void udplite6_proc_exit(void);
extern int ipv6_misc_proc_init(void);
extern void ipv6_misc_proc_exit(void);
extern struct rt6_statistics rt6_stats;
#endif
#ifdef CONFIG_SYSCTL
extern ctl_table ipv6_route_table[];
extern ctl_table ipv6_icmp_table[];
extern void ipv6_sysctl_register(void);
extern void ipv6_sysctl_unregister(void);
#endif
#endif /* __KERNEL__ */
#endif /* _NET_IPV6_H */

161
include/net/ipx.h Normal file
View File

@@ -0,0 +1,161 @@
#ifndef _NET_INET_IPX_H_
#define _NET_INET_IPX_H_
/*
* The following information is in its entirety obtained from:
*
* Novell 'IPX Router Specification' Version 1.10
* Part No. 107-000029-001
*
* Which is available from ftp.novell.com
*/
#include <linux/netdevice.h>
#include <net/datalink.h>
#include <linux/ipx.h>
#include <linux/list.h>
struct ipx_address {
__be32 net;
__u8 node[IPX_NODE_LEN];
__be16 sock;
};
#define ipx_broadcast_node "\377\377\377\377\377\377"
#define ipx_this_node "\0\0\0\0\0\0"
#define IPX_MAX_PPROP_HOPS 8
struct ipxhdr {
__be16 ipx_checksum __attribute__ ((packed));
#define IPX_NO_CHECKSUM __constant_htons(0xFFFF)
__be16 ipx_pktsize __attribute__ ((packed));
__u8 ipx_tctrl;
__u8 ipx_type;
#define IPX_TYPE_UNKNOWN 0x00
#define IPX_TYPE_RIP 0x01 /* may also be 0 */
#define IPX_TYPE_SAP 0x04 /* may also be 0 */
#define IPX_TYPE_SPX 0x05 /* SPX protocol */
#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */
struct ipx_address ipx_dest __attribute__ ((packed));
struct ipx_address ipx_source __attribute__ ((packed));
};
static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb)
{
return (struct ipxhdr *)skb->h.raw;
}
struct ipx_interface {
/* IPX address */
__be32 if_netnum;
unsigned char if_node[IPX_NODE_LEN];
atomic_t refcnt;
/* physical device info */
struct net_device *if_dev;
struct datalink_proto *if_dlink;
__be16 if_dlink_type;
/* socket support */
unsigned short if_sknum;
struct hlist_head if_sklist;
spinlock_t if_sklist_lock;
/* administrative overhead */
int if_ipx_offset;
unsigned char if_internal;
unsigned char if_primary;
struct list_head node; /* node in ipx_interfaces list */
};
struct ipx_route {
__be32 ir_net;
struct ipx_interface *ir_intrfc;
unsigned char ir_routed;
unsigned char ir_router_node[IPX_NODE_LEN];
struct list_head node; /* node in ipx_routes list */
atomic_t refcnt;
};
#ifdef __KERNEL__
struct ipx_cb {
u8 ipx_tctrl;
__be32 ipx_dest_net;
__be32 ipx_source_net;
struct {
__be32 netnum;
int index;
} last_hop;
};
#include <net/sock.h>
struct ipx_sock {
/* struct sock has to be the first member of ipx_sock */
struct sock sk;
struct ipx_address dest_addr;
struct ipx_interface *intrfc;
__be16 port;
#ifdef CONFIG_IPX_INTERN
unsigned char node[IPX_NODE_LEN];
#endif
unsigned short type;
/*
* To handle special ncp connection-handling sockets for mars_nwe,
* the connection number must be stored in the socket.
*/
unsigned short ipx_ncp_conn;
};
static inline struct ipx_sock *ipx_sk(struct sock *sk)
{
return (struct ipx_sock *)sk;
}
#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
#endif
#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
extern struct list_head ipx_routes;
extern rwlock_t ipx_routes_lock;
extern struct list_head ipx_interfaces;
extern struct ipx_interface *ipx_interfaces_head(void);
extern spinlock_t ipx_interfaces_lock;
extern struct ipx_interface *ipx_primary_net;
extern int ipx_proc_init(void);
extern void ipx_proc_exit(void);
extern const char *ipx_frame_name(__be16);
extern const char *ipx_device_name(struct ipx_interface *intrfc);
static __inline__ void ipxitf_hold(struct ipx_interface *intrfc)
{
atomic_inc(&intrfc->refcnt);
}
extern void ipxitf_down(struct ipx_interface *intrfc);
static __inline__ void ipxitf_put(struct ipx_interface *intrfc)
{
if (atomic_dec_and_test(&intrfc->refcnt))
ipxitf_down(intrfc);
}
static __inline__ void ipxrtr_hold(struct ipx_route *rt)
{
atomic_inc(&rt->refcnt);
}
static __inline__ void ipxrtr_put(struct ipx_route *rt)
{
if (atomic_dec_and_test(&rt->refcnt))
kfree(rt);
}
#endif /* _NET_INET_IPX_H_ */

View File

@@ -0,0 +1,87 @@
/*********************************************************************
*
* Filename: af_irda.h
* Version: 1.0
* Description: IrDA sockets declarations
* Status: Stable
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Dec 9 21:13:12 1997
* Modified at: Fri Jan 28 13:16:32 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef AF_IRDA_H
#define AF_IRDA_H
#include <linux/irda.h>
#include <net/irda/irda.h>
#include <net/irda/iriap.h> /* struct iriap_cb */
#include <net/irda/irias_object.h> /* struct ias_value */
#include <net/irda/irlmp.h> /* struct lsap_cb */
#include <net/irda/irttp.h> /* struct tsap_cb */
#include <net/irda/discovery.h> /* struct discovery_t */
#include <net/sock.h>
/* IrDA Socket */
struct irda_sock {
/* struct sock has to be the first member of irda_sock */
struct sock sk;
__u32 saddr; /* my local address */
__u32 daddr; /* peer address */
struct lsap_cb *lsap; /* LSAP used by Ultra */
__u8 pid; /* Protocol IP (PID) used by Ultra */
struct tsap_cb *tsap; /* TSAP used by this connection */
__u8 dtsap_sel; /* remote TSAP address */
__u8 stsap_sel; /* local TSAP address */
__u32 max_sdu_size_rx;
__u32 max_sdu_size_tx;
__u32 max_data_size;
__u8 max_header_size;
struct qos_info qos_tx;
__u16_host_order mask; /* Hint bits mask */
__u16_host_order hints; /* Hint bits */
void *ckey; /* IrLMP client handle */
void *skey; /* IrLMP service handle */
struct ias_object *ias_obj; /* Our service name + lsap in IAS */
struct iriap_cb *iriap; /* Used to query remote IAS */
struct ias_value *ias_result; /* Result of remote IAS query */
hashbin_t *cachelog; /* Result of discovery query */
__u32 cachedaddr; /* Result of selective discovery query */
int nslots; /* Number of slots to use for discovery */
int errno; /* status of the IAS query */
wait_queue_head_t query_wait; /* Wait for the answer to a query */
struct timer_list watchdog; /* Timeout for discovery */
LOCAL_FLOW tx_flow;
LOCAL_FLOW rx_flow;
};
static inline struct irda_sock *irda_sk(struct sock *sk)
{
return (struct irda_sock *)sk;
}
#endif /* AF_IRDA_H */

29
include/net/irda/crc.h Normal file
View File

@@ -0,0 +1,29 @@
/*********************************************************************
*
* Filename: crc.h
* Version:
* Description: CRC routines
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
* Modified at: Sun May 2 20:25:23 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
********************************************************************/
#ifndef IRDA_CRC_H
#define IRDA_CRC_H
#include <linux/types.h>
#include <linux/crc-ccitt.h>
#define INIT_FCS 0xffff /* Initial FCS value */
#define GOOD_FCS 0xf0b8 /* Good final FCS value */
/* Recompute the FCS with one more character appended. */
#define irda_fcs(fcs, c) crc_ccitt_byte(fcs, c)
/* Recompute the FCS with len bytes appended. */
#define irda_calc_crc16(fcs, buf, len) crc_ccitt(fcs, buf, len)
#endif

View File

@@ -0,0 +1,100 @@
/*********************************************************************
*
* Filename: discovery.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Apr 6 16:53:53 1999
* Modified at: Tue Oct 5 10:05:10 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef DISCOVERY_H
#define DISCOVERY_H
#include <asm/param.h>
#include <net/irda/irda.h>
#include <net/irda/irqueue.h> /* irda_queue_t */
#include <net/irda/irlap_event.h> /* LAP_REASON */
#define DISCOVERY_EXPIRE_TIMEOUT (2*sysctl_discovery_timeout*HZ)
#define DISCOVERY_DEFAULT_SLOTS 0
/*
* This type is used by the protocols that transmit 16 bits words in
* little endian format. A little endian machine stores MSB of word in
* byte[1] and LSB in byte[0]. A big endian machine stores MSB in byte[0]
* and LSB in byte[1].
*
* This structure is used in the code for things that are endian neutral
* but that fit in a word so that we can manipulate them efficiently.
* By endian neutral, I mean things that are really an array of bytes,
* and always used as such, for example the hint bits. Jean II
*/
typedef union {
__u16 word;
__u8 byte[2];
} __u16_host_order;
/* Same purpose, different application */
#define u16ho(array) (* ((__u16 *) array))
/* Types of discovery */
typedef enum {
DISCOVERY_LOG, /* What's in our discovery log */
DISCOVERY_ACTIVE, /* Doing our own discovery on the medium */
DISCOVERY_PASSIVE, /* Peer doing discovery on the medium */
EXPIRY_TIMEOUT, /* Entry expired due to timeout */
} DISCOVERY_MODE;
#define NICKNAME_MAX_LEN 21
/* Basic discovery information about a peer */
typedef struct irda_device_info discinfo_t; /* linux/irda.h */
/*
* The DISCOVERY structure is used for both discovery requests and responses
*/
typedef struct discovery_t {
irda_queue_t q; /* Must be first! */
discinfo_t data; /* Basic discovery information */
int name_len; /* Lenght of nickname */
LAP_REASON condition; /* More info about the discovery */
int gen_addr_bit; /* Need to generate a new device
* address? */
int nslots; /* Number of slots to use when
* discovering */
unsigned long timestamp; /* Last time discovered */
unsigned long firststamp; /* First time discovered */
} discovery_t;
void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery);
void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log);
void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force);
struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
__u16 mask, int old_entries);
#endif

View File

@@ -0,0 +1,108 @@
/*********************************************************************
*
* Filename: ircomm_core.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed Jun 9 08:58:43 1999
* Modified at: Mon Dec 13 11:52:29 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_CORE_H
#define IRCOMM_CORE_H
#include <net/irda/irda.h>
#include <net/irda/irqueue.h>
#include <net/irda/ircomm_event.h>
#define IRCOMM_MAGIC 0x98347298
#define IRCOMM_HEADER_SIZE 1
struct ircomm_cb; /* Forward decl. */
/*
* A small call-table, so we don't have to check the service-type whenever
* we want to do something
*/
typedef struct {
int (*data_request)(struct ircomm_cb *, struct sk_buff *, int clen);
int (*connect_request)(struct ircomm_cb *, struct sk_buff *,
struct ircomm_info *);
int (*connect_response)(struct ircomm_cb *, struct sk_buff *);
int (*disconnect_request)(struct ircomm_cb *, struct sk_buff *,
struct ircomm_info *);
} call_t;
struct ircomm_cb {
irda_queue_t queue;
magic_t magic;
notify_t notify;
call_t issue;
int state;
int line; /* Which TTY line we are using */
struct tsap_cb *tsap;
struct lsap_cb *lsap;
__u8 dlsap_sel; /* Destination LSAP/TSAP selector */
__u8 slsap_sel; /* Source LSAP/TSAP selector */
__u32 saddr; /* Source device address (link we are using) */
__u32 daddr; /* Destination device address */
int max_header_size; /* Header space we must reserve for each frame */
int max_data_size; /* The amount of data we can fill in each frame */
LOCAL_FLOW flow_status; /* Used by ircomm_lmp */
int pkt_count; /* Number of frames we have sent to IrLAP */
__u8 service_type;
};
extern hashbin_t *ircomm;
struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line);
int ircomm_close(struct ircomm_cb *self);
int ircomm_data_request(struct ircomm_cb *self, struct sk_buff *skb);
void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb);
void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb);
int ircomm_control_request(struct ircomm_cb *self, struct sk_buff *skb);
int ircomm_connect_request(struct ircomm_cb *self, __u8 dlsap_sel,
__u32 saddr, __u32 daddr, struct sk_buff *skb,
__u8 service_type);
void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb,
struct ircomm_info *info);
void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb,
struct ircomm_info *info);
int ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata);
int ircomm_disconnect_request(struct ircomm_cb *self, struct sk_buff *userdata);
void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb,
struct ircomm_info *info);
void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow);
#define ircomm_is_connected(self) (self->state == IRCOMM_CONN)
#endif

View File

@@ -0,0 +1,85 @@
/*********************************************************************
*
* Filename: ircomm_event.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Jun 6 23:51:13 1999
* Modified at: Thu Jun 10 08:36:25 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_EVENT_H
#define IRCOMM_EVENT_H
#include <net/irda/irmod.h>
typedef enum {
IRCOMM_IDLE,
IRCOMM_WAITI,
IRCOMM_WAITR,
IRCOMM_CONN,
} IRCOMM_STATE;
/* IrCOMM Events */
typedef enum {
IRCOMM_CONNECT_REQUEST,
IRCOMM_CONNECT_RESPONSE,
IRCOMM_TTP_CONNECT_INDICATION,
IRCOMM_LMP_CONNECT_INDICATION,
IRCOMM_TTP_CONNECT_CONFIRM,
IRCOMM_LMP_CONNECT_CONFIRM,
IRCOMM_LMP_DISCONNECT_INDICATION,
IRCOMM_TTP_DISCONNECT_INDICATION,
IRCOMM_DISCONNECT_REQUEST,
IRCOMM_TTP_DATA_INDICATION,
IRCOMM_LMP_DATA_INDICATION,
IRCOMM_DATA_REQUEST,
IRCOMM_CONTROL_REQUEST,
IRCOMM_CONTROL_INDICATION,
} IRCOMM_EVENT;
/*
* Used for passing information through the state-machine
*/
struct ircomm_info {
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
__u8 dlsap_sel;
LM_REASON reason; /* Reason for disconnect */
__u32 max_data_size;
__u32 max_header_size;
struct qos_info *qos;
};
extern char *ircomm_state[];
struct ircomm_cb; /* Forward decl. */
int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event,
struct sk_buff *skb, struct ircomm_info *info);
void ircomm_next_state(struct ircomm_cb *self, IRCOMM_STATE state);
#endif

View File

@@ -0,0 +1,38 @@
/*********************************************************************
*
* Filename: ircomm_lmp.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed Jun 9 10:06:07 1999
* Modified at: Fri Aug 13 07:32:32 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_LMP_H
#define IRCOMM_LMP_H
#include <net/irda/ircomm_core.h>
int ircomm_open_lsap(struct ircomm_cb *self);
#endif

View File

@@ -0,0 +1,149 @@
/*********************************************************************
*
* Filename: ircomm_param.h
* Version: 1.0
* Description: Parameter handling for the IrCOMM protocol
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Jun 7 08:47:28 1999
* Modified at: Wed Aug 25 13:46:33 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_PARAMS_H
#define IRCOMM_PARAMS_H
#include <net/irda/parameters.h>
/* Parameters common to all service types */
#define IRCOMM_SERVICE_TYPE 0x00
#define IRCOMM_PORT_TYPE 0x01 /* Only used in LM-IAS */
#define IRCOMM_PORT_NAME 0x02 /* Only used in LM-IAS */
/* Parameters for both 3 wire and 9 wire */
#define IRCOMM_DATA_RATE 0x10
#define IRCOMM_DATA_FORMAT 0x11
#define IRCOMM_FLOW_CONTROL 0x12
#define IRCOMM_XON_XOFF 0x13
#define IRCOMM_ENQ_ACK 0x14
#define IRCOMM_LINE_STATUS 0x15
#define IRCOMM_BREAK 0x16
/* Parameters for 9 wire */
#define IRCOMM_DTE 0x20
#define IRCOMM_DCE 0x21
#define IRCOMM_POLL 0x22
/* Service type (details) */
#define IRCOMM_3_WIRE_RAW 0x01
#define IRCOMM_3_WIRE 0x02
#define IRCOMM_9_WIRE 0x04
#define IRCOMM_CENTRONICS 0x08
/* Port type (details) */
#define IRCOMM_SERIAL 0x00
#define IRCOMM_PARALLEL 0x01
/* Data format (details) */
#define IRCOMM_WSIZE_5 0x00
#define IRCOMM_WSIZE_6 0x01
#define IRCOMM_WSIZE_7 0x02
#define IRCOMM_WSIZE_8 0x03
#define IRCOMM_1_STOP_BIT 0x00
#define IRCOMM_2_STOP_BIT 0x04 /* 1.5 if char len 5 */
#define IRCOMM_PARITY_DISABLE 0x00
#define IRCOMM_PARITY_ENABLE 0x08
#define IRCOMM_PARITY_ODD 0x00
#define IRCOMM_PARITY_EVEN 0x10
#define IRCOMM_PARITY_MARK 0x20
#define IRCOMM_PARITY_SPACE 0x30
/* Flow control */
#define IRCOMM_XON_XOFF_IN 0x01
#define IRCOMM_XON_XOFF_OUT 0x02
#define IRCOMM_RTS_CTS_IN 0x04
#define IRCOMM_RTS_CTS_OUT 0x08
#define IRCOMM_DSR_DTR_IN 0x10
#define IRCOMM_DSR_DTR_OUT 0x20
#define IRCOMM_ENQ_ACK_IN 0x40
#define IRCOMM_ENQ_ACK_OUT 0x80
/* Line status */
#define IRCOMM_OVERRUN_ERROR 0x02
#define IRCOMM_PARITY_ERROR 0x04
#define IRCOMM_FRAMING_ERROR 0x08
/* DTE (Data terminal equipment) line settings */
#define IRCOMM_DELTA_DTR 0x01
#define IRCOMM_DELTA_RTS 0x02
#define IRCOMM_DTR 0x04
#define IRCOMM_RTS 0x08
/* DCE (Data communications equipment) line settings */
#define IRCOMM_DELTA_CTS 0x01 /* Clear to send has changed */
#define IRCOMM_DELTA_DSR 0x02 /* Data set ready has changed */
#define IRCOMM_DELTA_RI 0x04 /* Ring indicator has changed */
#define IRCOMM_DELTA_CD 0x08 /* Carrier detect has changed */
#define IRCOMM_CTS 0x10 /* Clear to send is high */
#define IRCOMM_DSR 0x20 /* Data set ready is high */
#define IRCOMM_RI 0x40 /* Ring indicator is high */
#define IRCOMM_CD 0x80 /* Carrier detect is high */
#define IRCOMM_DCE_DELTA_ANY 0x0f
/*
* Parameter state
*/
struct ircomm_params {
/* General control params */
__u8 service_type;
__u8 port_type;
char port_name[32];
/* Control params for 3- and 9-wire service type */
__u32 data_rate; /* Data rate in bps */
__u8 data_format;
__u8 flow_control;
char xonxoff[2];
char enqack[2];
__u8 line_status;
__u8 _break;
__u8 null_modem;
/* Control params for 9-wire service type */
__u8 dte;
__u8 dce;
__u8 poll;
/* Control params for Centronics service type */
};
struct ircomm_tty_cb; /* Forward decl. */
int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush);
extern pi_param_info_t ircomm_param_info;
#endif /* IRCOMM_PARAMS_H */

View File

@@ -0,0 +1,39 @@
/*********************************************************************
*
* Filename: ircomm_ttp.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed Jun 9 10:06:07 1999
* Modified at: Fri Aug 13 07:32:22 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_TTP_H
#define IRCOMM_TTP_H
#include <net/irda/ircomm_core.h>
int ircomm_open_tsap(struct ircomm_cb *self);
#endif

View File

@@ -0,0 +1,139 @@
/*********************************************************************
*
* Filename: ircomm_tty.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Jun 6 23:24:22 1999
* Modified at: Fri Jan 28 13:16:57 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_TTY_H
#define IRCOMM_TTY_H
#include <linux/serial.h>
#include <linux/termios.h>
#include <linux/timer.h>
#include <linux/tty.h> /* struct tty_struct */
#include <net/irda/irias_object.h>
#include <net/irda/ircomm_core.h>
#include <net/irda/ircomm_param.h>
#define IRCOMM_TTY_PORTS 32
#define IRCOMM_TTY_MAGIC 0x3432
#define IRCOMM_TTY_MAJOR 161
#define IRCOMM_TTY_MINOR 0
/* This is used as an initial value to max_header_size before the proper
* value is filled in (5 for ttp, 4 for lmp). This allow us to detect
* the state of the underlying connection. - Jean II */
#define IRCOMM_TTY_HDR_UNINITIALISED 16
/* Same for payload size. See qos.c for the smallest max data size */
#define IRCOMM_TTY_DATA_UNINITIALISED (64 - IRCOMM_TTY_HDR_UNINITIALISED)
/* Those are really defined in include/linux/serial.h - Jean II */
#define ASYNC_B_INITIALIZED 31 /* Serial port was initialized */
#define ASYNC_B_NORMAL_ACTIVE 29 /* Normal device is active */
#define ASYNC_B_CLOSING 27 /* Serial port is closing */
/*
* IrCOMM TTY driver state
*/
struct ircomm_tty_cb {
irda_queue_t queue; /* Must be first */
magic_t magic;
int state; /* Connect state */
struct tty_struct *tty;
struct ircomm_cb *ircomm; /* IrCOMM layer instance */
struct sk_buff *tx_skb; /* Transmit buffer */
struct sk_buff *ctrl_skb; /* Control data buffer */
/* Parameters */
struct ircomm_params settings;
__u8 service_type; /* The service that we support */
int client; /* True if we are a client */
LOCAL_FLOW flow; /* IrTTP flow status */
int line;
unsigned long flags;
__u8 dlsap_sel;
__u8 slsap_sel;
__u32 saddr;
__u32 daddr;
__u32 max_data_size; /* Max data we can transmit in one packet */
__u32 max_header_size; /* The amount of header space we must reserve */
__u32 tx_data_size; /* Max data size of current tx_skb */
struct iriap_cb *iriap; /* Instance used for querying remote IAS */
struct ias_object* obj;
void *skey;
void *ckey;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
struct timer_list watchdog_timer;
struct work_struct tqueue;
unsigned short close_delay;
unsigned short closing_wait; /* time to wait before closing */
int open_count;
int blocked_open; /* # of blocked opens */
/* Protect concurent access to :
* o self->open_count
* o self->ctrl_skb
* o self->tx_skb
* Maybe other things may gain to be protected as well...
* Jean II */
spinlock_t spinlock;
};
void ircomm_tty_start(struct tty_struct *tty);
void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self);
extern int ircomm_tty_tiocmget(struct tty_struct *tty, struct file *file);
extern int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg);
extern void ircomm_tty_set_termios(struct tty_struct *tty,
struct ktermios *old_termios);
extern hashbin_t *ircomm_tty;
#endif

View File

@@ -0,0 +1,94 @@
/*********************************************************************
*
* Filename: ircomm_tty_attach.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed Jun 9 15:55:18 1999
* Modified at: Fri Dec 10 21:04:55 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRCOMM_TTY_ATTACH_H
#define IRCOMM_TTY_ATTACH_H
#include <net/irda/ircomm_tty.h>
typedef enum {
IRCOMM_TTY_IDLE,
IRCOMM_TTY_SEARCH,
IRCOMM_TTY_QUERY_PARAMETERS,
IRCOMM_TTY_QUERY_LSAP_SEL,
IRCOMM_TTY_SETUP,
IRCOMM_TTY_READY,
} IRCOMM_TTY_STATE;
/* IrCOMM TTY Events */
typedef enum {
IRCOMM_TTY_ATTACH_CABLE,
IRCOMM_TTY_DETACH_CABLE,
IRCOMM_TTY_DATA_REQUEST,
IRCOMM_TTY_DATA_INDICATION,
IRCOMM_TTY_DISCOVERY_REQUEST,
IRCOMM_TTY_DISCOVERY_INDICATION,
IRCOMM_TTY_CONNECT_CONFIRM,
IRCOMM_TTY_CONNECT_INDICATION,
IRCOMM_TTY_DISCONNECT_REQUEST,
IRCOMM_TTY_DISCONNECT_INDICATION,
IRCOMM_TTY_WD_TIMER_EXPIRED,
IRCOMM_TTY_GOT_PARAMETERS,
IRCOMM_TTY_GOT_LSAPSEL,
} IRCOMM_TTY_EVENT;
/* Used for passing information through the state-machine */
struct ircomm_tty_info {
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
__u8 dlsap_sel;
};
extern char *ircomm_state[];
extern char *ircomm_tty_state[];
int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
struct sk_buff *skb, struct ircomm_tty_info *info);
int ircomm_tty_attach_cable(struct ircomm_tty_cb *self);
void ircomm_tty_detach_cable(struct ircomm_tty_cb *self);
void ircomm_tty_connect_confirm(void *instance, void *sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
struct sk_buff *skb);
void ircomm_tty_disconnect_indication(void *instance, void *sap,
LM_REASON reason,
struct sk_buff *skb);
void ircomm_tty_connect_indication(void *instance, void *sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
struct sk_buff *skb);
int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self);
void ircomm_tty_link_established(struct ircomm_tty_cb *self);
#endif /* IRCOMM_TTY_ATTACH_H */

132
include/net/irda/irda.h Normal file
View File

@@ -0,0 +1,132 @@
/*********************************************************************
*
* Filename: irda.h
* Version: 1.0
* Description: IrDA common include file for kernel internal use
* Status: Stable
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Dec 9 21:13:12 1997
* Modified at: Fri Jan 28 13:16:32 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef NET_IRDA_H
#define NET_IRDA_H
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/kernel.h>
#include <linux/if.h> /* sa_family_t in <linux/irda.h> */
#include <linux/irda.h>
typedef __u32 magic_t;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* Hack to do small backoff when setting media busy in IrLAP */
#ifndef SMALL
#define SMALL 5
#endif
#ifndef IRDA_MIN /* Lets not mix this MIN with other header files */
#define IRDA_MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef IRDA_ALIGN
# define IRDA_ALIGN __attribute__((aligned))
#endif
#ifndef IRDA_PACK
# define IRDA_PACK __attribute__((packed))
#endif
#ifdef CONFIG_IRDA_DEBUG
extern unsigned int irda_debug;
/* use 0 for production, 1 for verification, >2 for debug */
#define IRDA_DEBUG_LEVEL 0
#define IRDA_DEBUG(n, args...) \
do { if (irda_debug >= (n)) \
printk(KERN_DEBUG args); \
} while (0)
#define IRDA_ASSERT(expr, func) \
do { if(!(expr)) { \
printk( "Assertion failed! %s:%s:%d %s\n", \
__FILE__,__FUNCTION__,__LINE__,(#expr) ); \
func } } while (0)
#define IRDA_ASSERT_LABEL(label) label
#else
#define IRDA_DEBUG(n, args...) do { } while (0)
#define IRDA_ASSERT(expr, func) do { (void)(expr); } while (0)
#define IRDA_ASSERT_LABEL(label)
#endif /* CONFIG_IRDA_DEBUG */
#define IRDA_WARNING(args...) do { if (net_ratelimit()) printk(KERN_WARNING args); } while (0)
#define IRDA_MESSAGE(args...) do { if (net_ratelimit()) printk(KERN_INFO args); } while (0)
#define IRDA_ERROR(args...) do { if (net_ratelimit()) printk(KERN_ERR args); } while (0)
/*
* Magic numbers used by Linux-IrDA. Random numbers which must be unique to
* give the best protection
*/
#define IRTTY_MAGIC 0x2357
#define LAP_MAGIC 0x1357
#define LMP_MAGIC 0x4321
#define LMP_LSAP_MAGIC 0x69333
#define LMP_LAP_MAGIC 0x3432
#define IRDA_DEVICE_MAGIC 0x63454
#define IAS_MAGIC 0x007
#define TTP_MAGIC 0x241169
#define TTP_TSAP_MAGIC 0x4345
#define IROBEX_MAGIC 0x341324
#define HB_MAGIC 0x64534
#define IRLAN_MAGIC 0x754
#define IAS_OBJECT_MAGIC 0x34234
#define IAS_ATTRIB_MAGIC 0x45232
#define IRDA_TASK_MAGIC 0x38423
#define IAS_DEVICE_ID 0x0000 /* Defined by IrDA, IrLMP section 4.1 (page 68) */
#define IAS_PNP_ID 0xd342
#define IAS_OBEX_ID 0x34323
#define IAS_IRLAN_ID 0x34234
#define IAS_IRCOMM_ID 0x2343
#define IAS_IRLPT_ID 0x9876
struct net_device;
struct packet_type;
extern void irda_proc_register(void);
extern void irda_proc_unregister(void);
extern int irda_sysctl_register(void);
extern void irda_sysctl_unregister(void);
extern int irsock_init(void);
extern void irsock_cleanup(void);
extern int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype,
struct net_device *orig_dev);
#endif /* NET_IRDA_H */

View File

@@ -0,0 +1,298 @@
/*********************************************************************
*
* Filename: irda_device.h
* Version: 0.9
* Description: Contains various declarations used by the drivers
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Apr 14 12:41:42 1998
* Modified at: Mon Mar 20 09:08:57 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>,
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
/*
* This header contains all the IrDA definitions a driver really
* needs, and therefore the driver should not need to include
* any other IrDA headers - Jean II
*/
#ifndef IRDA_DEVICE_H
#define IRDA_DEVICE_H
#include <linux/tty.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/irda.h>
#include <linux/types.h>
#include <net/pkt_sched.h>
#include <net/irda/irda.h>
#include <net/irda/qos.h> /* struct qos_info */
#include <net/irda/irqueue.h> /* irda_queue_t */
/* A few forward declarations (to make compiler happy) */
struct irlap_cb;
/* Some non-standard interface flags (should not conflict with any in if.h) */
#define IFF_SIR 0x0001 /* Supports SIR speeds */
#define IFF_MIR 0x0002 /* Supports MIR speeds */
#define IFF_FIR 0x0004 /* Supports FIR speeds */
#define IFF_VFIR 0x0008 /* Supports VFIR speeds */
#define IFF_PIO 0x0010 /* Supports PIO transfer of data */
#define IFF_DMA 0x0020 /* Supports DMA transfer of data */
#define IFF_SHM 0x0040 /* Supports shared memory data transfers */
#define IFF_DONGLE 0x0080 /* Interface has a dongle attached */
#define IFF_AIR 0x0100 /* Supports Advanced IR (AIR) standards */
#define IO_XMIT 0x01
#define IO_RECV 0x02
typedef enum {
IRDA_IRLAP, /* IrDA mode, and deliver to IrLAP */
IRDA_RAW, /* IrDA mode */
SHARP_ASK,
TV_REMOTE, /* Also known as Consumer Electronics IR */
} INFRARED_MODE;
typedef enum {
IRDA_TASK_INIT, /* All tasks are initialized with this state */
IRDA_TASK_DONE, /* Signals that the task is finished */
IRDA_TASK_WAIT,
IRDA_TASK_WAIT1,
IRDA_TASK_WAIT2,
IRDA_TASK_WAIT3,
IRDA_TASK_CHILD_INIT, /* Initializing child task */
IRDA_TASK_CHILD_WAIT, /* Waiting for child task to finish */
IRDA_TASK_CHILD_DONE /* Child task is finished */
} IRDA_TASK_STATE;
struct irda_task;
typedef int (*IRDA_TASK_CALLBACK) (struct irda_task *task);
struct irda_task {
irda_queue_t q;
magic_t magic;
IRDA_TASK_STATE state;
IRDA_TASK_CALLBACK function;
IRDA_TASK_CALLBACK finished;
struct irda_task *parent;
struct timer_list timer;
void *instance; /* Instance being called */
void *param; /* Parameter to be used by instance */
};
/* Dongle info */
struct dongle_reg;
typedef struct {
struct dongle_reg *issue; /* Registration info */
struct net_device *dev; /* Device we are attached to */
struct irda_task *speed_task; /* Task handling speed change */
struct irda_task *reset_task; /* Task handling reset */
__u32 speed; /* Current speed */
/* Callbacks to the IrDA device driver */
int (*set_mode)(struct net_device *, int mode);
int (*read)(struct net_device *dev, __u8 *buf, int len);
int (*write)(struct net_device *dev, __u8 *buf, int len);
int (*set_dtr_rts)(struct net_device *dev, int dtr, int rts);
} dongle_t;
/* Dongle registration info */
struct dongle_reg {
irda_queue_t q; /* Must be first */
IRDA_DONGLE type;
void (*open)(dongle_t *dongle, struct qos_info *qos);
void (*close)(dongle_t *dongle);
int (*reset)(struct irda_task *task);
int (*change_speed)(struct irda_task *task);
struct module *owner;
};
/*
* Per-packet information we need to hide inside sk_buff
* (must not exceed 48 bytes, check with struct sk_buff)
*/
struct irda_skb_cb {
magic_t magic; /* Be sure that we can trust the information */
__u32 next_speed; /* The Speed to be set *after* this frame */
__u16 mtt; /* Minimum turn around time */
__u16 xbofs; /* Number of xbofs required, used by SIR mode */
__u16 next_xbofs; /* Number of xbofs required *after* this frame */
void *context; /* May be used by drivers */
void (*destructor)(struct sk_buff *skb); /* Used for flow control */
__u16 xbofs_delay; /* Number of xbofs used for generating the mtt */
__u8 line; /* Used by IrCOMM in IrLPT mode */
};
/* Chip specific info */
typedef struct {
int cfg_base; /* Config register IO base */
int sir_base; /* SIR IO base */
int fir_base; /* FIR IO base */
int mem_base; /* Shared memory base */
int sir_ext; /* Length of SIR iobase */
int fir_ext; /* Length of FIR iobase */
int irq, irq2; /* Interrupts used */
int dma, dma2; /* DMA channel(s) used */
int fifo_size; /* FIFO size */
int irqflags; /* interrupt flags (ie, IRQF_SHARED|IRQF_DISABLED) */
int direction; /* Link direction, used by some FIR drivers */
int enabled; /* Powered on? */
int suspended; /* Suspended by APM */
__u32 speed; /* Currently used speed */
__u32 new_speed; /* Speed we must change to when Tx is finished */
int dongle_id; /* Dongle or transceiver currently used */
} chipio_t;
/* IO buffer specific info (inspired by struct sk_buff) */
typedef struct {
int state; /* Receiving state (transmit state not used) */
int in_frame; /* True if receiving frame */
__u8 *head; /* start of buffer */
__u8 *data; /* start of data in buffer */
int len; /* current length of data */
int truesize; /* total allocated size of buffer */
__u16 fcs;
struct sk_buff *skb; /* ZeroCopy Rx in async_unwrap_char() */
} iobuff_t;
/* Maximum SIR frame (skb) that we expect to receive *unwrapped*.
* Max LAP MTU (I field) is 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40).
* Max LAP header is 2 bytes (for now).
* Max CRC is 2 bytes at SIR, 4 bytes at FIR.
* Need 1 byte for skb_reserve() to align IP header for IrLAN.
* Add a few extra bytes just to be safe (buffer is power of two anyway)
* Jean II */
#define IRDA_SKB_MAX_MTU 2064
/* Maximum SIR frame that we expect to send, wrapped (i.e. with XBOFS
* and escaped characters on top of above). */
#define IRDA_SIR_MAX_FRAME 4269
/* The SIR unwrapper async_unwrap_char() will use a Rx-copy-break mechanism
* when using the optional ZeroCopy Rx, where only small frames are memcpy
* to a smaller skb to save memory. This is the threshold under which copy
* will happen (and over which it won't happen).
* Some FIR drivers may use this #define as well...
* This is the same value as various Ethernet drivers. - Jean II */
#define IRDA_RX_COPY_THRESHOLD 256
/* Function prototypes */
int irda_device_init(void);
void irda_device_cleanup(void);
/* IrLAP entry points used by the drivers.
* We declare them here to avoid the driver pulling a whole bunch stack
* headers they don't really need - Jean II */
struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
const char *hw_name);
void irlap_close(struct irlap_cb *self);
/* Interface to be uses by IrLAP */
void irda_device_set_media_busy(struct net_device *dev, int status);
int irda_device_is_media_busy(struct net_device *dev);
int irda_device_is_receiving(struct net_device *dev);
/* Interface for internal use */
static inline int irda_device_txqueue_empty(const struct net_device *dev)
{
return skb_queue_empty(&dev->qdisc->q);
}
int irda_device_set_raw_mode(struct net_device* self, int status);
struct net_device *alloc_irdadev(int sizeof_priv);
/* Dongle interface */
void irda_device_unregister_dongle(struct dongle_reg *dongle);
int irda_device_register_dongle(struct dongle_reg *dongle);
dongle_t *irda_device_dongle_init(struct net_device *dev, int type);
int irda_device_dongle_cleanup(dongle_t *dongle);
void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode);
void irda_task_delete(struct irda_task *task);
struct irda_task *irda_task_execute(void *instance,
IRDA_TASK_CALLBACK function,
IRDA_TASK_CALLBACK finished,
struct irda_task *parent, void *param);
void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state);
/*
* Function irda_get_mtt (skb)
*
* Utility function for getting the minimum turnaround time out of
* the skb, where it has been hidden in the cb field.
*/
static inline __u16 irda_get_mtt(const struct sk_buff *skb)
{
const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb;
return (cb->magic == LAP_MAGIC) ? cb->mtt : 10000;
}
/*
* Function irda_get_next_speed (skb)
*
* Extract the speed that should be set *after* this frame from the skb
*
* Note : return -1 for user space frames
*/
static inline __u32 irda_get_next_speed(const struct sk_buff *skb)
{
const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb;
return (cb->magic == LAP_MAGIC) ? cb->next_speed : -1;
}
/*
* Function irda_get_next_xbofs (skb)
*
* Extract the xbofs that should be set for this frame from the skb
*
* Note : default to 10 for user space frames
*/
static inline __u16 irda_get_xbofs(const struct sk_buff *skb)
{
const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb;
return (cb->magic == LAP_MAGIC) ? cb->xbofs : 10;
}
/*
* Function irda_get_next_xbofs (skb)
*
* Extract the xbofs that should be set *after* this frame from the skb
*
* Note : return -1 for user space frames
*/
static inline __u16 irda_get_next_xbofs(const struct sk_buff *skb)
{
const struct irda_skb_cb *cb = (const struct irda_skb_cb *) skb->cb;
return (cb->magic == LAP_MAGIC) ? cb->next_xbofs : -1;
}
#endif /* IRDA_DEVICE_H */

108
include/net/irda/iriap.h Normal file
View File

@@ -0,0 +1,108 @@
/*********************************************************************
*
* Filename: iriap.h
* Version: 0.5
* Description: Information Access Protocol (IAP)
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Thu Aug 21 00:02:07 1997
* Modified at: Sat Dec 25 16:42:09 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRIAP_H
#define IRIAP_H
#include <linux/types.h>
#include <linux/skbuff.h>
#include <net/irda/iriap_event.h>
#include <net/irda/irias_object.h>
#include <net/irda/irqueue.h> /* irda_queue_t */
#include <net/irda/timer.h> /* struct timer_list */
#define IAP_LST 0x80
#define IAP_ACK 0x40
#define IAS_SERVER 0
#define IAS_CLIENT 1
/* IrIAP Op-codes */
#define GET_INFO_BASE 0x01
#define GET_OBJECTS 0x02
#define GET_VALUE 0x03
#define GET_VALUE_BY_CLASS 0x04
#define GET_OBJECT_INFO 0x05
#define GET_ATTRIB_NAMES 0x06
#define IAS_SUCCESS 0
#define IAS_CLASS_UNKNOWN 1
#define IAS_ATTRIB_UNKNOWN 2
#define IAS_DISCONNECT 10
typedef void (*CONFIRM_CALLBACK)(int result, __u16 obj_id,
struct ias_value *value, void *priv);
struct iriap_cb {
irda_queue_t q; /* Must be first */
magic_t magic; /* Magic cookie */
int mode; /* Client or server */
__u32 saddr;
__u32 daddr;
__u8 operation;
struct sk_buff *request_skb;
struct lsap_cb *lsap;
__u8 slsap_sel;
/* Client states */
IRIAP_STATE client_state;
IRIAP_STATE call_state;
/* Server states */
IRIAP_STATE server_state;
IRIAP_STATE r_connect_state;
CONFIRM_CALLBACK confirm;
void *priv; /* Used to identify client */
__u8 max_header_size;
__u32 max_data_size;
struct timer_list watchdog_timer;
};
int iriap_init(void);
void iriap_cleanup(void);
struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
CONFIRM_CALLBACK callback);
void iriap_close(struct iriap_cb *self);
int iriap_getvaluebyclass_request(struct iriap_cb *self,
__u32 saddr, __u32 daddr,
char *name, char *attr);
void iriap_connect_request(struct iriap_cb *self);
void iriap_send_ack( struct iriap_cb *self);
void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb);
void iriap_register_server(void);
#endif

View File

@@ -0,0 +1,85 @@
/*********************************************************************
*
* Filename: iriap_event.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
* Modified at: Sun Oct 31 22:02:54 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRIAP_FSM_H
#define IRIAP_FSM_H
/* Forward because of circular include dependecies */
struct iriap_cb;
/* IrIAP states */
typedef enum {
/* Client */
S_DISCONNECT,
S_CONNECTING,
S_CALL,
/* S-Call */
S_MAKE_CALL,
S_CALLING,
S_OUTSTANDING,
S_REPLYING,
S_WAIT_FOR_CALL,
S_WAIT_ACTIVE,
/* Server */
R_DISCONNECT,
R_CALL,
/* R-Connect */
R_WAITING,
R_WAIT_ACTIVE,
R_RECEIVING,
R_EXECUTE,
R_RETURNING,
} IRIAP_STATE;
typedef enum {
IAP_CALL_REQUEST,
IAP_CALL_REQUEST_GVBC,
IAP_CALL_RESPONSE,
IAP_RECV_F_LST,
IAP_LM_DISCONNECT_INDICATION,
IAP_LM_CONNECT_INDICATION,
IAP_LM_CONNECT_CONFIRM,
} IRIAP_EVENT;
void iriap_next_client_state (struct iriap_cb *self, IRIAP_STATE state);
void iriap_next_call_state (struct iriap_cb *self, IRIAP_STATE state);
void iriap_next_server_state (struct iriap_cb *self, IRIAP_STATE state);
void iriap_next_r_connect_state(struct iriap_cb *self, IRIAP_STATE state);
void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event,
struct sk_buff *skb);
void iriap_do_call_event (struct iriap_cb *self, IRIAP_EVENT event,
struct sk_buff *skb);
void iriap_do_server_event (struct iriap_cb *self, IRIAP_EVENT event,
struct sk_buff *skb);
void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event,
struct sk_buff *skb);
#endif /* IRIAP_FSM_H */

View File

@@ -0,0 +1,108 @@
/*********************************************************************
*
* Filename: irias_object.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Thu Oct 1 22:49:50 1998
* Modified at: Wed Dec 15 11:20:57 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef LM_IAS_OBJECT_H
#define LM_IAS_OBJECT_H
#include <net/irda/irda.h>
#include <net/irda/irqueue.h>
/* LM-IAS Attribute types */
#define IAS_MISSING 0
#define IAS_INTEGER 1
#define IAS_OCT_SEQ 2
#define IAS_STRING 3
/* Object ownership of attributes (user or kernel) */
#define IAS_KERNEL_ATTR 0
#define IAS_USER_ATTR 1
/*
* LM-IAS Object
*/
struct ias_object {
irda_queue_t q; /* Must be first! */
magic_t magic;
char *name;
int id;
hashbin_t *attribs;
};
/*
* Values used by LM-IAS attributes
*/
struct ias_value {
__u8 type; /* Value description */
__u8 owner; /* Managed from user/kernel space */
int charset; /* Only used by string type */
int len;
/* Value */
union {
int integer;
char *string;
__u8 *oct_seq;
} t;
};
/*
* Attributes used by LM-IAS objects
*/
struct ias_attrib {
irda_queue_t q; /* Must be first! */
int magic;
char *name; /* Attribute name */
struct ias_value *value; /* Attribute value */
};
struct ias_object *irias_new_object(char *name, int id);
void irias_insert_object(struct ias_object *obj);
int irias_delete_object(struct ias_object *obj);
int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
int cleanobject);
void __irias_delete_object(struct ias_object *obj);
void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
int user);
void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
int user);
void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
int len, int user);
int irias_object_change_attribute(char *obj_name, char *attrib_name,
struct ias_value *new_value);
struct ias_object *irias_find_object(char *name);
struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name);
struct ias_value *irias_new_string_value(char *string);
struct ias_value *irias_new_integer_value(int integer);
struct ias_value *irias_new_octseq_value(__u8 *octseq , int len);
struct ias_value *irias_new_missing_value(void);
void irias_delete_value(struct ias_value *value);
extern struct ias_value irias_missing;
extern hashbin_t *irias_objects;
#endif

View File

@@ -0,0 +1,42 @@
/*********************************************************************
*
* Filename: irlan_client.h
* Version: 0.3
* Description: IrDA LAN access layer
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Aug 31 20:14:37 1997
* Modified at: Thu Apr 22 14:13:34 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAN_CLIENT_H
#define IRLAN_CLIENT_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/irda/irias_object.h>
#include <net/irda/irlan_event.h>
void irlan_client_discovery_indication(discinfo_t *, DISCOVERY_MODE, void *);
void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr);
void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb);
void irlan_client_get_value_confirm(int result, __u16 obj_id,
struct ias_value *value, void *priv);
#endif

View File

@@ -0,0 +1,230 @@
/*********************************************************************
*
* Filename: irlan_common.h
* Version: 0.8
* Description: IrDA LAN access layer
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Aug 31 20:14:37 1997
* Modified at: Sun Oct 31 19:41:24 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAN_H
#define IRLAN_H
#include <asm/param.h> /* for HZ */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/irda/irttp.h>
#define IRLAN_MTU 1518
#define IRLAN_TIMEOUT 10*HZ /* 10 seconds */
/* Command packet types */
#define CMD_GET_PROVIDER_INFO 0
#define CMD_GET_MEDIA_CHAR 1
#define CMD_OPEN_DATA_CHANNEL 2
#define CMD_CLOSE_DATA_CHAN 3
#define CMD_RECONNECT_DATA_CHAN 4
#define CMD_FILTER_OPERATION 5
/* Some responses */
#define RSP_SUCCESS 0
#define RSP_INSUFFICIENT_RESOURCES 1
#define RSP_INVALID_COMMAND_FORMAT 2
#define RSP_COMMAND_NOT_SUPPORTED 3
#define RSP_PARAM_NOT_SUPPORTED 4
#define RSP_VALUE_NOT_SUPPORTED 5
#define RSP_NOT_OPEN 6
#define RSP_AUTHENTICATION_REQUIRED 7
#define RSP_INVALID_PASSWORD 8
#define RSP_PROTOCOL_ERROR 9
#define RSP_ASYNCHRONOUS_ERROR 255
/* Media types */
#define MEDIA_802_3 1
#define MEDIA_802_5 2
/* Filter parameters */
#define DATA_CHAN 1
#define FILTER_TYPE 2
#define FILTER_MODE 3
/* Filter types */
#define IRLAN_DIRECTED 0x01
#define IRLAN_FUNCTIONAL 0x02
#define IRLAN_GROUP 0x04
#define IRLAN_MAC_FRAME 0x08
#define IRLAN_MULTICAST 0x10
#define IRLAN_BROADCAST 0x20
#define IRLAN_IPX_SOCKET 0x40
/* Filter modes */
#define ALL 1
#define FILTER 2
#define NONE 3
/* Filter operations */
#define GET 1
#define CLEAR 2
#define ADD 3
#define REMOVE 4
#define DYNAMIC 5
/* Access types */
#define ACCESS_DIRECT 1
#define ACCESS_PEER 2
#define ACCESS_HOSTED 3
#define IRLAN_BYTE 0
#define IRLAN_SHORT 1
#define IRLAN_ARRAY 2
/* IrLAN sits on top if IrTTP */
#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER)
/* 1 byte for the command code and 1 byte for the parameter count */
#define IRLAN_CMD_HEADER 2
#define IRLAN_STRING_PARAMETER_LEN(name, value) (1 + strlen((name)) + 2 \
+ strlen ((value)))
#define IRLAN_BYTE_PARAMETER_LEN(name) (1 + strlen((name)) + 2 + 1)
#define IRLAN_SHORT_PARAMETER_LEN(name) (1 + strlen((name)) + 2 + 2)
/*
* IrLAN client
*/
struct irlan_client_cb {
int state;
int open_retries;
struct tsap_cb *tsap_ctrl;
__u32 max_sdu_size;
__u8 max_header_size;
int access_type; /* Access type of provider */
__u8 reconnect_key[255];
__u8 key_len;
__u16 recv_arb_val;
__u16 max_frame;
int filter_type;
int unicast_open;
int broadcast_open;
int tx_busy;
struct sk_buff_head txq; /* Transmit control queue */
struct iriap_cb *iriap;
struct timer_list kick_timer;
};
/*
* IrLAN provider
*/
struct irlan_provider_cb {
int state;
struct tsap_cb *tsap_ctrl;
__u32 max_sdu_size;
__u8 max_header_size;
/*
* Store some values here which are used by the provider to parse
* the filter operations
*/
int data_chan;
int filter_type;
int filter_mode;
int filter_operation;
int filter_entry;
int access_type; /* Access type */
__u16 send_arb_val;
__u8 mac_address[6]; /* Generated MAC address for peer device */
};
/*
* IrLAN control block
*/
struct irlan_cb {
int magic;
struct list_head dev_list;
struct net_device *dev; /* Ethernet device structure*/
struct net_device_stats stats;
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
int disconnect_reason; /* Why we got disconnected */
int media; /* Media type */
__u8 version[2]; /* IrLAN version */
struct tsap_cb *tsap_data; /* Data TSAP */
int use_udata; /* Use Unit Data transfers */
__u8 stsap_sel_data; /* Source data TSAP selector */
__u8 dtsap_sel_data; /* Destination data TSAP selector */
__u8 dtsap_sel_ctrl; /* Destination ctrl TSAP selector */
struct irlan_client_cb client; /* Client specific fields */
struct irlan_provider_cb provider; /* Provider specific fields */
__u32 max_sdu_size;
__u8 max_header_size;
wait_queue_head_t open_wait;
struct timer_list watchdog_timer;
};
void irlan_close(struct irlan_cb *self);
void irlan_close_tsaps(struct irlan_cb *self);
int irlan_register_netdev(struct irlan_cb *self);
void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel);
void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout);
void irlan_open_data_tsap(struct irlan_cb *self);
int irlan_run_ctrl_tx_queue(struct irlan_cb *self);
struct irlan_cb *irlan_get_any(void);
void irlan_get_provider_info(struct irlan_cb *self);
void irlan_get_media_char(struct irlan_cb *self);
void irlan_open_data_channel(struct irlan_cb *self);
void irlan_close_data_channel(struct irlan_cb *self);
void irlan_set_multicast_filter(struct irlan_cb *self, int status);
void irlan_set_broadcast_filter(struct irlan_cb *self, int status);
int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value);
int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value);
int irlan_insert_string_param(struct sk_buff *skb, char *param, char *value);
int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *value,
__u16 value_len);
int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len);
#endif

View File

@@ -0,0 +1,33 @@
/*********************************************************************
*
* Filename: irlan_eth.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Thu Oct 15 08:36:58 1998
* Modified at: Fri May 14 23:29:00 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAN_ETH_H
#define IRLAN_ETH_H
struct net_device *alloc_irlandev(const char *name);
int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb);
void irlan_eth_flow_indication( void *instance, void *sap, LOCAL_FLOW flow);
void irlan_eth_send_gratuitous_arp(struct net_device *dev);
#endif

View File

@@ -0,0 +1,81 @@
/*********************************************************************
*
* Filename: irlan_event.h
* Version:
* Description: LAN access
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Aug 31 20:14:37 1997
* Modified at: Tue Feb 2 09:45:17 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAN_EVENT_H
#define IRLAN_EVENT_H
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <net/irda/irlan_common.h>
typedef enum {
IRLAN_IDLE,
IRLAN_QUERY,
IRLAN_CONN,
IRLAN_INFO,
IRLAN_MEDIA,
IRLAN_OPEN,
IRLAN_WAIT,
IRLAN_ARB,
IRLAN_DATA,
IRLAN_CLOSE,
IRLAN_SYNC
} IRLAN_STATE;
typedef enum {
IRLAN_DISCOVERY_INDICATION,
IRLAN_IAS_PROVIDER_AVAIL,
IRLAN_IAS_PROVIDER_NOT_AVAIL,
IRLAN_LAP_DISCONNECT,
IRLAN_LMP_DISCONNECT,
IRLAN_CONNECT_COMPLETE,
IRLAN_DATA_INDICATION,
IRLAN_DATA_CONNECT_INDICATION,
IRLAN_RETRY_CONNECT,
IRLAN_CONNECT_INDICATION,
IRLAN_GET_INFO_CMD,
IRLAN_GET_MEDIA_CMD,
IRLAN_OPEN_DATA_CMD,
IRLAN_FILTER_CONFIG_CMD,
IRLAN_CHECK_CON_ARB,
IRLAN_PROVIDER_SIGNAL,
IRLAN_WATCHDOG_TIMEOUT,
} IRLAN_EVENT;
extern char *irlan_state[];
void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event,
struct sk_buff *skb);
void irlan_do_provider_event(struct irlan_cb *self, IRLAN_EVENT event,
struct sk_buff *skb);
void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state);
void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state);
#endif

View File

@@ -0,0 +1,35 @@
/*********************************************************************
*
* Filename: irlan_filter.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Jan 29 15:24:08 1999
* Modified at: Sun Feb 7 23:35:31 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998 Dag Brattli, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAN_FILTER_H
#define IRLAN_FILTER_H
void irlan_check_command_param(struct irlan_cb *self, char *param,
char *value);
void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb);
#ifdef CONFIG_PROC_FS
void irlan_print_filter(struct seq_file *seq, int filter_type);
#endif
#endif /* IRLAN_FILTER_H */

View File

@@ -0,0 +1,52 @@
/*********************************************************************
*
* Filename: irlan_provider.h
* Version: 0.1
* Description: IrDA LAN access layer
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Aug 31 20:14:37 1997
* Modified at: Sun May 9 12:26:11 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAN_SERVER_H
#define IRLAN_SERVER_H
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/irda/irlan_common.h>
void irlan_provider_ctrl_disconnect_indication(void *instance, void *sap,
LM_REASON reason,
struct sk_buff *skb);
void irlan_provider_connect_response(struct irlan_cb *, struct tsap_cb *);
int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb);
int irlan_provider_parse_command(struct irlan_cb *self, int cmd,
struct sk_buff *skb);
void irlan_provider_send_reply(struct irlan_cb *self, int command,
int ret_code);
int irlan_provider_open_ctrl_tsap(struct irlan_cb *self);
#endif

292
include/net/irda/irlap.h Normal file
View File

@@ -0,0 +1,292 @@
/*********************************************************************
*
* Filename: irlap.h
* Version: 0.8
* Description: An IrDA LAP driver for Linux
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
* Modified at: Fri Dec 10 13:21:17 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLAP_H
#define IRLAP_H
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
#include <net/irda/irqueue.h> /* irda_queue_t */
#include <net/irda/qos.h> /* struct qos_info */
#include <net/irda/discovery.h> /* discovery_t */
#include <net/irda/irlap_event.h> /* IRLAP_STATE, ... */
#include <net/irda/irmod.h> /* struct notify_t */
#define CONFIG_IRDA_DYNAMIC_WINDOW 1
#define LAP_RELIABLE 1
#define LAP_UNRELIABLE 0
#define LAP_ADDR_HEADER 1 /* IrLAP Address Header */
#define LAP_CTRL_HEADER 1 /* IrLAP Control Header */
/* May be different when we get VFIR */
#define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
/* Each IrDA device gets a random 32 bits IRLAP device address */
#define LAP_ALEN 4
#define BROADCAST 0xffffffff /* Broadcast device address */
#define CBROADCAST 0xfe /* Connection broadcast address */
#define XID_FORMAT 0x01 /* Discovery XID format */
/* Nobody seems to use this constant. */
#define LAP_WINDOW_SIZE 8
/* We keep the LAP queue very small to minimise the amount of buffering.
* this improve latency and reduce resource consumption.
* This work only because we have synchronous refilling of IrLAP through
* the flow control mechanism (via scheduler and IrTTP).
* 2 buffers is the minimum we can work with, one that we send while polling
* IrTTP, and another to know that we should not send the pf bit.
* Jean II */
#define LAP_HIGH_THRESHOLD 2
/* Some rare non TTP clients don't implement flow control, and
* so don't comply with the above limit (and neither with this one).
* For IAP and management, it doesn't matter, because they never transmit much.
*.For IrLPT, this should be fixed.
* - Jean II */
#define LAP_MAX_QUEUE 10
/* Please note that all IrDA management frames (LMP/TTP conn req/disc and
* IAS queries) fall in the second category and are sent to LAP even if TTP
* is stopped. This means that those frames will wait only a maximum of
* two (2) data frames before beeing sent on the "wire", which speed up
* new socket setup when the link is saturated.
* Same story for two sockets competing for the medium : if one saturates
* the LAP, when the other want to transmit it only has to wait for
* maximum three (3) packets (2 + one scheduling), which improve performance
* of delay sensitive applications.
* Jean II */
#define NR_EXPECTED 1
#define NR_UNEXPECTED 0
#define NR_INVALID -1
#define NS_EXPECTED 1
#define NS_UNEXPECTED 0
#define NS_INVALID -1
/*
* Meta information passed within the IrLAP state machine
*/
struct irlap_info {
__u8 caddr; /* Connection address */
__u8 control; /* Frame type */
__u8 cmd;
__u32 saddr;
__u32 daddr;
int pf; /* Poll/final bit set */
__u8 nr; /* Sequence number of next frame expected */
__u8 ns; /* Sequence number of frame sent */
int S; /* Number of slots */
int slot; /* Random chosen slot */
int s; /* Current slot */
discovery_t *discovery; /* Discovery information */
};
/* Main structure of IrLAP */
struct irlap_cb {
irda_queue_t q; /* Must be first */
magic_t magic;
/* Device we are attached to */
struct net_device *netdev;
char hw_name[2*IFNAMSIZ + 1];
/* Connection state */
volatile IRLAP_STATE state; /* Current state */
/* Timers used by IrLAP */
struct timer_list query_timer;
struct timer_list slot_timer;
struct timer_list discovery_timer;
struct timer_list final_timer;
struct timer_list poll_timer;
struct timer_list wd_timer;
struct timer_list backoff_timer;
/* Media busy stuff */
struct timer_list media_busy_timer;
int media_busy;
/* Timeouts which will be different with different turn time */
int slot_timeout;
int poll_timeout;
int final_timeout;
int wd_timeout;
struct sk_buff_head txq; /* Frames to be transmitted */
struct sk_buff_head txq_ultra;
__u8 caddr; /* Connection address */
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
int retry_count; /* Times tried to establish connection */
int add_wait; /* True if we are waiting for frame */
__u8 connect_pending;
__u8 disconnect_pending;
/* To send a faster RR if tx queue empty */
#ifdef CONFIG_IRDA_FAST_RR
int fast_RR_timeout;
int fast_RR;
#endif /* CONFIG_IRDA_FAST_RR */
int N1; /* N1 * F-timer = Negitiated link disconnect warning threshold */
int N2; /* N2 * F-timer = Negitiated link disconnect time */
int N3; /* Connection retry count */
int local_busy;
int remote_busy;
int xmitflag;
__u8 vs; /* Next frame to be sent */
__u8 vr; /* Next frame to be received */
__u8 va; /* Last frame acked */
int window; /* Nr of I-frames allowed to send */
int window_size; /* Current negotiated window size */
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
__u32 line_capacity; /* Number of bytes allowed to send */
__u32 bytes_left; /* Number of bytes still allowed to transmit */
#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
struct sk_buff_head wx_list;
__u8 ack_required;
/* XID parameters */
__u8 S; /* Number of slots */
__u8 slot; /* Random chosen slot */
__u8 s; /* Current slot */
int frame_sent; /* Have we sent reply? */
hashbin_t *discovery_log;
discovery_t *discovery_cmd;
__u32 speed; /* Link speed */
struct qos_info qos_tx; /* QoS requested by peer */
struct qos_info qos_rx; /* QoS requested by self */
struct qos_info *qos_dev; /* QoS supported by device */
notify_t notify; /* Callbacks to IrLMP */
int mtt_required; /* Minumum turnaround time required */
int xbofs_delay; /* Nr of XBOF's used to MTT */
int bofs_count; /* Negotiated extra BOFs */
int next_bofs; /* Negotiated extra BOFs after next frame */
};
/*
* Function prototypes
*/
int irlap_init(void);
void irlap_cleanup(void);
struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
const char *hw_name);
void irlap_close(struct irlap_cb *self);
void irlap_connect_request(struct irlap_cb *self, __u32 daddr,
struct qos_info *qos, int sniff);
void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb);
void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb);
void irlap_connect_confirm(struct irlap_cb *, struct sk_buff *skb);
void irlap_data_indication(struct irlap_cb *, struct sk_buff *, int unreliable);
void irlap_data_request(struct irlap_cb *, struct sk_buff *, int unreliable);
#ifdef CONFIG_IRDA_ULTRA
void irlap_unitdata_request(struct irlap_cb *, struct sk_buff *);
void irlap_unitdata_indication(struct irlap_cb *, struct sk_buff *);
#endif /* CONFIG_IRDA_ULTRA */
void irlap_disconnect_request(struct irlap_cb *);
void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason);
void irlap_status_indication(struct irlap_cb *, int quality_of_link);
void irlap_test_request(__u8 *info, int len);
void irlap_discovery_request(struct irlap_cb *, discovery_t *discovery);
void irlap_discovery_confirm(struct irlap_cb *, hashbin_t *discovery_log);
void irlap_discovery_indication(struct irlap_cb *, discovery_t *discovery);
void irlap_reset_indication(struct irlap_cb *self);
void irlap_reset_confirm(void);
void irlap_update_nr_received(struct irlap_cb *, int nr);
int irlap_validate_nr_received(struct irlap_cb *, int nr);
int irlap_validate_ns_received(struct irlap_cb *, int ns);
int irlap_generate_rand_time_slot(int S, int s);
void irlap_initiate_connection_state(struct irlap_cb *);
void irlap_flush_all_queues(struct irlap_cb *);
void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *);
void irlap_apply_default_connection_parameters(struct irlap_cb *self);
void irlap_apply_connection_parameters(struct irlap_cb *self, int now);
#define IRLAP_GET_HEADER_SIZE(self) (LAP_MAX_HEADER)
#define IRLAP_GET_TX_QUEUE_LEN(self) skb_queue_len(&self->txq)
/* Return TRUE if the node is in primary mode (i.e. master)
* - Jean II */
static inline int irlap_is_primary(struct irlap_cb *self)
{
int ret;
switch(self->state) {
case LAP_XMIT_P:
case LAP_NRM_P:
ret = 1;
break;
case LAP_XMIT_S:
case LAP_NRM_S:
ret = 0;
break;
default:
ret = -1;
}
return(ret);
}
/* Clear a pending IrLAP disconnect. - Jean II */
static inline void irlap_clear_disconnect(struct irlap_cb *self)
{
self->disconnect_pending = FALSE;
}
#endif

View File

@@ -0,0 +1,131 @@
/*********************************************************************
*
*
* Filename: irlap_event.h
* Version: 0.1
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Aug 16 00:59:29 1997
* Modified at: Tue Dec 21 11:20:30 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRLAP_EVENT_H
#define IRLAP_EVENT_H
#include <net/irda/irda.h>
/* A few forward declarations (to make compiler happy) */
struct irlap_cb;
struct irlap_info;
/* IrLAP States */
typedef enum {
LAP_NDM, /* Normal disconnected mode */
LAP_QUERY,
LAP_REPLY,
LAP_CONN, /* Connect indication */
LAP_SETUP, /* Setting up connection */
LAP_OFFLINE, /* A really boring state */
LAP_XMIT_P,
LAP_PCLOSE,
LAP_NRM_P, /* Normal response mode as primary */
LAP_RESET_WAIT,
LAP_RESET,
LAP_NRM_S, /* Normal response mode as secondary */
LAP_XMIT_S,
LAP_SCLOSE,
LAP_RESET_CHECK,
} IRLAP_STATE;
/* IrLAP Events */
typedef enum {
/* Services events */
DISCOVERY_REQUEST,
CONNECT_REQUEST,
CONNECT_RESPONSE,
DISCONNECT_REQUEST,
DATA_REQUEST,
RESET_REQUEST,
RESET_RESPONSE,
/* Send events */
SEND_I_CMD,
SEND_UI_FRAME,
/* Receive events */
RECV_DISCOVERY_XID_CMD,
RECV_DISCOVERY_XID_RSP,
RECV_SNRM_CMD,
RECV_TEST_CMD,
RECV_TEST_RSP,
RECV_UA_RSP,
RECV_DM_RSP,
RECV_RD_RSP,
RECV_I_CMD,
RECV_I_RSP,
RECV_UI_FRAME,
RECV_FRMR_RSP,
RECV_RR_CMD,
RECV_RR_RSP,
RECV_RNR_CMD,
RECV_RNR_RSP,
RECV_REJ_CMD,
RECV_REJ_RSP,
RECV_SREJ_CMD,
RECV_SREJ_RSP,
RECV_DISC_CMD,
/* Timer events */
SLOT_TIMER_EXPIRED,
QUERY_TIMER_EXPIRED,
FINAL_TIMER_EXPIRED,
POLL_TIMER_EXPIRED,
DISCOVERY_TIMER_EXPIRED,
WD_TIMER_EXPIRED,
BACKOFF_TIMER_EXPIRED,
MEDIA_BUSY_TIMER_EXPIRED,
} IRLAP_EVENT;
/*
* Disconnect reason code
*/
typedef enum { /* FIXME check the two first reason codes */
LAP_DISC_INDICATION=1, /* Received a disconnect request from peer */
LAP_NO_RESPONSE, /* To many retransmits without response */
LAP_RESET_INDICATION, /* To many retransmits, or invalid nr/ns */
LAP_FOUND_NONE, /* No devices were discovered */
LAP_MEDIA_BUSY,
LAP_PRIMARY_CONFLICT,
} LAP_REASON;
extern const char *irlap_state[];
void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
struct sk_buff *skb, struct irlap_info *info);
void irlap_print_event(IRLAP_EVENT event);
extern int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb);
#endif

View File

@@ -0,0 +1,169 @@
/*********************************************************************
*
* Filename: irlap_frame.h
* Version: 0.9
* Description: IrLAP frame declarations
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Aug 19 10:27:26 1997
* Modified at: Sat Dec 25 21:07:26 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRLAP_FRAME_H
#define IRLAP_FRAME_H
#include <linux/skbuff.h>
#include <net/irda/irda.h>
/* A few forward declarations (to make compiler happy) */
struct irlap_cb;
struct discovery_t;
/* Frame types and templates */
#define INVALID 0xff
/* Unnumbered (U) commands */
#define SNRM_CMD 0x83 /* Set Normal Response Mode */
#define DISC_CMD 0x43 /* Disconnect */
#define XID_CMD 0x2f /* Exchange Station Identification */
#define TEST_CMD 0xe3 /* Test */
/* Unnumbered responses */
#define RNRM_RSP 0x83 /* Request Normal Response Mode */
#define UA_RSP 0x63 /* Unnumbered Acknowledgement */
#define FRMR_RSP 0x87 /* Frame Reject */
#define DM_RSP 0x0f /* Disconnect Mode */
#define RD_RSP 0x43 /* Request Disconnection */
#define XID_RSP 0xaf /* Exchange Station Identification */
#define TEST_RSP 0xe3 /* Test frame */
/* Supervisory (S) */
#define RR 0x01 /* Receive Ready */
#define REJ 0x09 /* Reject */
#define RNR 0x05 /* Receive Not Ready */
#define SREJ 0x0d /* Selective Reject */
/* Information (I) */
#define I_FRAME 0x00 /* Information Format */
#define UI_FRAME 0x03 /* Unnumbered Information */
#define CMD_FRAME 0x01
#define RSP_FRAME 0x00
#define PF_BIT 0x10 /* Poll/final bit */
/* Some IrLAP field lengths */
/*
* Only baud rate triplet is 4 bytes (PV can be 2 bytes).
* All others params (7) are 3 bytes, so that's 7*3 + 1*4 bytes.
*/
#define IRLAP_NEGOCIATION_PARAMS_LEN 25
#define IRLAP_DISCOVERY_INFO_LEN 32
struct disc_frame {
__u8 caddr; /* Connection address */
__u8 control;
} IRDA_PACK;
struct xid_frame {
__u8 caddr; /* Connection address */
__u8 control;
__u8 ident; /* Should always be XID_FORMAT */
__le32 saddr; /* Source device address */
__le32 daddr; /* Destination device address */
__u8 flags; /* Discovery flags */
__u8 slotnr;
__u8 version;
} IRDA_PACK;
struct test_frame {
__u8 caddr; /* Connection address */
__u8 control;
__le32 saddr; /* Source device address */
__le32 daddr; /* Destination device address */
} IRDA_PACK;
struct ua_frame {
__u8 caddr;
__u8 control;
__le32 saddr; /* Source device address */
__le32 daddr; /* Dest device address */
} IRDA_PACK;
struct dm_frame {
__u8 caddr; /* Connection address */
__u8 control;
} IRDA_PACK;
struct rd_frame {
__u8 caddr; /* Connection address */
__u8 control;
} IRDA_PACK;
struct rr_frame {
__u8 caddr; /* Connection address */
__u8 control;
} IRDA_PACK;
struct i_frame {
__u8 caddr;
__u8 control;
} IRDA_PACK;
struct snrm_frame {
__u8 caddr;
__u8 control;
__le32 saddr;
__le32 daddr;
__u8 ncaddr;
} IRDA_PACK;
void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);
void irlap_send_discovery_xid_frame(struct irlap_cb *, int S, __u8 s,
__u8 command,
struct discovery_t *discovery);
void irlap_send_snrm_frame(struct irlap_cb *, struct qos_info *);
void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
struct sk_buff *cmd);
void irlap_send_ua_response_frame(struct irlap_cb *, struct qos_info *);
void irlap_send_dm_frame(struct irlap_cb *self);
void irlap_send_rd_frame(struct irlap_cb *self);
void irlap_send_disc_frame(struct irlap_cb *self);
void irlap_send_rr_frame(struct irlap_cb *self, int command);
void irlap_send_data_primary(struct irlap_cb *, struct sk_buff *);
void irlap_send_data_primary_poll(struct irlap_cb *, struct sk_buff *);
void irlap_send_data_secondary(struct irlap_cb *, struct sk_buff *);
void irlap_send_data_secondary_final(struct irlap_cb *, struct sk_buff *);
void irlap_resend_rejected_frames(struct irlap_cb *, int command);
void irlap_resend_rejected_frame(struct irlap_cb *self, int command);
void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
__u8 caddr, int command);
extern int irlap_insert_qos_negotiation_params(struct irlap_cb *self,
struct sk_buff *skb);
#endif

294
include/net/irda/irlmp.h Normal file
View File

@@ -0,0 +1,294 @@
/*********************************************************************
*
* Filename: irlmp.h
* Version: 0.9
* Description: IrDA Link Management Protocol (LMP) layer
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Aug 17 20:54:32 1997
* Modified at: Fri Dec 10 13:23:01 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLMP_H
#define IRLMP_H
#include <asm/param.h> /* for HZ */
#include <linux/types.h>
#include <net/irda/irda.h>
#include <net/irda/qos.h>
#include <net/irda/irlap.h> /* LAP_MAX_HEADER, ... */
#include <net/irda/irlmp_event.h>
#include <net/irda/irqueue.h>
#include <net/irda/discovery.h>
/* LSAP-SEL's */
#define LSAP_MASK 0x7f
#define LSAP_IAS 0x00
#define LSAP_ANY 0xff
#define LSAP_MAX 0x6f /* 0x70-0x7f are reserved */
#define LSAP_CONNLESS 0x70 /* Connectionless LSAP, mostly used for Ultra */
#define DEV_ADDR_ANY 0xffffffff
#define LMP_HEADER 2 /* Dest LSAP + Source LSAP */
#define LMP_CONTROL_HEADER 4 /* LMP_HEADER + opcode + parameter */
#define LMP_PID_HEADER 1 /* Used by Ultra */
#define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER)
#define LM_MAX_CONNECTIONS 10
#define LM_IDLE_TIMEOUT 2*HZ /* 2 seconds for now */
typedef enum {
S_PNP = 0,
S_PDA,
S_COMPUTER,
S_PRINTER,
S_MODEM,
S_FAX,
S_LAN,
S_TELEPHONY,
S_COMM,
S_OBEX,
S_ANY,
S_END,
} SERVICE;
/* For selective discovery */
typedef void (*DISCOVERY_CALLBACK1) (discinfo_t *, DISCOVERY_MODE, void *);
/* For expiry (the same) */
typedef void (*DISCOVERY_CALLBACK2) (discinfo_t *, DISCOVERY_MODE, void *);
typedef struct {
irda_queue_t queue; /* Must be first */
__u16_host_order hints; /* Hint bits */
} irlmp_service_t;
typedef struct {
irda_queue_t queue; /* Must be first */
__u16_host_order hint_mask;
DISCOVERY_CALLBACK1 disco_callback; /* Selective discovery */
DISCOVERY_CALLBACK2 expir_callback; /* Selective expiration */
void *priv; /* Used to identify client */
} irlmp_client_t;
/*
* Information about each logical LSAP connection
*/
struct lsap_cb {
irda_queue_t queue; /* Must be first */
magic_t magic;
unsigned long connected; /* set_bit used on this */
int persistent;
__u8 slsap_sel; /* Source (this) LSAP address */
__u8 dlsap_sel; /* Destination LSAP address (if connected) */
#ifdef CONFIG_IRDA_ULTRA
__u8 pid; /* Used by connectionless LSAP */
#endif /* CONFIG_IRDA_ULTRA */
struct sk_buff *conn_skb; /* Store skb here while connecting */
struct timer_list watchdog_timer;
LSAP_STATE lsap_state; /* Connection state */
notify_t notify; /* Indication/Confirm entry points */
struct qos_info qos; /* QoS for this connection */
struct lap_cb *lap; /* Pointer to LAP connection structure */
};
/*
* Used for caching the last slsap->dlsap->handle mapping
*
* We don't need to keep/match the remote address in the cache because
* we are associated with a specific LAP (which implies it).
* Jean II
*/
typedef struct {
int valid;
__u8 slsap_sel;
__u8 dlsap_sel;
struct lsap_cb *lsap;
} CACHE_ENTRY;
/*
* Information about each registred IrLAP layer
*/
struct lap_cb {
irda_queue_t queue; /* Must be first */
magic_t magic;
int reason; /* LAP disconnect reason */
IRLMP_STATE lap_state;
struct irlap_cb *irlap; /* Instance of IrLAP layer */
hashbin_t *lsaps; /* LSAP associated with this link */
struct lsap_cb *flow_next; /* Next lsap to be polled for Tx */
__u8 caddr; /* Connection address */
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
struct qos_info *qos; /* LAP QoS for this session */
struct timer_list idle_timer;
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
/* The lsap cache was moved from struct irlmp_cb to here because
* it must be associated with the specific LAP. Also, this
* improves performance. - Jean II */
CACHE_ENTRY cache; /* Caching last slsap->dlsap->handle mapping */
#endif
};
/*
* Main structure for IrLMP
*/
struct irlmp_cb {
magic_t magic;
__u8 conflict_flag;
discovery_t discovery_cmd; /* Discovery command to use by IrLAP */
discovery_t discovery_rsp; /* Discovery response to use by IrLAP */
/* Last lsap picked automatically by irlmp_find_free_slsap() */
int last_lsap_sel;
struct timer_list discovery_timer;
hashbin_t *links; /* IrLAP connection table */
hashbin_t *unconnected_lsaps;
hashbin_t *clients;
hashbin_t *services;
hashbin_t *cachelog; /* Current discovery log */
int running;
__u16_host_order hints; /* Hint bits */
};
/* Prototype declarations */
int irlmp_init(void);
void irlmp_cleanup(void);
struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid);
void irlmp_close_lsap( struct lsap_cb *self);
__u16 irlmp_service_to_hint(int service);
void *irlmp_register_service(__u16 hints);
int irlmp_unregister_service(void *handle);
void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
DISCOVERY_CALLBACK2 expir_clb, void *priv);
int irlmp_unregister_client(void *handle);
int irlmp_update_client(void *handle, __u16 hint_mask,
DISCOVERY_CALLBACK1 disco_clb,
DISCOVERY_CALLBACK2 expir_clb, void *priv);
void irlmp_register_link(struct irlap_cb *, __u32 saddr, notify_t *);
void irlmp_unregister_link(__u32 saddr);
int irlmp_connect_request(struct lsap_cb *, __u8 dlsap_sel,
__u32 saddr, __u32 daddr,
struct qos_info *, struct sk_buff *);
void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb);
int irlmp_connect_response(struct lsap_cb *, struct sk_buff *);
void irlmp_connect_confirm(struct lsap_cb *, struct sk_buff *);
struct lsap_cb *irlmp_dup(struct lsap_cb *self, void *instance);
void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
struct sk_buff *userdata);
int irlmp_disconnect_request(struct lsap_cb *, struct sk_buff *userdata);
void irlmp_discovery_confirm(hashbin_t *discovery_log, DISCOVERY_MODE mode);
void irlmp_discovery_request(int nslots);
discinfo_t *irlmp_get_discoveries(int *pn, __u16 mask, int nslots);
void irlmp_do_expiry(void);
void irlmp_do_discovery(int nslots);
discovery_t *irlmp_get_discovery_response(void);
void irlmp_discovery_expiry(discinfo_t *expiry, int number);
int irlmp_data_request(struct lsap_cb *, struct sk_buff *);
void irlmp_data_indication(struct lsap_cb *, struct sk_buff *);
int irlmp_udata_request(struct lsap_cb *, struct sk_buff *);
void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *);
#ifdef CONFIG_IRDA_ULTRA
int irlmp_connless_data_request(struct lsap_cb *, struct sk_buff *, __u8);
void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *);
#endif /* CONFIG_IRDA_ULTRA */
void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock);
void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow);
LM_REASON irlmp_convert_lap_reason(LAP_REASON);
static inline __u32 irlmp_get_saddr(const struct lsap_cb *self)
{
return (self && self->lap) ? self->lap->saddr : 0;
}
static inline __u32 irlmp_get_daddr(const struct lsap_cb *self)
{
return (self && self->lap) ? self->lap->daddr : 0;
}
extern const char *irlmp_reasons[];
extern int sysctl_discovery_timeout;
extern int sysctl_discovery_slots;
extern int sysctl_discovery;
extern int sysctl_lap_keepalive_time; /* in ms, default is LM_IDLE_TIMEOUT */
extern struct irlmp_cb *irlmp;
/* Check if LAP queue is full.
* Used by IrTTP for low control, see comments in irlap.h - Jean II */
static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self)
{
if (self == NULL)
return 0;
if (self->lap == NULL)
return 0;
if (self->lap->irlap == NULL)
return 0;
return(IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD);
}
/* After doing a irlmp_dup(), this get one of the two socket back into
* a state where it's waiting incomming connections.
* Note : this can be used *only* if the socket is not yet connected
* (i.e. NO irlmp_connect_response() done on this socket).
* - Jean II */
static inline void irlmp_listen(struct lsap_cb *self)
{
self->dlsap_sel = LSAP_ANY;
self->lap = NULL;
self->lsap_state = LSAP_DISCONNECTED;
/* Started when we received the LM_CONNECT_INDICATION */
del_timer(&self->watchdog_timer);
}
#endif

View File

@@ -0,0 +1,98 @@
/*********************************************************************
*
* Filename: irlmp_event.h
* Version: 0.1
* Description: IrDA-LMP event handling
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
* Modified at: Thu Jul 8 12:18:54 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRLMP_EVENT_H
#define IRLMP_EVENT_H
/* A few forward declarations (to make compiler happy) */
struct irlmp_cb;
struct lsap_cb;
struct lap_cb;
struct discovery_t;
/* LAP states */
typedef enum {
/* IrLAP connection control states */
LAP_STANDBY, /* No LAP connection */
LAP_U_CONNECT, /* Starting LAP connection */
LAP_ACTIVE, /* LAP connection is active */
} IRLMP_STATE;
/* LSAP connection control states */
typedef enum {
LSAP_DISCONNECTED, /* No LSAP connection */
LSAP_CONNECT, /* Connect indication from peer */
LSAP_CONNECT_PEND, /* Connect request from service user */
LSAP_DATA_TRANSFER_READY, /* LSAP connection established */
LSAP_SETUP, /* Trying to set up LSAP connection */
LSAP_SETUP_PEND, /* Request to start LAP connection */
} LSAP_STATE;
typedef enum {
/* LSAP events */
LM_CONNECT_REQUEST,
LM_CONNECT_CONFIRM,
LM_CONNECT_RESPONSE,
LM_CONNECT_INDICATION,
LM_DISCONNECT_INDICATION,
LM_DISCONNECT_REQUEST,
LM_DATA_REQUEST,
LM_UDATA_REQUEST,
LM_DATA_INDICATION,
LM_UDATA_INDICATION,
LM_WATCHDOG_TIMEOUT,
/* IrLAP events */
LM_LAP_CONNECT_REQUEST,
LM_LAP_CONNECT_INDICATION,
LM_LAP_CONNECT_CONFIRM,
LM_LAP_DISCONNECT_INDICATION,
LM_LAP_DISCONNECT_REQUEST,
LM_LAP_DISCOVERY_REQUEST,
LM_LAP_DISCOVERY_CONFIRM,
LM_LAP_IDLE_TIMEOUT,
} IRLMP_EVENT;
extern const char *irlmp_state[];
extern const char *irlsap_state[];
void irlmp_watchdog_timer_expired(void *data);
void irlmp_discovery_timer_expired(void *data);
void irlmp_idle_timer_expired(void *data);
void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event,
struct sk_buff *skb);
int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event,
struct sk_buff *skb);
#endif /* IRLMP_EVENT_H */

View File

@@ -0,0 +1,62 @@
/*********************************************************************
*
* Filename: irlmp_frame.h
* Version: 0.9
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Aug 19 02:09:59 1997
* Modified at: Fri Dec 10 13:21:53 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRMLP_FRAME_H
#define IRMLP_FRAME_H
#include <linux/skbuff.h>
#include <net/irda/discovery.h>
/* IrLMP frame opcodes */
#define CONNECT_CMD 0x01
#define CONNECT_CNF 0x81
#define DISCONNECT 0x02
#define ACCESSMODE_CMD 0x03
#define ACCESSMODE_CNF 0x83
#define CONTROL_BIT 0x80
void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
int expedited, struct sk_buff *skb);
void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
__u8 opcode, struct sk_buff *skb);
void irlmp_link_data_indication(struct lap_cb *, struct sk_buff *,
int unreliable);
#ifdef CONFIG_IRDA_ULTRA
void irlmp_link_unitdata_indication(struct lap_cb *, struct sk_buff *);
#endif /* CONFIG_IRDA_ULTRA */
void irlmp_link_connect_indication(struct lap_cb *, __u32 saddr, __u32 daddr,
struct qos_info *qos, struct sk_buff *skb);
void irlmp_link_connect_request(__u32 daddr);
void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos,
struct sk_buff *skb);
void irlmp_link_disconnect_indication(struct lap_cb *, struct irlap_cb *,
LAP_REASON reason, struct sk_buff *);
void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log);
void irlmp_link_discovery_indication(struct lap_cb *, discovery_t *discovery);
#endif

109
include/net/irda/irmod.h Normal file
View File

@@ -0,0 +1,109 @@
/*********************************************************************
*
* Filename: irmod.h
* Version: 0.3
* Description: IrDA module and utilities functions
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Dec 15 13:58:52 1997
* Modified at: Fri Jan 28 13:15:24 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charg.
*
********************************************************************/
#ifndef IRMOD_H
#define IRMOD_H
/* Misc status information */
typedef enum {
STATUS_OK,
STATUS_ABORTED,
STATUS_NO_ACTIVITY,
STATUS_NOISY,
STATUS_REMOTE,
} LINK_STATUS;
typedef enum {
LOCK_NO_CHANGE,
LOCK_LOCKED,
LOCK_UNLOCKED,
} LOCK_STATUS;
typedef enum { FLOW_STOP, FLOW_START } LOCAL_FLOW;
/*
* IrLMP disconnect reasons. The order is very important, since they
* correspond to disconnect reasons sent in IrLMP disconnect frames, so
* please do not touch :-)
*/
typedef enum {
LM_USER_REQUEST = 1, /* User request */
LM_LAP_DISCONNECT, /* Unexpected IrLAP disconnect */
LM_CONNECT_FAILURE, /* Failed to establish IrLAP connection */
LM_LAP_RESET, /* IrLAP reset */
LM_INIT_DISCONNECT, /* Link Management initiated disconnect */
LM_LSAP_NOTCONN, /* Data delivered on unconnected LSAP */
LM_NON_RESP_CLIENT, /* Non responsive LM-MUX client */
LM_NO_AVAIL_CLIENT, /* No available LM-MUX client */
LM_CONN_HALF_OPEN, /* Connection is half open */
LM_BAD_SOURCE_ADDR, /* Illegal source address (i.e 0x00) */
} LM_REASON;
#define LM_UNKNOWN 0xff /* Unspecified disconnect reason */
/* A few forward declarations (to make compiler happy) */
struct qos_info; /* in <net/irda/qos.h> */
/*
* Notify structure used between transport and link management layers
*/
typedef struct {
int (*data_indication)(void *priv, void *sap, struct sk_buff *skb);
int (*udata_indication)(void *priv, void *sap, struct sk_buff *skb);
void (*connect_confirm)(void *instance, void *sap,
struct qos_info *qos, __u32 max_sdu_size,
__u8 max_header_size, struct sk_buff *skb);
void (*connect_indication)(void *instance, void *sap,
struct qos_info *qos, __u32 max_sdu_size,
__u8 max_header_size, struct sk_buff *skb);
void (*disconnect_indication)(void *instance, void *sap,
LM_REASON reason, struct sk_buff *);
void (*flow_indication)(void *instance, void *sap, LOCAL_FLOW flow);
void (*status_indication)(void *instance,
LINK_STATUS link, LOCK_STATUS lock);
void *instance; /* Layer instance pointer */
char name[16]; /* Name of layer */
} notify_t;
#define NOTIFY_MAX_NAME 16
/* Zero the notify structure */
void irda_notify_init(notify_t *notify);
/* Locking wrapper - Note the inverted logic on irda_lock().
* Those function basically return false if the lock is already in the
* position you want to set it. - Jean II */
#define irda_lock(lock) (! test_and_set_bit(0, (void *) (lock)))
#define irda_unlock(lock) (test_and_clear_bit(0, (void *) (lock)))
#endif /* IRMOD_H */

View File

@@ -0,0 +1,96 @@
/*********************************************************************
*
* Filename: irqueue.h
* Version: 0.3
* Description: General queue implementation
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Jun 9 13:26:50 1998
* Modified at: Thu Oct 7 13:25:16 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (C) 1998-1999, Aage Kvalnes <aage@cs.uit.no>
* Copyright (c) 1998, Dag Brattli
* All Rights Reserved.
*
* This code is taken from the Vortex Operating System written by Aage
* Kvalnes and has been ported to Linux and Linux/IR by Dag Brattli
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#include <linux/types.h>
#include <linux/spinlock.h>
#ifndef IRDA_QUEUE_H
#define IRDA_QUEUE_H
#define NAME_SIZE 32
/*
* Hash types (some flags can be xored)
* See comments in irqueue.c for which one to use...
*/
#define HB_NOLOCK 0 /* No concurent access prevention */
#define HB_LOCK 1 /* Prevent concurent write with global lock */
/*
* Hash defines
*/
#define HASHBIN_SIZE 8
#define HASHBIN_MASK 0x7
#ifndef IRDA_ALIGN
#define IRDA_ALIGN __attribute__((aligned))
#endif
#define Q_NULL { NULL, NULL, "", 0 }
typedef void (*FREE_FUNC)(void *arg);
struct irda_queue {
struct irda_queue *q_next;
struct irda_queue *q_prev;
char q_name[NAME_SIZE];
long q_hash; /* Must be able to cast a (void *) */
};
typedef struct irda_queue irda_queue_t;
typedef struct hashbin_t {
__u32 magic;
int hb_type;
int hb_size;
spinlock_t hb_spinlock; /* HB_LOCK - Can be used by the user */
irda_queue_t* hb_queue[HASHBIN_SIZE] IRDA_ALIGN;
irda_queue_t* hb_current;
} hashbin_t;
hashbin_t *hashbin_new(int type);
int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func);
int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func);
void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv,
const char* name);
void* hashbin_remove(hashbin_t* hashbin, long hashv, const char* name);
void* hashbin_remove_first(hashbin_t *hashbin);
void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry);
void* hashbin_find(hashbin_t* hashbin, long hashv, const char* name);
void* hashbin_lock_find(hashbin_t* hashbin, long hashv, const char* name);
void* hashbin_find_next(hashbin_t* hashbin, long hashv, const char* name,
void ** pnext);
irda_queue_t *hashbin_get_first(hashbin_t *hashbin);
irda_queue_t *hashbin_get_next(hashbin_t *hashbin);
#define HASHBIN_GET_SIZE(hashbin) hashbin->hb_size
#endif

210
include/net/irda/irttp.h Normal file
View File

@@ -0,0 +1,210 @@
/*********************************************************************
*
* Filename: irttp.h
* Version: 1.0
* Description: Tiny Transport Protocol (TTP) definitions
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sun Aug 31 20:14:31 1997
* Modified at: Sun Dec 12 13:09:07 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef IRTTP_H
#define IRTTP_H
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <net/irda/irda.h>
#include <net/irda/irlmp.h> /* struct lsap_cb */
#include <net/irda/qos.h> /* struct qos_info */
#include <net/irda/irqueue.h>
#define TTP_MAX_CONNECTIONS LM_MAX_CONNECTIONS
#define TTP_HEADER 1
#define TTP_MAX_HEADER (TTP_HEADER + LMP_MAX_HEADER)
#define TTP_SAR_HEADER 5
#define TTP_PARAMETERS 0x80
#define TTP_MORE 0x80
/* Transmission queue sizes */
/* Worst case scenario, two window of data - Jean II */
#define TTP_TX_MAX_QUEUE 14
/* We need to keep at least 5 frames to make sure that we can refill
* appropriately the LAP layer. LAP keeps only two buffers, and we need
* to have 7 to make a full window - Jean II */
#define TTP_TX_LOW_THRESHOLD 5
/* Most clients are synchronous with respect to flow control, so we can
* keep a low number of Tx buffers in TTP - Jean II */
#define TTP_TX_HIGH_THRESHOLD 7
/* Receive queue sizes */
/* Minimum of credit that the peer should hold.
* If the peer has less credits than 9 frames, we will explicitely send
* him some credits (through irttp_give_credit() and a specific frame).
* Note that when we give credits it's likely that it won't be sent in
* this LAP window, but in the next one. So, we make sure that the peer
* has something to send while waiting for credits (one LAP window == 7
* + 1 frames while he process the credits). - Jean II */
#define TTP_RX_MIN_CREDIT 8
/* This is the default maximum number of credits held by the peer, so the
* default maximum number of frames he can send us before needing flow
* control answer from us (this may be negociated differently at TSAP setup).
* We want to minimise the number of times we have to explicitely send some
* credit to the peer, hoping we can piggyback it on the return data. In
* particular, it doesn't make sense for us to send credit more than once
* per LAP window.
* Moreover, giving credits has some latency, so we need strictly more than
* a LAP window, otherwise we may already have credits in our Tx queue.
* But on the other hand, we don't want to keep too many Rx buffer here
* before starting to flow control the other end, so make it exactly one
* LAP window + 1 + MIN_CREDITS. - Jean II */
#define TTP_RX_DEFAULT_CREDIT 16
/* Maximum number of credits we can allow the peer to have, and therefore
* maximum Rx queue size.
* Note that we try to deliver packets to the higher layer every time we
* receive something, so in normal mode the Rx queue will never contains
* more than one or two packets. - Jean II */
#define TTP_RX_MAX_CREDIT 21
/* What clients should use when calling ttp_open_tsap() */
#define DEFAULT_INITIAL_CREDIT TTP_RX_DEFAULT_CREDIT
/* Some priorities for disconnect requests */
#define P_NORMAL 0
#define P_HIGH 1
#define TTP_SAR_DISABLE 0
#define TTP_SAR_UNBOUND 0xffffffff
/* Parameters */
#define TTP_MAX_SDU_SIZE 0x01
/*
* This structure contains all data assosiated with one instance of a TTP
* connection.
*/
struct tsap_cb {
irda_queue_t q; /* Must be first */
magic_t magic; /* Just in case */
__u8 stsap_sel; /* Source TSAP */
__u8 dtsap_sel; /* Destination TSAP */
struct lsap_cb *lsap; /* Corresponding LSAP to this TSAP */
__u8 connected; /* TSAP connected */
__u8 initial_credit; /* Initial credit to give peer */
int avail_credit; /* Available credit to return to peer */
int remote_credit; /* Credit held by peer TTP entity */
int send_credit; /* Credit held by local TTP entity */
struct sk_buff_head tx_queue; /* Frames to be transmitted */
struct sk_buff_head rx_queue; /* Received frames */
struct sk_buff_head rx_fragments;
int tx_queue_lock;
int rx_queue_lock;
spinlock_t lock;
notify_t notify; /* Callbacks to client layer */
struct net_device_stats stats;
struct timer_list todo_timer;
__u32 max_seg_size; /* Max data that fit into an IrLAP frame */
__u8 max_header_size;
int rx_sdu_busy; /* RxSdu.busy */
__u32 rx_sdu_size; /* Current size of a partially received frame */
__u32 rx_max_sdu_size; /* Max receive user data size */
int tx_sdu_busy; /* TxSdu.busy */
__u32 tx_max_sdu_size; /* Max transmit user data size */
int close_pend; /* Close, but disconnect_pend */
unsigned long disconnect_pend; /* Disconnect, but still data to send */
struct sk_buff *disconnect_skb;
};
struct irttp_cb {
magic_t magic;
hashbin_t *tsaps;
};
int irttp_init(void);
void irttp_cleanup(void);
struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify);
int irttp_close_tsap(struct tsap_cb *self);
int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb);
int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb);
int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
__u32 saddr, __u32 daddr,
struct qos_info *qos, __u32 max_sdu_size,
struct sk_buff *userdata);
int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
struct sk_buff *userdata);
int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb,
int priority);
void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow);
struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance);
static __inline __u32 irttp_get_saddr(struct tsap_cb *self)
{
return irlmp_get_saddr(self->lsap);
}
static __inline __u32 irttp_get_daddr(struct tsap_cb *self)
{
return irlmp_get_daddr(self->lsap);
}
static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self)
{
return self->max_seg_size;
}
/* After doing a irttp_dup(), this get one of the two socket back into
* a state where it's waiting incomming connections.
* Note : this can be used *only* if the socket is not yet connected
* (i.e. NO irttp_connect_response() done on this socket).
* - Jean II */
static inline void irttp_listen(struct tsap_cb *self)
{
irlmp_listen(self->lsap);
self->dtsap_sel = LSAP_ANY;
}
/* Return TRUE if the node is in primary mode (i.e. master)
* - Jean II */
static inline int irttp_is_primary(struct tsap_cb *self)
{
if ((self == NULL) ||
(self->lsap == NULL) ||
(self->lsap->lap == NULL) ||
(self->lsap->lap->irlap == NULL))
return -2;
return(irlap_is_primary(self->lsap->lap->irlap));
}
#endif /* IRTTP_H */

View File

@@ -0,0 +1,102 @@
/*********************************************************************
*
* Filename: parameters.h
* Version: 1.0
* Description: A more general way to handle (pi,pl,pv) parameters
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Jun 7 08:47:28 1999
* Modified at: Sun Jan 30 14:05:14 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Michel D<>nzer <daenzer@debian.org>, 10/2001
* - simplify irda_pv_t to avoid endianness issues
*
********************************************************************/
#ifndef IRDA_PARAMS_H
#define IRDA_PARAMS_H
/*
* The currently supported types. Beware not to change the sequence since
* it a good reason why the sized integers has a value equal to their size
*/
typedef enum {
PV_INTEGER, /* Integer of any (pl) length */
PV_INT_8_BITS, /* Integer of 8 bits in length */
PV_INT_16_BITS, /* Integer of 16 bits in length */
PV_STRING, /* \0 terminated string */
PV_INT_32_BITS, /* Integer of 32 bits in length */
PV_OCT_SEQ, /* Octet sequence */
PV_NO_VALUE /* Does not contain any value (pl=0) */
} PV_TYPE;
/* Bit 7 of type field */
#define PV_BIG_ENDIAN 0x80
#define PV_LITTLE_ENDIAN 0x00
#define PV_MASK 0x7f /* To mask away endian bit */
#define PV_PUT 0
#define PV_GET 1
typedef union {
char *c;
__u32 i;
__u32 *ip;
} irda_pv_t;
typedef struct {
__u8 pi;
__u8 pl;
irda_pv_t pv;
} irda_param_t;
typedef int (*PI_HANDLER)(void *self, irda_param_t *param, int get);
typedef int (*PV_HANDLER)(void *self, __u8 *buf, int len, __u8 pi,
PV_TYPE type, PI_HANDLER func);
typedef struct {
PI_HANDLER func; /* Handler for this parameter identifier */
PV_TYPE type; /* Data type for this parameter */
} pi_minor_info_t;
typedef struct {
pi_minor_info_t *pi_minor_call_table;
int len;
} pi_major_info_t;
typedef struct {
pi_major_info_t *tables;
int len;
__u8 pi_mask;
int pi_major_offset;
} pi_param_info_t;
int irda_param_pack(__u8 *buf, char *fmt, ...);
int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len,
pi_param_info_t *info);
int irda_param_extract_all(void *self, __u8 *buf, int len,
pi_param_info_t *info);
#define irda_param_insert_byte(buf,pi,pv) irda_param_pack(buf,"bbb",pi,1,pv)
#endif /* IRDA_PARAMS_H */

103
include/net/irda/qos.h Normal file
View File

@@ -0,0 +1,103 @@
/*********************************************************************
*
* Filename: qos.h
* Version: 1.0
* Description: Quality of Service definitions
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Sep 19 23:21:09 1997
* Modified at: Thu Dec 2 13:51:54 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************/
#ifndef IRDA_QOS_H
#define IRDA_QOS_H
#include <linux/skbuff.h>
#include <net/irda/parameters.h>
#define PI_BAUD_RATE 0x01
#define PI_MAX_TURN_TIME 0x82
#define PI_DATA_SIZE 0x83
#define PI_WINDOW_SIZE 0x84
#define PI_ADD_BOFS 0x85
#define PI_MIN_TURN_TIME 0x86
#define PI_LINK_DISC 0x08
#define IR_115200_MAX 0x3f
/* Baud rates (first byte) */
#define IR_2400 0x01
#define IR_9600 0x02
#define IR_19200 0x04
#define IR_38400 0x08
#define IR_57600 0x10
#define IR_115200 0x20
#define IR_576000 0x40
#define IR_1152000 0x80
/* Baud rates (second byte) */
#define IR_4000000 0x01
#define IR_16000000 0x02
/* Quality of Service information */
typedef struct {
__u32 value;
__u16 bits; /* LSB is first byte, MSB is second byte */
} qos_value_t;
struct qos_info {
magic_t magic;
qos_value_t baud_rate; /* IR_11520O | ... */
qos_value_t max_turn_time;
qos_value_t data_size;
qos_value_t window_size;
qos_value_t additional_bofs;
qos_value_t min_turn_time;
qos_value_t link_disc_time;
qos_value_t power;
};
extern int sysctl_max_baud_rate;
extern int sysctl_max_inactive_time;
void irda_init_max_qos_capabilies(struct qos_info *qos);
void irda_qos_compute_intersection(struct qos_info *, struct qos_info *);
__u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time);
void irda_qos_bits_to_value(struct qos_info *qos);
/* So simple, how could we not inline those two ?
* Note : one byte is 10 bits if you include start and stop bits
* Jean II */
#define irlap_min_turn_time_in_bytes(speed, min_turn_time) ( \
speed * min_turn_time / 10000000 \
)
#define irlap_xbofs_in_usec(speed, xbofs) ( \
xbofs * 10000000 / speed \
)
#endif

105
include/net/irda/timer.h Normal file
View File

@@ -0,0 +1,105 @@
/*********************************************************************
*
* Filename: timer.h
* Version:
* Description:
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Aug 16 00:59:29 1997
* Modified at: Thu Oct 7 12:25:24 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef TIMER_H
#define TIMER_H
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <asm/param.h> /* for HZ */
#include <net/irda/irda.h>
/* A few forward declarations (to make compiler happy) */
struct irlmp_cb;
struct irlap_cb;
struct lsap_cb;
struct lap_cb;
/*
* Timeout definitions, some defined in IrLAP 6.13.5 - p. 92
*/
#define POLL_TIMEOUT (450*HZ/1000) /* Must never exceed 500 ms */
#define FINAL_TIMEOUT (500*HZ/1000) /* Must never exceed 500 ms */
/*
* Normally twice of p-timer. Note 3, IrLAP 6.3.11.2 - p. 60 suggests
* at least twice duration of the P-timer.
*/
#define WD_TIMEOUT (POLL_TIMEOUT*2)
#define MEDIABUSY_TIMEOUT (500*HZ/1000) /* 500 msec */
#define SMALLBUSY_TIMEOUT (100*HZ/1000) /* 100 msec - IrLAP 6.13.4 */
/*
* Slot timer must never exceed 85 ms, and must always be at least 25 ms,
* suggested to 75-85 msec by IrDA lite. This doesn't work with a lot of
* devices, and other stackes uses a lot more, so it's best we do it as well
* (Note : this is the default value and sysctl overides it - Jean II)
*/
#define SLOT_TIMEOUT (90*HZ/1000)
/*
* The latest discovery frame (XID) is longer due to the extra discovery
* information (hints, device name...). This is its extra length.
* We use that when setting the query timeout. Jean II
*/
#define XIDEXTRA_TIMEOUT (34*HZ/1000) /* 34 msec */
#define WATCHDOG_TIMEOUT (20*HZ) /* 20 sec */
typedef void (*TIMER_CALLBACK)(void *);
static inline void irda_start_timer(struct timer_list *ptimer, int timeout,
void* data, TIMER_CALLBACK callback)
{
ptimer->function = (void (*)(unsigned long)) callback;
ptimer->data = (unsigned long) data;
/* Set new value for timer (update or add timer).
* We use mod_timer() because it's more efficient and also
* safer with respect to race conditions - Jean II */
mod_timer(ptimer, jiffies + timeout);
}
void irlap_start_slot_timer(struct irlap_cb *self, int timeout);
void irlap_start_query_timer(struct irlap_cb *self, int S, int s);
void irlap_start_final_timer(struct irlap_cb *self, int timeout);
void irlap_start_wd_timer(struct irlap_cb *self, int timeout);
void irlap_start_backoff_timer(struct irlap_cb *self, int timeout);
void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout);
void irlap_stop_mbusy_timer(struct irlap_cb *);
void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout);
void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout);
void irlmp_start_idle_timer(struct lap_cb *, int timeout);
void irlmp_stop_idle_timer(struct lap_cb *self);
#endif

View File

@@ -0,0 +1,58 @@
/*********************************************************************
*
* Filename: wrapper.h
* Version: 1.2
* Description: IrDA SIR async wrapper layer
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
* Modified at: Tue Jan 11 12:37:29 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
*
* 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.
*
* Neither Dag Brattli nor University of Troms<6D> admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
#ifndef WRAPPER_H
#define WRAPPER_H
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/irda/irda_device.h> /* iobuff_t */
#define BOF 0xc0 /* Beginning of frame */
#define XBOF 0xff
#define EOF 0xc1 /* End of frame */
#define CE 0x7d /* Control escape */
#define STA BOF /* Start flag */
#define STO EOF /* End flag */
#define IRDA_TRANS 0x20 /* Asynchronous transparency modifier */
/* States for receving a frame in async mode */
enum {
OUTSIDE_FRAME,
BEGIN_FRAME,
LINK_ESCAPE,
INSIDE_FRAME
};
/* Proto definitions */
int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize);
void async_unwrap_char(struct net_device *dev, struct net_device_stats *stats,
iobuff_t *buf, __u8 byte);
#endif

106
include/net/iucv/af_iucv.h Normal file
View File

@@ -0,0 +1,106 @@
/*
* Copyright 2006 IBM Corporation
* IUCV protocol stack for Linux on zSeries
* Version 1.0
* Author(s): Jennifer Hunt <jenhunt@us.ibm.com>
*
*/
#ifndef __AFIUCV_H
#define __AFIUCV_H
#include <asm/types.h>
#include <asm/byteorder.h>
#include <linux/list.h>
#include <linux/poll.h>
#include <linux/socket.h>
#ifndef AF_IUCV
#define AF_IUCV 32
#define PF_IUCV AF_IUCV
#endif
/* Connection and socket states */
enum {
IUCV_CONNECTED = 1,
IUCV_OPEN,
IUCV_BOUND,
IUCV_LISTEN,
IUCV_SEVERED,
IUCV_DISCONN,
IUCV_CLOSED
};
#define IUCV_QUEUELEN_DEFAULT 65535
#define IUCV_CONN_TIMEOUT (HZ * 40)
#define IUCV_DISCONN_TIMEOUT (HZ * 2)
#define IUCV_CONN_IDLE_TIMEOUT (HZ * 60)
#define IUCV_BUFSIZE_DEFAULT 32768
/* IUCV socket address */
struct sockaddr_iucv {
sa_family_t siucv_family;
unsigned short siucv_port; /* Reserved */
unsigned int siucv_addr; /* Reserved */
char siucv_nodeid[8]; /* Reserved */
char siucv_user_id[8]; /* Guest User Id */
char siucv_name[8]; /* Application Name */
};
/* Common socket structures and functions */
#define iucv_sk(__sk) ((struct iucv_sock *) __sk)
struct iucv_sock {
struct sock sk;
char src_user_id[8];
char src_name[8];
char dst_user_id[8];
char dst_name[8];
struct list_head accept_q;
struct sock *parent;
struct iucv_path *path;
struct sk_buff_head send_skb_q;
unsigned int send_tag;
};
struct iucv_sock_list {
struct hlist_head head;
rwlock_t lock;
atomic_t autobind_name;
};
static void iucv_sock_destruct(struct sock *sk);
static void iucv_sock_cleanup_listen(struct sock *parent);
static void iucv_sock_kill(struct sock *sk);
static void iucv_sock_close(struct sock *sk);
static int iucv_sock_create(struct socket *sock, int proto);
static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
int addr_len);
static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
int alen, int flags);
static int iucv_sock_listen(struct socket *sock, int backlog);
static int iucv_sock_accept(struct socket *sock, struct socket *newsock,
int flags);
static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
int *len, int peer);
static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len);
static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags);
unsigned int iucv_sock_poll(struct file *file, struct socket *sock,
poll_table *wait);
static int iucv_sock_release(struct socket *sock);
static int iucv_sock_shutdown(struct socket *sock, int how);
void iucv_sock_link(struct iucv_sock_list *l, struct sock *s);
void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *s);
int iucv_sock_wait_state(struct sock *sk, int state, int state2,
unsigned long timeo);
int iucv_sock_wait_cnt(struct sock *sk, unsigned long timeo);
void iucv_accept_enqueue(struct sock *parent, struct sock *sk);
void iucv_accept_unlink(struct sock *sk);
struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock);
#endif /* __IUCV_H */

415
include/net/iucv/iucv.h Normal file
View File

@@ -0,0 +1,415 @@
/*
* drivers/s390/net/iucv.h
* IUCV base support.
*
* S390 version
* Copyright 2000, 2006 IBM Corporation
* Author(s):Alan Altmark (Alan_Altmark@us.ibm.com)
* Xenia Tkatschow (xenia@us.ibm.com)
* Rewritten for af_iucv:
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
*
* Functionality:
* To explore any of the IUCV functions, one must first register their
* program using iucv_register(). Once your program has successfully
* completed a register, it can exploit the other functions.
* For furthur reference on all IUCV functionality, refer to the
* CP Programming Services book, also available on the web thru
* www.ibm.com/s390/vm/pubs, manual # SC24-5760
*
* Definition of Return Codes
* - All positive return codes including zero are reflected back
* from CP. The definition of each return code can be found in
* CP Programming Services book.
* - Return Code of:
* -EINVAL: Invalid value
* -ENOMEM: storage allocation failed
*/
#include <linux/types.h>
#include <asm/debug.h>
/*
* IUCV option flags usable by device drivers:
*
* IUCV_IPRMDATA Indicates that your program can handle a message in the
* parameter list / a message is sent in the parameter list.
* Used for iucv_path_accept, iucv_path_connect,
* iucv_message_reply, iucv_message_send, iucv_message_send2way.
* IUCV_IPQUSCE Indicates that you do not want to receive messages on this
* path until an iucv_path_resume is issued.
* Used for iucv_path_accept, iucv_path_connect.
* IUCV_IPBUFLST Indicates that an address list is used for the message data.
* Used for iucv_message_receive, iucv_message_send,
* iucv_message_send2way.
* IUCV_IPPRTY Specifies that you want to send priority messages.
* Used for iucv_path_accept, iucv_path_connect,
* iucv_message_reply, iucv_message_send, iucv_message_send2way.
* IUCV_IPSYNC Indicates a synchronous send request.
* Used for iucv_message_send, iucv_message_send2way.
* IUCV_IPANSLST Indicates that an address list is used for the reply data.
* Used for iucv_message_reply, iucv_message_send2way.
* IUCV_IPLOCAL Specifies that the communication partner has to be on the
* local system. If local is specified no target class can be
* specified.
* Used for iucv_path_connect.
*
* All flags are defined in the input field IPFLAGS1 of each function
* and can be found in CP Programming Services.
*/
#define IUCV_IPRMDATA 0x80
#define IUCV_IPQUSCE 0x40
#define IUCV_IPBUFLST 0x40
#define IUCV_IPPRTY 0x20
#define IUCV_IPANSLST 0x08
#define IUCV_IPSYNC 0x04
#define IUCV_IPLOCAL 0x01
/*
* iucv_array : Defines buffer array.
* Inside the array may be 31- bit addresses and 31-bit lengths.
* Use a pointer to an iucv_array as the buffer, reply or answer
* parameter on iucv_message_send, iucv_message_send2way, iucv_message_receive
* and iucv_message_reply if IUCV_IPBUFLST or IUCV_IPANSLST are used.
*/
struct iucv_array {
u32 address;
u32 length;
} __attribute__ ((aligned (8)));
extern struct bus_type iucv_bus;
extern struct device *iucv_root;
/*
* struct iucv_path
* pathid: 16 bit path identification
* msglim: 16 bit message limit
* flags: properties of the path: IPRMDATA, IPQUSCE, IPPRTY
* handler: address of iucv handler structure
* private: private information of the handler associated with the path
* list: list_head for the iucv_handler path list.
*/
struct iucv_path {
u16 pathid;
u16 msglim;
u8 flags;
void *private;
struct iucv_handler *handler;
struct list_head list;
};
/*
* struct iucv_message
* id: 32 bit message id
* audit: 32 bit error information of purged or replied messages
* class: 32 bit target class of a message (source class for replies)
* tag: 32 bit tag to be associated with the message
* length: 32 bit length of the message / reply
* reply_size: 32 bit maximum allowed length of the reply
* rmmsg: 8 byte inline message
* flags: message properties (IUCV_IPPRTY)
*/
struct iucv_message {
u32 id;
u32 audit;
u32 class;
u32 tag;
u32 length;
u32 reply_size;
u8 rmmsg[8];
u8 flags;
};
/*
* struct iucv_handler
*
* A vector of functions that handle IUCV interrupts. Each functions gets
* a parameter area as defined by the CP Programming Services and private
* pointer that is provided by the user of the interface.
*/
struct iucv_handler {
/*
* The path_pending function is called after an iucv interrupt
* type 0x01 has been received. The base code allocates a path
* structure and "asks" the handler if this path belongs to the
* handler. To accept the path the path_pending function needs
* to call iucv_path_accept and return 0. If the callback returns
* a value != 0 the iucv base code will continue with the next
* handler. The order in which the path_pending functions are
* called is the order of the registration of the iucv handlers
* to the base code.
*/
int (*path_pending)(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]);
/*
* The path_complete function is called after an iucv interrupt
* type 0x02 has been received for a path that has been established
* for this handler with iucv_path_connect and got accepted by the
* peer with iucv_path_accept.
*/
void (*path_complete)(struct iucv_path *, u8 ipuser[16]);
/*
* The path_severed function is called after an iucv interrupt
* type 0x03 has been received. The communication peer shutdown
* his end of the communication path. The path still exists and
* remaining messages can be received until a iucv_path_sever
* shuts down the other end of the path as well.
*/
void (*path_severed)(struct iucv_path *, u8 ipuser[16]);
/*
* The path_quiesced function is called after an icuv interrupt
* type 0x04 has been received. The communication peer has quiesced
* the path. Delivery of messages is stopped until iucv_path_resume
* has been called.
*/
void (*path_quiesced)(struct iucv_path *, u8 ipuser[16]);
/*
* The path_resumed function is called after an icuv interrupt
* type 0x05 has been received. The communication peer has resumed
* the path.
*/
void (*path_resumed)(struct iucv_path *, u8 ipuser[16]);
/*
* The message_pending function is called after an icuv interrupt
* type 0x06 or type 0x07 has been received. A new message is
* availabe and can be received with iucv_message_receive.
*/
void (*message_pending)(struct iucv_path *, struct iucv_message *);
/*
* The message_complete function is called after an icuv interrupt
* type 0x08 or type 0x09 has been received. A message send with
* iucv_message_send2way has been replied to. The reply can be
* received with iucv_message_receive.
*/
void (*message_complete)(struct iucv_path *, struct iucv_message *);
struct list_head list;
struct list_head paths;
};
/**
* iucv_register:
* @handler: address of iucv handler structure
* @smp: != 0 indicates that the handler can deal with out of order messages
*
* Registers a driver with IUCV.
*
* Returns 0 on success, -ENOMEM if the memory allocation for the pathid
* table failed, or -EIO if IUCV_DECLARE_BUFFER failed on all cpus.
*/
int iucv_register(struct iucv_handler *handler, int smp);
/**
* iucv_unregister
* @handler: address of iucv handler structure
* @smp: != 0 indicates that the handler can deal with out of order messages
*
* Unregister driver from IUCV.
*/
void iucv_unregister(struct iucv_handler *handle, int smp);
/**
* iucv_path_alloc
* @msglim: initial message limit
* @flags: initial flags
* @gfp: kmalloc allocation flag
*
* Allocate a new path structure for use with iucv_connect.
*
* Returns NULL if the memory allocation failed or a pointer to the
* path structure.
*/
static inline struct iucv_path *iucv_path_alloc(u16 msglim, u8 flags, gfp_t gfp)
{
struct iucv_path *path;
path = kzalloc(sizeof(struct iucv_path), gfp);
if (path) {
path->msglim = msglim;
path->flags = flags;
}
return path;
}
/**
* iucv_path_free
* @path: address of iucv path structure
*
* Frees a path structure.
*/
static inline void iucv_path_free(struct iucv_path *path)
{
kfree(path);
}
/**
* iucv_path_accept
* @path: address of iucv path structure
* @handler: address of iucv handler structure
* @userdata: 16 bytes of data reflected to the communication partner
* @private: private data passed to interrupt handlers for this path
*
* This function is issued after the user received a connection pending
* external interrupt and now wishes to complete the IUCV communication path.
*
* Returns the result of the CP IUCV call.
*/
int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
u8 userdata[16], void *private);
/**
* iucv_path_connect
* @path: address of iucv path structure
* @handler: address of iucv handler structure
* @userid: 8-byte user identification
* @system: 8-byte target system identification
* @userdata: 16 bytes of data reflected to the communication partner
* @private: private data passed to interrupt handlers for this path
*
* This function establishes an IUCV path. Although the connect may complete
* successfully, you are not able to use the path until you receive an IUCV
* Connection Complete external interrupt.
*
* Returns the result of the CP IUCV call.
*/
int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
u8 userid[8], u8 system[8], u8 userdata[16],
void *private);
/**
* iucv_path_quiesce:
* @path: address of iucv path structure
* @userdata: 16 bytes of data reflected to the communication partner
*
* This function temporarily suspends incoming messages on an IUCV path.
* You can later reactivate the path by invoking the iucv_resume function.
*
* Returns the result from the CP IUCV call.
*/
int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]);
/**
* iucv_path_resume:
* @path: address of iucv path structure
* @userdata: 16 bytes of data reflected to the communication partner
*
* This function resumes incoming messages on an IUCV path that has
* been stopped with iucv_path_quiesce.
*
* Returns the result from the CP IUCV call.
*/
int iucv_path_resume(struct iucv_path *path, u8 userdata[16]);
/**
* iucv_path_sever
* @path: address of iucv path structure
* @userdata: 16 bytes of data reflected to the communication partner
*
* This function terminates an IUCV path.
*
* Returns the result from the CP IUCV call.
*/
int iucv_path_sever(struct iucv_path *path, u8 userdata[16]);
/**
* iucv_message_purge
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @srccls: source class of message
*
* Cancels a message you have sent.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
u32 srccls);
/**
* iucv_message_receive
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: flags that affect how the message is received (IUCV_IPBUFLST)
* @buffer: address of data buffer or address of struct iucv_array
* @size: length of data buffer
* @residual:
*
* This function receives messages that are being sent to you over
* established paths. This function will deal with RMDATA messages
* embedded in struct iucv_message as well.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
u8 flags, void *buffer, size_t size, size_t *residual);
/**
* iucv_message_reject
* @path: address of iucv path structure
* @msg: address of iucv msg structure
*
* The reject function refuses a specified message. Between the time you
* are notified of a message and the time that you complete the message,
* the message may be rejected.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg);
/**
* iucv_message_reply
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: how the reply is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
* @reply: address of data buffer or address of struct iucv_array
* @size: length of reply data buffer
*
* This function responds to the two-way messages that you receive. You
* must identify completely the message to which you wish to reply. ie,
* pathid, msgid, and trgcls. Prmmsg signifies the data is moved into
* the parameter list.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
u8 flags, void *reply, size_t size);
/**
* iucv_message_send
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
* @srccls: source class of message
* @buffer: address of data buffer or address of struct iucv_array
* @size: length of send buffer
*
* This function transmits data to another application. Data to be
* transmitted is in a buffer and this is a one-way message and the
* receiver will not reply to the message.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
u8 flags, u32 srccls, void *buffer, size_t size);
/**
* iucv_message_send2way
* @path: address of iucv path structure
* @msg: address of iucv msg structure
* @flags: how the message is sent and the reply is received
* (IUCV_IPRMDATA, IUCV_IPBUFLST, IUCV_IPPRTY, IUCV_ANSLST)
* @srccls: source class of message
* @buffer: address of data buffer or address of struct iucv_array
* @size: length of send buffer
* @ansbuf: address of answer buffer or address of struct iucv_array
* @asize: size of reply buffer
*
* This function transmits data to another application. Data to be
* transmitted is in a buffer. The receiver of the send is expected to
* reply to the message and a buffer is provided into which IUCV moves
* the reply to this message.
*
* Returns the result from the CP IUCV call.
*/
int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
u8 flags, u32 srccls, void *buffer, size_t size,
void *answer, size_t asize, size_t *residual);

655
include/net/iw_handler.h Normal file
View File

@@ -0,0 +1,655 @@
/*
* This file define the new driver API for Wireless Extensions
*
* Version : 8 16.3.07
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 2001-2007 Jean Tourrilhes, All Rights Reserved.
*/
#ifndef _IW_HANDLER_H
#define _IW_HANDLER_H
/************************** DOCUMENTATION **************************/
/*
* Initial driver API (1996 -> onward) :
* -----------------------------------
* The initial API just sends the IOCTL request received from user space
* to the driver (via the driver ioctl handler). The driver has to
* handle all the rest...
*
* The initial API also defines a specific handler in struct net_device
* to handle wireless statistics.
*
* The initial APIs served us well and has proven a reasonably good design.
* However, there is a few shortcommings :
* o No events, everything is a request to the driver.
* o Large ioctl function in driver with gigantic switch statement
* (i.e. spaghetti code).
* o Driver has to mess up with copy_to/from_user, and in many cases
* does it unproperly. Common mistakes are :
* * buffer overflows (no checks or off by one checks)
* * call copy_to/from_user with irq disabled
* o The user space interface is tied to ioctl because of the use
* copy_to/from_user.
*
* New driver API (2002 -> onward) :
* -------------------------------
* The new driver API is just a bunch of standard functions (handlers),
* each handling a specific Wireless Extension. The driver just export
* the list of handler it supports, and those will be called apropriately.
*
* I tried to keep the main advantage of the previous API (simplicity,
* efficiency and light weight), and also I provide a good dose of backward
* compatibility (most structures are the same, driver can use both API
* simultaneously, ...).
* Hopefully, I've also addressed the shortcomming of the initial API.
*
* The advantage of the new API are :
* o Handling of Extensions in driver broken in small contained functions
* o Tighter checks of ioctl before calling the driver
* o Flexible commit strategy (at least, the start of it)
* o Backward compatibility (can be mixed with old API)
* o Driver doesn't have to worry about memory and user-space issues
* The last point is important for the following reasons :
* o You are now able to call the new driver API from any API you
* want (including from within other parts of the kernel).
* o Common mistakes are avoided (buffer overflow, user space copy
* with irq disabled and so on).
*
* The Drawback of the new API are :
* o bloat (especially kernel)
* o need to migrate existing drivers to new API
* My initial testing shows that the new API adds around 3kB to the kernel
* and save between 0 and 5kB from a typical driver.
* Also, as all structures and data types are unchanged, the migration is
* quite straightforward (but tedious).
*
* ---
*
* The new driver API is defined below in this file. User space should
* not be aware of what's happening down there...
*
* A new kernel wrapper is in charge of validating the IOCTLs and calling
* the appropriate driver handler. This is implemented in :
* # net/core/wireless.c
*
* The driver export the list of handlers in :
* # include/linux/netdevice.h (one place)
*
* The new driver API is available for WIRELESS_EXT >= 13.
* Good luck with migration to the new API ;-)
*/
/* ---------------------- THE IMPLEMENTATION ---------------------- */
/*
* Some of the choice I've made are pretty controversials. Defining an
* API is very much weighting compromises. This goes into some of the
* details and the thinking behind the implementation.
*
* Implementation goals :
* --------------------
* The implementation goals were as follow :
* o Obvious : you should not need a PhD to understand what's happening,
* the benefit is easier maintainance.
* o Flexible : it should accommodate a wide variety of driver
* implementations and be as flexible as the old API.
* o Lean : it should be efficient memory wise to minimise the impact
* on kernel footprint.
* o Transparent to user space : the large number of user space
* applications that use Wireless Extensions should not need
* any modifications.
*
* Array of functions versus Struct of functions
* ---------------------------------------------
* 1) Having an array of functions allow the kernel code to access the
* handler in a single lookup, which is much more efficient (think hash
* table here).
* 2) The only drawback is that driver writer may put their handler in
* the wrong slot. This is trivial to test (I set the frequency, the
* bitrate changes). Once the handler is in the proper slot, it will be
* there forever, because the array is only extended at the end.
* 3) Backward/forward compatibility : adding new handler just require
* extending the array, so you can put newer driver in older kernel
* without having to patch the kernel code (and vice versa).
*
* All handler are of the same generic type
* ----------------------------------------
* That's a feature !!!
* 1) Having a generic handler allow to have generic code, which is more
* efficient. If each of the handler was individually typed I would need
* to add a big switch in the kernel (== more bloat). This solution is
* more scalable, adding new Wireless Extensions doesn't add new code.
* 2) You can use the same handler in different slots of the array. For
* hardware, it may be more efficient or logical to handle multiple
* Wireless Extensions with a single function, and the API allow you to
* do that. (An example would be a single record on the card to control
* both bitrate and frequency, the handler would read the old record,
* modify it according to info->cmd and rewrite it).
*
* Functions prototype uses union iwreq_data
* -----------------------------------------
* Some would have prefered functions defined this way :
* static int mydriver_ioctl_setrate(struct net_device *dev,
* long rate, int auto)
* 1) The kernel code doesn't "validate" the content of iwreq_data, and
* can't do it (different hardware may have different notion of what a
* valid frequency is), so we don't pretend that we do it.
* 2) The above form is not extendable. If I want to add a flag (for
* example to distinguish setting max rate and basic rate), I would
* break the prototype. Using iwreq_data is more flexible.
* 3) Also, the above form is not generic (see above).
* 4) I don't expect driver developper using the wrong field of the
* union (Doh !), so static typechecking doesn't add much value.
* 5) Lastly, you can skip the union by doing :
* static int mydriver_ioctl_setrate(struct net_device *dev,
* struct iw_request_info *info,
* struct iw_param *rrq,
* char *extra)
* And then adding the handler in the array like this :
* (iw_handler) mydriver_ioctl_setrate, // SIOCSIWRATE
*
* Using functions and not a registry
* ----------------------------------
* Another implementation option would have been for every instance to
* define a registry (a struct containing all the Wireless Extensions)
* and only have a function to commit the registry to the hardware.
* 1) This approach can be emulated by the current code, but not
* vice versa.
* 2) Some drivers don't keep any configuration in the driver, for them
* adding such a registry would be a significant bloat.
* 3) The code to translate from Wireless Extension to native format is
* needed anyway, so it would not reduce significantely the amount of code.
* 4) The current approach only selectively translate Wireless Extensions
* to native format and only selectively set, whereas the registry approach
* would require to translate all WE and set all parameters for any single
* change.
* 5) For many Wireless Extensions, the GET operation return the current
* dynamic value, not the value that was set.
*
* This header is <net/iw_handler.h>
* ---------------------------------
* 1) This header is kernel space only and should not be exported to
* user space. Headers in "include/linux/" are exported, headers in
* "include/net/" are not.
*
* Mixed 32/64 bit issues
* ----------------------
* The Wireless Extensions are designed to be 64 bit clean, by using only
* datatypes with explicit storage size.
* There are some issues related to kernel and user space using different
* memory model, and in particular 64bit kernel with 32bit user space.
* The problem is related to struct iw_point, that contains a pointer
* that *may* need to be translated.
* This is quite messy. The new API doesn't solve this problem (it can't),
* but is a step in the right direction :
* 1) Meta data about each ioctl is easily available, so we know what type
* of translation is needed.
* 2) The move of data between kernel and user space is only done in a single
* place in the kernel, so adding specific hooks in there is possible.
* 3) In the long term, it allows to move away from using ioctl as the
* user space API.
*
* So many comments and so few code
* --------------------------------
* That's a feature. Comments won't bloat the resulting kernel binary.
*/
/***************************** INCLUDES *****************************/
#include <linux/wireless.h> /* IOCTL user space API */
#include <linux/if_ether.h>
/***************************** VERSION *****************************/
/*
* This constant is used to know which version of the driver API is
* available. Hopefully, this will be pretty stable and no changes
* will be needed...
* I just plan to increment with each new version.
*/
#define IW_HANDLER_VERSION 8
/*
* Changes :
*
* V2 to V3
* --------
* - Move event definition in <linux/wireless.h>
* - Add Wireless Event support :
* o wireless_send_event() prototype
* o iwe_stream_add_event/point() inline functions
* V3 to V4
* --------
* - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
*
* V4 to V5
* --------
* - Add new spy support : struct iw_spy_data & prototypes
*
* V5 to V6
* --------
* - Change the way we get to spy_data method for added safety
* - Remove spy #ifdef, they are always on -> cleaner code
* - Add IW_DESCR_FLAG_NOMAX flag for very large requests
* - Start migrating get_wireless_stats to struct iw_handler_def
*
* V6 to V7
* --------
* - Add struct ieee80211_device pointer in struct iw_public_data
* - Remove (struct iw_point *)->pointer from events and streams
* - Remove spy_offset from struct iw_handler_def
* - Add "check" version of event macros for ieee802.11 stack
*
* V7 to V8
* ----------
* - Prevent leaking of kernel space in stream on 64 bits.
*/
/**************************** CONSTANTS ****************************/
/* Enhanced spy support available */
#define IW_WIRELESS_SPY
#define IW_WIRELESS_THRSPY
/* Special error message for the driver to indicate that we
* should do a commit after return from the iw_handler */
#define EIWCOMMIT EINPROGRESS
/* Flags available in struct iw_request_info */
#define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */
/* Type of headers we know about (basically union iwreq_data) */
#define IW_HEADER_TYPE_NULL 0 /* Not available */
#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
#define IW_HEADER_TYPE_UINT 4 /* __u32 */
#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */
#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */
#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */
#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */
/* Handling flags */
/* Most are not implemented. I just use them as a reminder of some
* cool features we might need one day ;-) */
#define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */
/* Wrapper level flags */
#define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
#define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */
/* SET : Omit payload from generated iwevent */
#define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */
/* Driver level flags */
#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
/****************************** TYPES ******************************/
/* ----------------------- WIRELESS HANDLER ----------------------- */
/*
* A wireless handler is just a standard function, that looks like the
* ioctl handler.
* We also define there how a handler list look like... As the Wireless
* Extension space is quite dense, we use a simple array, which is faster
* (that's the perfect hash table ;-).
*/
/*
* Meta data about the request passed to the iw_handler.
* Most handlers can safely ignore what's in there.
* The 'cmd' field might come handy if you want to use the same handler
* for multiple command...
* This struct is also my long term insurance. I can add new fields here
* without breaking the prototype of iw_handler...
*/
struct iw_request_info
{
__u16 cmd; /* Wireless Extension command */
__u16 flags; /* More to come ;-) */
};
struct net_device;
/*
* This is how a function handling a Wireless Extension should look
* like (both get and set, standard and private).
*/
typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra);
/*
* This define all the handler that the driver export.
* As you need only one per driver type, please use a static const
* shared by all driver instances... Same for the members...
* This will be linked from net_device in <linux/netdevice.h>
*/
struct iw_handler_def
{
/* Number of handlers defined (more precisely, index of the
* last defined handler + 1) */
__u16 num_standard;
__u16 num_private;
/* Number of private arg description */
__u16 num_private_args;
/* Array of handlers for standard ioctls
* We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT]
*/
const iw_handler * standard;
/* Array of handlers for private ioctls
* Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
*/
const iw_handler * private;
/* Arguments of private handler. This one is just a list, so you
* can put it in any order you want and should not leave holes...
* We will automatically export that to user space... */
const struct iw_priv_args * private_args;
/* New location of get_wireless_stats, to de-bloat struct net_device.
* The old pointer in struct net_device will be gradually phased
* out, and drivers are encouraged to use this one... */
struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
};
/* ---------------------- IOCTL DESCRIPTION ---------------------- */
/*
* One of the main goal of the new interface is to deal entirely with
* user space/kernel space memory move.
* For that, we need to know :
* o if iwreq is a pointer or contain the full data
* o what is the size of the data to copy
*
* For private IOCTLs, we use the same rules as used by iwpriv and
* defined in struct iw_priv_args.
*
* For standard IOCTLs, things are quite different and we need to
* use the stuctures below. Actually, this struct is also more
* efficient, but that's another story...
*/
/*
* Describe how a standard IOCTL looks like.
*/
struct iw_ioctl_description
{
__u8 header_type; /* NULL, iw_point or other */
__u8 token_type; /* Future */
__u16 token_size; /* Granularity of payload */
__u16 min_tokens; /* Min acceptable token number */
__u16 max_tokens; /* Max acceptable token number */
__u32 flags; /* Special handling of the request */
};
/* Need to think of short header translation table. Later. */
/* --------------------- ENHANCED SPY SUPPORT --------------------- */
/*
* In the old days, the driver was handling spy support all by itself.
* Now, the driver can delegate this task to Wireless Extensions.
* It needs to include this struct in its private part and use the
* standard spy iw_handler.
*/
/*
* Instance specific spy data, i.e. addresses spied and quality for them.
*/
struct iw_spy_data
{
/* --- Standard spy support --- */
int spy_number;
u_char spy_address[IW_MAX_SPY][ETH_ALEN];
struct iw_quality spy_stat[IW_MAX_SPY];
/* --- Enhanced spy support (event) */
struct iw_quality spy_thr_low; /* Low threshold */
struct iw_quality spy_thr_high; /* High threshold */
u_char spy_thr_under[IW_MAX_SPY];
};
/* --------------------- DEVICE WIRELESS DATA --------------------- */
/*
* This is all the wireless data specific to a device instance that
* is managed by the core of Wireless Extensions or the 802.11 layer.
* We only keep pointer to those structures, so that a driver is free
* to share them between instances.
* This structure should be initialised before registering the device.
* Access to this data follow the same rules as any other struct net_device
* data (i.e. valid as long as struct net_device exist, same locking rules).
*/
/* Forward declaration */
struct ieee80211_device;
/* The struct */
struct iw_public_data {
/* Driver enhanced spy support */
struct iw_spy_data * spy_data;
/* Structure managed by the in-kernel IEEE 802.11 layer */
struct ieee80211_device * ieee80211;
};
/**************************** PROTOTYPES ****************************/
/*
* Functions part of the Wireless Extensions (defined in net/core/wireless.c).
* Those may be called only within the kernel.
*/
/* First : function strictly used inside the kernel */
/* Handle /proc/net/wireless, called in net/code/dev.c */
extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
int length);
/* Handle IOCTLs, called in net/core/dev.c */
extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
/* Handle RtNetlink requests, called in net/core/rtnetlink.c */
extern int wireless_rtnetlink_set(struct net_device * dev,
char * data,
int len);
extern int wireless_rtnetlink_get(struct net_device * dev,
char * data,
int len,
char ** p_buf,
int * p_len);
/* Second : functions that may be called by driver modules */
/* Send a single event to user space */
extern void wireless_send_event(struct net_device * dev,
unsigned int cmd,
union iwreq_data * wrqu,
char * extra);
/* We may need a function to send a stream of events to user space.
* More on that later... */
/* Standard handler for SIOCSIWSPY */
extern int iw_handler_set_spy(struct net_device * dev,
struct iw_request_info * info,
union iwreq_data * wrqu,
char * extra);
/* Standard handler for SIOCGIWSPY */
extern int iw_handler_get_spy(struct net_device * dev,
struct iw_request_info * info,
union iwreq_data * wrqu,
char * extra);
/* Standard handler for SIOCSIWTHRSPY */
extern int iw_handler_set_thrspy(struct net_device * dev,
struct iw_request_info *info,
union iwreq_data * wrqu,
char * extra);
/* Standard handler for SIOCGIWTHRSPY */
extern int iw_handler_get_thrspy(struct net_device * dev,
struct iw_request_info *info,
union iwreq_data * wrqu,
char * extra);
/* Driver call to update spy records */
extern void wireless_spy_update(struct net_device * dev,
unsigned char * address,
struct iw_quality * wstats);
/************************* INLINE FUNTIONS *************************/
/*
* Function that are so simple that it's more efficient inlining them
*/
/*------------------------------------------------------------------*/
/*
* Wrapper to add an Wireless Event to a stream of events.
*/
static inline char *
iwe_stream_add_event(char * stream, /* Stream of events */
char * ends, /* End of stream */
struct iw_event *iwe, /* Payload */
int event_len) /* Real size of payload */
{
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
/* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN,
event_len - IW_EV_LCP_LEN);
stream += event_len;
}
return stream;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add an short Wireless Event containing a pointer to a
* stream of events.
*/
static inline char *
iwe_stream_add_point(char * stream, /* Stream of events */
char * ends, /* End of stream */
struct iw_event *iwe, /* Payload length + flags */
char * extra) /* More payload */
{
int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
stream += event_len;
}
return stream;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add a value to a Wireless Event in a stream of events.
* Be careful, this one is tricky to use properly :
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
*/
static inline char *
iwe_stream_add_value(char * event, /* Event in the stream */
char * value, /* Value in event */
char * ends, /* End of stream */
struct iw_event *iwe, /* Payload */
int event_len) /* Real size of payload */
{
/* Don't duplicate LCP */
event_len -= IW_EV_LCP_LEN;
/* Check if it's possible */
if(likely((value + event_len) < ends)) {
/* Add new value */
memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
value += event_len;
/* Patch LCP */
iwe->len = value - event;
memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
}
return value;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add an Wireless Event to a stream of events.
* Same as above, with explicit error check...
*/
static inline char *
iwe_stream_check_add_event(char * stream, /* Stream of events */
char * ends, /* End of stream */
struct iw_event *iwe, /* Payload */
int event_len, /* Size of payload */
int * perr) /* Error report */
{
/* Check if it's possible, set error if not */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
/* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN,
event_len - IW_EV_LCP_LEN);
stream += event_len;
} else
*perr = -E2BIG;
return stream;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add an short Wireless Event containing a pointer to a
* stream of events.
* Same as above, with explicit error check...
*/
static inline char *
iwe_stream_check_add_point(char * stream, /* Stream of events */
char * ends, /* End of stream */
struct iw_event *iwe, /* Payload length + flags */
char * extra, /* More payload */
int * perr) /* Error report */
{
int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
stream += event_len;
} else
*perr = -E2BIG;
return stream;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add a value to a Wireless Event in a stream of events.
* Be careful, this one is tricky to use properly :
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
* Same as above, with explicit error check...
*/
static inline char *
iwe_stream_check_add_value(char * event, /* Event in the stream */
char * value, /* Value in event */
char * ends, /* End of stream */
struct iw_event *iwe, /* Payload */
int event_len, /* Size of payload */
int * perr) /* Error report */
{
/* Don't duplicate LCP */
event_len -= IW_EV_LCP_LEN;
/* Check if it's possible */
if(likely((value + event_len) < ends)) {
/* Add new value */
memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
value += event_len;
/* Patch LCP */
iwe->len = value - event;
memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
} else
*perr = -E2BIG;
return value;
}
#endif /* _IW_HANDLER_H */

152
include/net/lapb.h Normal file
View File

@@ -0,0 +1,152 @@
#ifndef _LAPB_H
#define _LAPB_H
#include <linux/lapb.h>
#define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */
#define LAPB_ACK_PENDING_CONDITION 0x01
#define LAPB_REJECT_CONDITION 0x02
#define LAPB_PEER_RX_BUSY_CONDITION 0x04
/* Control field templates */
#define LAPB_I 0x00 /* Information frames */
#define LAPB_S 0x01 /* Supervisory frames */
#define LAPB_U 0x03 /* Unnumbered frames */
#define LAPB_RR 0x01 /* Receiver ready */
#define LAPB_RNR 0x05 /* Receiver not ready */
#define LAPB_REJ 0x09 /* Reject */
#define LAPB_SABM 0x2F /* Set Asynchronous Balanced Mode */
#define LAPB_SABME 0x6F /* Set Asynchronous Balanced Mode Extended */
#define LAPB_DISC 0x43 /* Disconnect */
#define LAPB_DM 0x0F /* Disconnected mode */
#define LAPB_UA 0x63 /* Unnumbered acknowledge */
#define LAPB_FRMR 0x87 /* Frame reject */
#define LAPB_ILLEGAL 0x100 /* Impossible to be a real frame type */
#define LAPB_SPF 0x10 /* Poll/final bit for standard LAPB */
#define LAPB_EPF 0x01 /* Poll/final bit for extended LAPB */
#define LAPB_FRMR_W 0x01 /* Control field invalid */
#define LAPB_FRMR_X 0x02 /* I field invalid */
#define LAPB_FRMR_Y 0x04 /* I field too long */
#define LAPB_FRMR_Z 0x08 /* Invalid N(R) */
#define LAPB_POLLOFF 0
#define LAPB_POLLON 1
/* LAPB C-bit */
#define LAPB_COMMAND 1
#define LAPB_RESPONSE 2
#define LAPB_ADDR_A 0x03
#define LAPB_ADDR_B 0x01
#define LAPB_ADDR_C 0x0F
#define LAPB_ADDR_D 0x07
/* Define Link State constants. */
enum {
LAPB_STATE_0, /* Disconnected State */
LAPB_STATE_1, /* Awaiting Connection State */
LAPB_STATE_2, /* Awaiting Disconnection State */
LAPB_STATE_3, /* Data Transfer State */
LAPB_STATE_4 /* Frame Reject State */
};
#define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE)
#define LAPB_DEFAULT_WINDOW 7 /* Window=7 */
#define LAPB_DEFAULT_T1 (5 * HZ) /* T1=5s */
#define LAPB_DEFAULT_T2 (1 * HZ) /* T2=1s */
#define LAPB_DEFAULT_N2 20 /* N2=20 */
#define LAPB_SMODULUS 8
#define LAPB_EMODULUS 128
/*
* Information about the current frame.
*/
struct lapb_frame {
unsigned short type; /* Parsed type */
unsigned short nr, ns; /* N(R), N(S) */
unsigned char cr; /* Command/Response */
unsigned char pf; /* Poll/Final */
unsigned char control[2]; /* Original control data*/
};
/*
* The per LAPB connection control structure.
*/
struct lapb_cb {
struct list_head node;
struct net_device *dev;
/* Link status fields */
unsigned int mode;
unsigned char state;
unsigned short vs, vr, va;
unsigned char condition;
unsigned short n2, n2count;
unsigned short t1, t2;
struct timer_list t1timer, t2timer;
/* Internal control information */
struct sk_buff_head write_queue;
struct sk_buff_head ack_queue;
unsigned char window;
struct lapb_register_struct callbacks;
/* FRMR control information */
struct lapb_frame frmr_data;
unsigned char frmr_type;
atomic_t refcnt;
};
/* lapb_iface.c */
extern void lapb_connect_confirmation(struct lapb_cb *lapb, int);
extern void lapb_connect_indication(struct lapb_cb *lapb, int);
extern void lapb_disconnect_confirmation(struct lapb_cb *lapb, int);
extern void lapb_disconnect_indication(struct lapb_cb *lapb, int);
extern int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *);
extern int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *);
/* lapb_in.c */
extern void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *);
/* lapb_out.c */
extern void lapb_kick(struct lapb_cb *lapb);
extern void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *, int);
extern void lapb_establish_data_link(struct lapb_cb *lapb);
extern void lapb_enquiry_response(struct lapb_cb *lapb);
extern void lapb_timeout_response(struct lapb_cb *lapb);
extern void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short);
extern void lapb_check_need_response(struct lapb_cb *lapb, int, int);
/* lapb_subr.c */
extern void lapb_clear_queues(struct lapb_cb *lapb);
extern void lapb_frames_acked(struct lapb_cb *lapb, unsigned short);
extern void lapb_requeue_frames(struct lapb_cb *lapb);
extern int lapb_validate_nr(struct lapb_cb *lapb, unsigned short);
extern int lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *);
extern void lapb_send_control(struct lapb_cb *lapb, int, int, int);
extern void lapb_transmit_frmr(struct lapb_cb *lapb);
/* lapb_timer.c */
extern void lapb_start_t1timer(struct lapb_cb *lapb);
extern void lapb_start_t2timer(struct lapb_cb *lapb);
extern void lapb_stop_t1timer(struct lapb_cb *lapb);
extern void lapb_stop_t2timer(struct lapb_cb *lapb);
extern int lapb_t1timer_running(struct lapb_cb *lapb);
/*
* Debug levels.
* 0 = Off
* 1 = State Changes
* 2 = Packets I/O and State Changes
* 3 = Hex dumps, Packets I/O and State Changes.
*/
#define LAPB_DEBUG 0
#endif

131
include/net/llc.h Normal file
View File

@@ -0,0 +1,131 @@
#ifndef LLC_H
#define LLC_H
/*
* Copyright (c) 1997 by Procom Technology, Inc.
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation.
* This program is distributed without any warranty or implied warranty
* of merchantability or fitness for a particular purpose.
*
* See the GNU General Public License for more details.
*/
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
struct net_device;
struct packet_type;
struct sk_buff;
struct llc_addr {
unsigned char lsap;
unsigned char mac[IFHWADDRLEN];
};
#define LLC_SAP_STATE_INACTIVE 1
#define LLC_SAP_STATE_ACTIVE 2
/**
* struct llc_sap - Defines the SAP component
*
* @station - station this sap belongs to
* @state - sap state
* @p_bit - only lowest-order bit used
* @f_bit - only lowest-order bit used
* @laddr - SAP value in this 'lsap'
* @node - entry in station sap_list
* @sk_list - LLC sockets this one manages
*/
struct llc_sap {
unsigned char state;
unsigned char p_bit;
unsigned char f_bit;
atomic_t refcnt;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
struct llc_addr laddr;
struct list_head node;
struct {
rwlock_t lock;
struct hlist_head list;
} sk_list;
};
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */
#define LLC_DEST_CONN 2 /* Type 2 goes here */
extern struct list_head llc_sap_list;
extern rwlock_t llc_sap_list_lock;
extern unsigned char llc_station_mac_sa[ETH_ALEN];
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
extern int llc_mac_hdr_init(struct sk_buff *skb,
const unsigned char *sa, const unsigned char *da);
extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
struct sk_buff *skb));
extern void llc_remove_pack(int type);
extern void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
extern struct llc_sap *llc_sap_open(unsigned char lsap,
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev));
static inline void llc_sap_hold(struct llc_sap *sap)
{
atomic_inc(&sap->refcnt);
}
extern void llc_sap_close(struct llc_sap *sap);
static inline void llc_sap_put(struct llc_sap *sap)
{
if (atomic_dec_and_test(&sap->refcnt))
llc_sap_close(sap);
}
extern struct llc_sap *llc_sap_find(unsigned char sap_value);
extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
unsigned char *dmac, unsigned char dsap);
extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_station_init(void);
extern void llc_station_exit(void);
#ifdef CONFIG_PROC_FS
extern int llc_proc_init(void);
extern void llc_proc_exit(void);
#else
#define llc_proc_init() (0)
#define llc_proc_exit() do { } while(0)
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SYSCTL
extern int llc_sysctl_init(void);
extern void llc_sysctl_exit(void);
extern int sysctl_llc2_ack_timeout;
extern int sysctl_llc2_busy_timeout;
extern int sysctl_llc2_p_timeout;
extern int sysctl_llc2_rej_timeout;
extern int sysctl_llc_station_ack_timeout;
#else
#define llc_sysctl_init() (0)
#define llc_sysctl_exit() do { } while(0)
#endif /* CONFIG_SYSCTL */
#endif /* LLC_H */

202
include/net/llc_c_ac.h Normal file
View File

@@ -0,0 +1,202 @@
#ifndef LLC_C_AC_H
#define LLC_C_AC_H
/*
* Copyright (c) 1997 by Procom Technology,Inc.
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation.
* This program is distributed without any warranty or implied warranty
* of merchantability or fitness for a particular purpose.
*
* See the GNU General Public License for more details.
*/
/* Connection component state transition actions */
/*
* Connection state transition actions
* (Fb = F bit; Pb = P bit; Xb = X bit)
*/
#define LLC_CONN_AC_CLR_REMOTE_BUSY 1
#define LLC_CONN_AC_CONN_IND 2
#define LLC_CONN_AC_CONN_CONFIRM 3
#define LLC_CONN_AC_DATA_IND 4
#define LLC_CONN_AC_DISC_IND 5
#define LLC_CONN_AC_RESET_IND 6
#define LLC_CONN_AC_RESET_CONFIRM 7
#define LLC_CONN_AC_REPORT_STATUS 8
#define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1 9
#define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2 10
#define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X 11
#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb 12
#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1 13
#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG 14
#define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X 15
#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0 16
#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb 17
#define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1 18
#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1 19
#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR 20
#define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0 21
#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0 22
#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR 23
#define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1 24
#define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1 25
#define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1 26
#define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0 27
#define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1 28
#define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1 29
#define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0 30
#define LLC_CONN_AC_SET_REMOTE_BUSY 31
#define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0 32
#define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1 33
#define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1 34
#define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1 35
#define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1 36
#define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0 37
#define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0 38
#define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X 39
#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb 40
#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG 41
#define LLC_CONN_AC_S_FLAG_SET_0 42
#define LLC_CONN_AC_S_FLAG_SET_1 43
#define LLC_CONN_AC_START_P_TMR 44
#define LLC_CONN_AC_START_ACK_TMR 45
#define LLC_CONN_AC_START_REJ_TMR 46
#define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING 47
#define LLC_CONN_AC_STOP_ACK_TMR 48
#define LLC_CONN_AC_STOP_P_TMR 49
#define LLC_CONN_AC_STOP_REJ_TMR 50
#define LLC_CONN_AC_STOP_ALL_TMRS 51
#define LLC_CONN_AC_STOP_OTHER_TMRS 52
#define LLC_CONN_AC_UPDATE_Nr_RECEIVED 53
#define LLC_CONN_AC_UPDATE_P_FLAG 54
#define LLC_CONN_AC_DATA_FLAG_SET_2 55
#define LLC_CONN_AC_DATA_FLAG_SET_0 56
#define LLC_CONN_AC_DATA_FLAG_SET_1 57
#define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0 58
#define LLC_CONN_AC_P_FLAG_SET_0 59
#define LLC_CONN_AC_P_FLAG_SET_P 60
#define LLC_CONN_AC_REMOTE_BUSY_SET_0 61
#define LLC_CONN_AC_RETRY_CNT_SET_0 62
#define LLC_CONN_AC_RETRY_CNT_INC_BY_1 63
#define LLC_CONN_AC_Vr_SET_0 64
#define LLC_CONN_AC_Vr_INC_BY_1 65
#define LLC_CONN_AC_Vs_SET_0 66
#define LLC_CONN_AC_Vs_SET_Nr 67
#define LLC_CONN_AC_F_FLAG_SET_P 68
#define LLC_CONN_AC_STOP_SENDACK_TMR 70
#define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71
typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ac_conn_confirm(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_data_ind(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_disc_ind(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_ind(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_confirm(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_disc_cmd_p_set_x(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_dm_rsp_f_set_p(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_dm_rsp_f_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_resend_i_xxx_x_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_resend_i_rsp_f_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rej_cmd_p_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rej_rsp_f_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rej_xxx_x_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_set_remote_busy(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rr_cmd_p_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rr_rsp_f_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_ack_rsp_f_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_rr_xxx_x_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_ack_xxx_x_set_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_ua_rsp_f_set_p(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_set_s_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_s_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_p_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_ack_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_rej_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_ack_tmr_if_not_running(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_stop_ack_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_p_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_rej_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_all_timers(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_other_timers(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_upd_nr_received(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_tx_win_size(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_dec_tx_win_size(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_upd_p_flag(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_2(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_set_p_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_remote_busy_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_cause_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_cause_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_retry_cnt_by_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_vr_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_vr_by_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_vs_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_vs(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_upd_vs(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_disc(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_reset(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_disc_confirm(struct sock* sk, struct sk_buff *skb);
extern u8 llc_circular_between(u8 a, u8 b, u8 c);
extern int llc_conn_ac_send_ack_if_needed(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_sendack_flag(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_send_i_as_ack(struct sock* sk, struct sk_buff *skb);
extern void llc_conn_busy_tmr_cb(unsigned long timeout_data);
extern void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data);
extern void llc_conn_ack_tmr_cb(unsigned long timeout_data);
extern void llc_conn_rej_tmr_cb(unsigned long timeout_data);
extern void llc_conn_set_p_flag(struct sock *sk, u8 value);
#endif /* LLC_C_AC_H */

269
include/net/llc_c_ev.h Normal file
View File

@@ -0,0 +1,269 @@
#ifndef LLC_C_EV_H
#define LLC_C_EV_H
/*
* Copyright (c) 1997 by Procom Technology,Inc.
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation.
* This program is distributed without any warranty or implied warranty
* of merchantability or fitness for a particular purpose.
*
* See the GNU General Public License for more details.
*/
#include <net/sock.h>
/* Connection component state transition event qualifiers */
/* Types of events (possible values in 'ev->type') */
#define LLC_CONN_EV_TYPE_SIMPLE 1
#define LLC_CONN_EV_TYPE_CONDITION 2
#define LLC_CONN_EV_TYPE_PRIM 3
#define LLC_CONN_EV_TYPE_PDU 4 /* command/response PDU */
#define LLC_CONN_EV_TYPE_ACK_TMR 5
#define LLC_CONN_EV_TYPE_P_TMR 6
#define LLC_CONN_EV_TYPE_REJ_TMR 7
#define LLC_CONN_EV_TYPE_BUSY_TMR 8
#define LLC_CONN_EV_TYPE_RPT_STATUS 9
#define LLC_CONN_EV_TYPE_SENDACK_TMR 10
#define NBR_CONN_EV 5
/* Connection events which cause state transitions when fully qualified */
#define LLC_CONN_EV_CONN_REQ 1
#define LLC_CONN_EV_CONN_RESP 2
#define LLC_CONN_EV_DATA_REQ 3
#define LLC_CONN_EV_DISC_REQ 4
#define LLC_CONN_EV_RESET_REQ 5
#define LLC_CONN_EV_RESET_RESP 6
#define LLC_CONN_EV_LOCAL_BUSY_DETECTED 7
#define LLC_CONN_EV_LOCAL_BUSY_CLEARED 8
#define LLC_CONN_EV_RX_BAD_PDU 9
#define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X 10
#define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X 11
#define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X 12
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X 13
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns 14
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns 15
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X 16
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns 17
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns 18
#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X 19
#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X 20
#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X 21
#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X 22
#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X 23
#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X 24
#define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X 25
#define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X 26
#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X 27
#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X 28
#define LLC_CONN_EV_RX_XXX_YYY 29
#define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr 30
#define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr 31
#define LLC_CONN_EV_P_TMR_EXP 32
#define LLC_CONN_EV_ACK_TMR_EXP 33
#define LLC_CONN_EV_REJ_TMR_EXP 34
#define LLC_CONN_EV_BUSY_TMR_EXP 35
#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 36
#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0 37
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns 38
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns 39
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns 40
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns 41
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 42
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 43
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 44
#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 45
#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 46
#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 47
#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 48
#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 49
#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 50
#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 51
#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 52
#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 53
#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 54
#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 55
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 56
#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 57
#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 58
#define LLC_CONN_EV_TX_BUFF_FULL 59
#define LLC_CONN_EV_INIT_P_F_CYCLE 100
/*
* Connection event qualifiers; for some events a certain combination of
* these qualifiers must be TRUE before event recognized valid for state;
* these constants act as indexes into the Event Qualifier function
* table
*/
#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1 1
#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0 2
#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2 3
#define LLC_CONN_EV_QFY_P_FLAG_EQ_1 4
#define LLC_CONN_EV_QFY_P_FLAG_EQ_0 5
#define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit 6
#define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0 7
#define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2 8
#define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2 9
#define LLC_CONN_EV_QFY_S_FLAG_EQ_1 10
#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11
#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12
struct llc_conn_state_ev {
u8 type;
u8 prim;
u8 prim_type;
u8 reason;
u8 status;
u8 ind_prim;
u8 cfm_prim;
};
static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
{
return (struct llc_conn_state_ev *)skb->cb;
}
typedef int (*llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb);
typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_local_busy_detected(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk, struct sk_buff *skb);
/* NOT_USED functions and their variations */
extern int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb);
/* Available connection action qualifiers */
extern int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_conn(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_disc(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_failed(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk,
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk,
struct sk_buff *skb);
static __inline__ int llc_conn_space(struct sock *sk, struct sk_buff *skb)
{
return atomic_read(&sk->sk_rmem_alloc) + skb->truesize <
(unsigned)sk->sk_rcvbuf;
}
#endif /* LLC_C_EV_H */

Some files were not shown because too many files have changed in this diff Show More