(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
#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>
#define tca_gen(name) \
struct tcf_##name *next; \
u32 index; \
int refcnt; \
int bindcnt; \
u32 capab; \
int action; \
struct tcf_t tm; \
struct gnet_stats_basic bstats; \
struct gnet_stats_queue qstats; \
struct gnet_stats_rate_est rate_est; \
spinlock_t *stats_lock; \
spinlock_t lock
struct tcf_police
{
tca_gen(police);
int result;
u32 ewma_rate;
u32 burst;
u32 mtu;
u32 toks;
u32 ptoks;
psched_time_t t_c;
struct qdisc_rate_table *R_tab;
struct qdisc_rate_table *P_tab;
};
#ifdef CONFIG_NET_CLS_ACT
#define ACT_P_CREATED 1
#define ACT_P_DELETED 1
struct tcf_act_hdr
{
tca_gen(act_hdr);
};
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;
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 *);
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 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 int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind);
extern int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind);
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 *);
extern int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *,int , int );
extern int tcf_act_police_dump(struct sk_buff *, struct tc_action *, int, int);
extern int tcf_act_police(struct sk_buff **skb, struct tc_action *a);
#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->bindcnt--;
}
p->refcnt--;
if (p->refcnt <= 0 && !p->bindcnt) {
tcf_police_destroy(p);
ret = 1;
}
}
#else
if (p && --p->refcnt == 0)
tcf_police_destroy(p);
#endif /* CONFIG_NET_CLS_ACT */
return ret;
}
#endif

View File

@@ -0,0 +1,239 @@
#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
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
__u32 valid;
__u32 prefered;
__u32 reserved2;
struct in6_addr prefix;
};
#ifdef __KERNEL__
#include <linux/in6.h>
#include <linux/netdevice.h>
#include <net/if_inet6.h>
#define IN6_ADDR_HSIZE 16
extern void 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);
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);
/*
* 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_dev_ac_dec(struct net_device *dev, 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 (struct inet6_dev *)dev->ip6_ptr;
}
extern rwlock_t addrconf_lock;
static inline struct inet6_dev *
in6_dev_get(struct net_device *dev)
{
struct inet6_dev *idev = NULL;
read_lock(&addrconf_lock);
idev = dev->ip6_ptr;
if (idev)
atomic_inc(&idev->refcnt);
read_unlock(&addrconf_lock);
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 = 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));
}
#endif
#endif

View File

@@ -0,0 +1,78 @@
#ifndef __LINUX_NET_AFUNIX_H
#define __LINUX_NET_AFUNIX_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 rwlock_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 */
};
#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb))
#define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
#define unix_state_rlock(s) read_lock(&unix_sk(s)->lock)
#define unix_state_runlock(s) read_unlock(&unix_sk(s)->lock)
#define unix_state_wlock(s) write_lock(&unix_sk(s)->lock)
#define unix_state_wunlock(s) write_unlock(&unix_sk(s)->lock)
#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 semaphore readsem;
struct sock *peer;
struct sock *other;
struct sock *gc_tree;
atomic_t inflight;
rwlock_t lock;
wait_queue_head_t peer_wait;
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
#endif
#endif

View File

@@ -0,0 +1,35 @@
#ifndef _NET_AH_H
#define _NET_AH_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;
void (*icv)(struct ah_data*,
struct sk_buff *skb, u8 *icv);
struct crypto_tfm *tfm;
};
static inline void
ah_hmac_digest(struct ah_data *ahp, struct sk_buff *skb, u8 *auth_data)
{
struct crypto_tfm *tfm = ahp->tfm;
memset(auth_data, 0, ahp->icv_trunc_len);
crypto_hmac_init(tfm, ahp->key, &ahp->key_len);
skb_icv_walk(skb, tfm, 0, skb->len, crypto_hmac_update);
crypto_hmac_final(tfm, ahp->key, &ahp->key_len, ahp->work_icv);
memcpy(auth_data, ahp->work_icv, ahp->icv_trunc_len);
}
#endif

View File

@@ -0,0 +1,32 @@
/* 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_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt);
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, u32 dest_ip,
struct net_device *dev, u32 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(u32 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, u32 dest_ip,
struct net_device *dev, u32 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 */

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/skbuff.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 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 {
u32 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

View File

@@ -0,0 +1,387 @@
/*
* Declarations of AX.25 type objects.
*
* Alan Cox (GW4PTS) 10/11/93
*/
#ifndef _AX25_H
#define _AX25_H
#include <linux/config.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_IP 0xCC
#define AX25_P_ARP 0xCD
#define AX25_P_TEXT 0xF0
#define AX25_P_NETROM 0xCF
#define AX25_P_SEGMENT 0x08
/* 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,
AX25_STATE_1,
AX25_STATE_2,
AX25_STATE_3,
AX25_STATE_4
};
#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,
AX25_PROTO_DAMA_SLAVE,
AX25_PROTO_DAMA_MASTER
};
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 (10 * HZ) /* T1=10s */
#define AX25_DEF_T2 (3 * HZ) /* T2=3s */
#define AX25_DEF_T3 (300 * HZ) /* T3=300s */
#define AX25_DEF_N2 10 /* N2=10 */
#define AX25_DEF_IDLE (0 * 60 * HZ) /* 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 (3 * 60 * HZ) /* DAMA timeout 3 minutes */
typedef struct ax25_uid_assoc {
struct ax25_uid_assoc *next;
uid_t uid;
ax25_address call;
} ax25_uid_assoc;
typedef struct {
ax25_address calls[AX25_MAX_DIGIS];
unsigned char repeated[AX25_MAX_DIGIS];
unsigned char ndigi;
char lastrepeat;
} ax25_digi;
typedef struct ax25_route {
struct ax25_route *next;
atomic_t ref;
ax25_address callsign;
struct net_device *dev;
ax25_digi *digipeat;
char ip_mode;
struct timer_list timer;
} ax25_route;
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)) {
if (ax25->digipeat)
kfree(ax25->digipeat);
kfree(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 *ax25_create_cb(void);
extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
extern int ax25_create(struct socket *, int);
extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
/* ax25_addr.c */
extern ax25_address null_ax25_address;
extern char *ax2asc(ax25_address *);
extern ax25_address *asc2ax(char *);
extern int ax25cmp(ax25_address *, ax25_address *);
extern int ax25digicmp(ax25_digi *, ax25_digi *);
extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *);
extern int ax25_addr_build(unsigned char *, ax25_address *, ax25_address *, ax25_digi *, int, int);
extern int ax25_addr_size(ax25_digi *);
extern void ax25_digi_invert(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_on(ax25_dev *);
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 */
extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *));
extern void ax25_protocol_release(unsigned int);
extern int ax25_linkfail_register(void (*)(ax25_cb *, int));
extern void ax25_linkfail_release(void (*)(ax25_cb *, int));
extern int 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 *);
/* ax25_ip.c */
extern int ax25_encapsulate(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 *);
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 struct file_operations ax25_route_fops;
extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *,
struct net_device *);
extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *);
extern void ax25_rt_free(void);
static inline void ax25_put_route(ax25_route *ax25_rt)
{
atomic_dec(&ax25_rt->ref);
}
/* 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_address *ax25_findbyuid(uid_t);
extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *);
extern 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,182 @@
/*
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)
#ifdef HCI_DATA_DUMP
#define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len)
#else
#define BT_DMP(D...)
#endif
extern struct proc_dir_entry *proc_bt;
/* 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);
struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio);
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 {
int incoming;
};
#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb))
static inline struct sk_buff *bt_skb_alloc(unsigned int len, int 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;
}
void bt_dump(char *pref, __u8 *buf, int count);
int bt_err(__u16 code);
#endif /* __BLUETOOTH_H */

View File

@@ -0,0 +1,747 @@
/*
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_VHCI 0
#define HCI_USB 1
#define HCI_PCCARD 2
#define HCI_UART 3
#define HCI_RS232 4
#define HCI_PCI 5
/* HCI device quirks */
enum {
HCI_QUIRK_RESET_ON_INIT
};
/* 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_CONN_TIMEOUT (HZ * 40)
#define HCI_DISCONN_TIMEOUT (HZ * 2)
#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
/* 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_SNIF 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
/* Link policies */
#define HCI_LP_RSWITCH 0x0001
#define HCI_LP_HOLD 0x0002
#define HCI_LP_SNIFF 0x0004
#define HCI_LP_PARK 0x0008
/* Link mode */
#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;
__u16 hci_rev;
__u8 lmp_ver;
__u16 manufacturer;
__u16 lmp_subver;
} __attribute__ ((packed));
#define OCF_READ_LOCAL_FEATURES 0x0003
struct hci_rp_read_loc_features {
__u8 status;
__u8 features[8];
} __attribute__ ((packed));
#define OCF_READ_BUFFER_SIZE 0x0005
struct hci_rp_read_buffer_size {
__u8 status;
__u16 acl_mtu;
__u8 sco_mtu;
__u16 acl_max_pkt;
__u16 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;
__u16 voice_setting;
} __attribute__ ((packed));
#define OCF_WRITE_VOICE_SETTING 0x0026
struct hci_cp_write_voice_setting {
__u16 voice_setting;
} __attribute__ ((packed));
#define OCF_HOST_BUFFER_SIZE 0x0033
struct hci_cp_host_buffer_size {
__u16 acl_mtu;
__u8 sco_mtu;
__u16 acl_max_pkt;
__u16 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;
__u16 pkt_type;
__u8 pscan_rep_mode;
__u8 pscan_mode;
__u16 clock_offset;
__u8 role_switch;
} __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 {
__u16 handle;
__u8 reason;
} __attribute__ ((packed));
#define OCF_ADD_SCO 0x0007
struct hci_cp_add_sco {
__u16 handle;
__u16 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_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 {
__u16 handle;
__u16 pkt_type;
} __attribute__ ((packed));
#define OCF_AUTH_REQUESTED 0x0011
struct hci_cp_auth_requested {
__u16 handle;
} __attribute__ ((packed));
#define OCF_SET_CONN_ENCRYPT 0x0013
struct hci_cp_set_conn_encrypt {
__u16 handle;
__u8 encrypt;
} __attribute__ ((packed));
#define OCF_CHANGE_CONN_LINK_KEY 0x0015
struct hci_cp_change_conn_link_key {
__u16 handle;
} __attribute__ ((packed));
#define OCF_READ_REMOTE_FEATURES 0x001B
struct hci_cp_read_rmt_features {
__u16 handle;
} __attribute__ ((packed));
#define OCF_READ_REMOTE_VERSION 0x001D
struct hci_cp_read_rmt_version {
__u16 handle;
} __attribute__ ((packed));
/* Link Policy */
#define OGF_LINK_POLICY 0x02
#define OCF_ROLE_DISCOVERY 0x0009
struct hci_cp_role_discovery {
__u16 handle;
} __attribute__ ((packed));
struct hci_rp_role_discovery {
__u8 status;
__u16 handle;
__u8 role;
} __attribute__ ((packed));
#define OCF_READ_LINK_POLICY 0x000C
struct hci_cp_read_link_policy {
__u16 handle;
} __attribute__ ((packed));
struct hci_rp_read_link_policy {
__u8 status;
__u16 handle;
__u16 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 {
__u16 handle;
__u16 policy;
} __attribute__ ((packed));
struct hci_rp_write_link_policy {
__u8 status;
__u16 handle;
} __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];
__u16 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];
__u16 clock_offset;
__s8 rssi;
} __attribute__ ((packed));
#define HCI_EV_CONN_COMPLETE 0x03
struct hci_ev_conn_complete {
__u8 status;
__u16 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;
__u16 handle;
__u8 reason;
} __attribute__ ((packed));
#define HCI_EV_AUTH_COMPLETE 0x06
struct hci_ev_auth_complete {
__u8 status;
__u16 handle;
} __attribute__ ((packed));
#define HCI_EV_ENCRYPT_CHANGE 0x08
struct hci_ev_encrypt_change {
__u8 status;
__u16 handle;
__u8 encrypt;
} __attribute__ ((packed));
#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09
struct hci_ev_change_conn_link_key_complete {
__u8 status;
__u16 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;
__u16 handle;
struct hci_qos qos;
} __attribute__ ((packed));
#define HCI_EV_CMD_COMPLETE 0x0E
struct hci_ev_cmd_complete {
__u8 ncmd;
__u16 opcode;
} __attribute__ ((packed));
#define HCI_EV_CMD_STATUS 0x0F
struct hci_ev_cmd_status {
__u8 status;
__u8 ncmd;
__u16 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;
__u16 handle;
__u8 mode;
__u16 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_RMT_FEATURES 0x0B
struct hci_ev_rmt_features {
__u8 status;
__u16 handle;
__u8 features[8];
} __attribute__ ((packed));
#define HCI_EV_RMT_VERSION 0x0C
struct hci_ev_rmt_version {
__u8 status;
__u16 handle;
__u8 lmp_ver;
__u16 manufacturer;
__u16 lmp_subver;
} __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 {
__u16 opcode; /* OCF & OGF */
__u8 plen;
} __attribute__ ((packed));
struct hci_event_hdr {
__u8 evt;
__u8 plen;
} __attribute__ ((packed));
struct hci_acl_hdr {
__u16 handle; /* Handle & Flags(PB, BC) */
__u16 dlen;
} __attribute__ ((packed));
struct hci_sco_hdr {
__u16 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];
__u16 opcode;
};
struct hci_ufilter {
__u32 type_mask;
__u32 event_mask[2];
__u16 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,594 @@
/*
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 <linux/proc_fs.h>
#include <net/bluetooth/hci.h>
/* HCI upper protocols */
#define HCI_PROTO_L2CAP 0
#define HCI_PROTO_SCO 1
#define HCI_INIT_TIMEOUT (HZ * 10)
extern struct proc_dir_entry *proc_bt_hci;
/* HCI Core structures */
struct inquiry_data {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
__u16 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];
__u16 voice_setting;
__u16 pkt_type;
__u16 link_policy;
__u16 link_mode;
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;
void *driver_data;
void *core_data;
atomic_t promisc;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
struct class_device class_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 type;
__u8 out;
__u8 dev_class[3];
__u32 link_mode;
unsigned long pend;
unsigned int sent;
struct sk_buff_head data_q;
struct timer_list timer;
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
};
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;
}
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);
static inline void hci_conn_set_timer(struct hci_conn *conn, unsigned long timeout)
{
mod_timer(&conn->timer, jiffies + timeout);
}
static inline void hci_conn_del_timer(struct hci_conn *conn)
{
del_timer(&conn->timer);
}
static inline void hci_conn_hold(struct hci_conn *conn)
{
atomic_inc(&conn->refcnt);
hci_conn_del_timer(conn);
}
static inline void hci_conn_put(struct hci_conn *conn)
{
if (atomic_dec_and_test(&conn->refcnt)) {
if (conn->type == ACL_LINK) {
unsigned long timeo = (conn->out) ?
HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2;
hci_conn_set_timer(conn, timeo);
} else
hci_conn_set_timer(conn, HZ / 100);
}
}
/* ----- 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 */
do_gettimeofday(&skb->stamp);
/* 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);
#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->class_dev.dev = (pdev))
/* ----- LMP capabilities ----- */
#define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
/* ----- 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);
};
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);
}
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->sk_protinfo)
struct hci_pinfo {
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);
void hci_req_cancel(struct hci_dev *hdev, int err);
#endif /* __HCI_CORE_H */

View File

@@ -0,0 +1,248 @@
/*
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;
};
/* Socket options */
#define L2CAP_OPTIONS 0x01
struct l2cap_options {
__u16 omtu;
__u16 imtu;
__u16 flush_to;
};
#define L2CAP_CONNINFO 0x02
struct l2cap_conninfo {
__u16 hci_handle;
};
#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
#define L2CAP_QOS 0x04
struct l2cap_qos {
__u16 service_type;
__u32 token_rate;
__u32 token_bucket_size;
__u32 peak_bandwidth;
__u32 latency;
__u32 delay_variation;
};
#define L2CAP_SERV_NO_TRAFFIC 0x00
#define L2CAP_SERV_BEST_EFFORT 0x01
#define L2CAP_SERV_GUARANTEED 0x02
/* 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_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->sk_protinfo)
struct l2cap_pinfo {
__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,357 @@
/*
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_DEFAULT_MTU 127
#define RFCOMM_DEFAULT_CREDITS 7
#define RFCOMM_MAX_L2CAP_MTU 1024
#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 0x4
#define RFCOMM_RPN_PARITY_EVEN 0x5
#define RFCOMM_RPN_PARITY_MARK 0x6
#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;
u16 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;
u16 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;
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_MSC_PENDING 2
#define RFCOMM_TIMED_OUT 3
/* 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_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
extern struct task_struct *rfcomm_thread;
extern unsigned long rfcomm_event;
static inline void rfcomm_schedule(uint event)
{
if (!rfcomm_thread)
return;
//set_bit(event, &rfcomm_event);
set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
wake_up_process(rfcomm_thread);
}
extern struct semaphore rfcomm_sem;
#define rfcomm_lock() down(&rfcomm_sem);
#define rfcomm_unlock() up(&rfcomm_sem);
/* ---- RFCOMM DLCs (channels) ---- */
struct rfcomm_dlc *rfcomm_dlc_alloc(int 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 ---- */
struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
void rfcomm_session_del(struct rfcomm_session *s);
void rfcomm_session_close(struct rfcomm_session *s, int err);
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);
}
static inline void rfcomm_session_put(struct rfcomm_session *s)
{
if (atomic_dec_and_test(&s->refcnt))
rfcomm_session_del(s);
}
/* ---- RFCOMM chechsum ---- */
extern u8 rfcomm_crc_table[];
/* ---- RFCOMM sockets ---- */
struct sockaddr_rc {
sa_family_t rc_family;
bdaddr_t rc_bdaddr;
u8 rc_channel;
};
#define rfcomm_pi(sk) ((struct rfcomm_pinfo *)sk->sk_protinfo)
struct rfcomm_pinfo {
struct rfcomm_dlc *dlc;
u8 channel;
};
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);
extern struct proc_dir_entry *proc_bt_rfcomm;
#endif /* __RFCOMM_H */

View File

@@ -0,0 +1,77 @@
/*
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;
};
/* set/get sockopt defines */
#define SCO_OPTIONS 0x01
struct sco_options {
__u16 mtu;
};
#define SCO_CONNINFO 0x02
struct sco_conninfo {
__u16 hci_handle;
};
/* ---- 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->sk_protinfo)
struct sco_pinfo {
__u32 flags;
struct sco_conn *conn;
};
#endif /* __SCO_H */

View File

@@ -0,0 +1,87 @@
/*
* 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
unsigned int csum_and_copy_from_user (const char __user *src, char *dst,
int len, int sum, int *err_ptr)
{
if (verify_area(VERIFY_READ, src, len) == 0)
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__ unsigned int csum_and_copy_to_user
(const char *src, char __user *dst, int len, unsigned int 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 -1; /* invalid checksum */
}
#endif
static inline unsigned int csum_add(unsigned int csum, unsigned int addend)
{
csum += addend;
return csum + (csum < addend);
}
static inline unsigned int csum_sub(unsigned int csum, unsigned int addend)
{
return csum_add(csum, ~addend);
}
static inline unsigned int
csum_block_add(unsigned int csum, unsigned int csum2, int offset)
{
if (offset&1)
csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF);
return csum_add(csum, csum2);
}
static inline unsigned int
csum_block_sub(unsigned int csum, unsigned int csum2, int offset)
{
if (offset&1)
csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF);
return csum_sub(csum, csum2);
}
#endif

View File

@@ -0,0 +1,39 @@
#ifndef NET_COMPAT_H
#define NET_COMPAT_H
#include <linux/config.h>
#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;
};
#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 *, unsigned char *,
int);
#endif /* NET_COMPAT_H */

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 *);
int (*request)(struct datalink_proto *, struct sk_buff *,
unsigned char *);
struct list_head node;
};
#endif

View File

@@ -0,0 +1,234 @@
#ifndef _NET_DN_H
#define _NET_DN_H
#include <linux/dn.h>
#include <asm/byteorder.h>
typedef unsigned short dn_address;
#define dn_ntohs(x) le16_to_cpu((unsigned short)(x))
#define dn_htons(x) cpu_to_le16((unsigned short)(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 */
unsigned short addrloc;
unsigned short addrrem;
unsigned short numdat;
unsigned short numoth;
unsigned short numoth_rcv;
unsigned short numdat_rcv;
unsigned short ackxmt_dat;
unsigned short ackxmt_oth;
unsigned short ackrcv_dat;
unsigned short ackrcv_oth;
unsigned char flowrem_sw;
unsigned char flowloc_sw;
#define DN_SEND 2
#define DN_DONTSEND 1
#define DN_NOCHANGE 0
unsigned short flowrem_dat;
unsigned short flowrem_oth;
unsigned short flowloc_dat;
unsigned short flowloc_oth;
unsigned char services_rem;
unsigned char services_loc;
unsigned char info_rem;
unsigned char info_loc;
unsigned short segsize_rem;
unsigned short segsize_loc;
unsigned char nonagle;
unsigned char multi_ireq;
unsigned char 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);
};
#define DN_SK(__sk) ((struct dn_scp *)(__sk)->sk_protinfo)
/*
* 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 {
unsigned short dst;
unsigned short src;
unsigned short hops;
unsigned short dst_port;
unsigned short src_port;
unsigned char services;
unsigned char info;
unsigned char rt_flags;
unsigned char nsp_flags;
unsigned short segsize;
unsigned short segnum;
unsigned short xmit_count;
unsigned long stamp;
int iif;
};
static inline dn_address dn_eth2dn(unsigned char *ethaddr)
{
return ethaddr[4] | (ethaddr[5] << 8);
}
static inline dn_address dn_saddr2dn(struct sockaddr_dn *saddr)
{
return *(dn_address *)saddr->sdn_nodeaddr;
}
static inline void dn_dn2eth(unsigned char *ethaddr, dn_address addr)
{
ethaddr[0] = 0xAA;
ethaddr[1] = 0x00;
ethaddr[2] = 0x04;
ethaddr[3] = 0x00;
ethaddr[4] = (unsigned char)(addr & 0xff);
ethaddr[5] = (unsigned char)(addr >> 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;
fl->uli_u.dnports.objnum = scp->addr.sdn_objnum;
if (fl->uli_u.dnports.objnum == 0) {
fl->uli_u.dnports.objnamel = scp->addr.sdn_objnamel;
memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16);
}
}
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(dn_address, 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 void dn_start_fast_timer(struct sock *sk);
extern void dn_stop_fast_timer(struct sock *sk);
extern dn_address 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;
#endif /* _NET_DN_H */

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;
dn_address ifa_local;
dn_address ifa_address;
unsigned char ifa_flags;
unsigned char 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;
unsigned char 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
{
unsigned char msgflg __attribute__((packed));
unsigned short dstnode __attribute__((packed));
unsigned short srcnode __attribute__((packed));
unsigned char forward __attribute__((packed));
};
struct dn_long_packet
{
unsigned char msgflg __attribute__((packed));
unsigned char d_area __attribute__((packed));
unsigned char d_subarea __attribute__((packed));
unsigned char d_id[6] __attribute__((packed));
unsigned char s_area __attribute__((packed));
unsigned char s_subarea __attribute__((packed));
unsigned char s_id[6] __attribute__((packed));
unsigned char nl2 __attribute__((packed));
unsigned char visit_ct __attribute__((packed));
unsigned char s_class __attribute__((packed));
unsigned char pt __attribute__((packed));
};
/*------------------------- DRP - Routing messages ---------------------*/
struct endnode_hello_message
{
unsigned char msgflg __attribute__((packed));
unsigned char tiver[3] __attribute__((packed));
unsigned char id[6] __attribute__((packed));
unsigned char iinfo __attribute__((packed));
unsigned short blksize __attribute__((packed));
unsigned char area __attribute__((packed));
unsigned char seed[8] __attribute__((packed));
unsigned char neighbor[6] __attribute__((packed));
unsigned short timer __attribute__((packed));
unsigned char mpd __attribute__((packed));
unsigned char datalen __attribute__((packed));
unsigned char data[2] __attribute__((packed));
};
struct rtnode_hello_message
{
unsigned char msgflg __attribute__((packed));
unsigned char tiver[3] __attribute__((packed));
unsigned char id[6] __attribute__((packed));
unsigned char iinfo __attribute__((packed));
unsigned short blksize __attribute__((packed));
unsigned char priority __attribute__((packed));
unsigned char area __attribute__((packed));
unsigned short timer __attribute__((packed));
unsigned char 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(dn_address *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, dn_address 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 */

View File

@@ -0,0 +1,205 @@
#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 dn_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;
u32 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;
dn_address 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 {
u16 datum;
} dn_fib_key_t;
typedef struct {
u16 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 {
int 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_rt_message(struct sk_buff *skb);
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 u16 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);
extern int dn_fib_sync_down(dn_address local, struct net_device *dev,
int force);
extern int dn_fib_sync_up(struct net_device *dev);
/*
* dn_tables.c
*/
extern struct dn_fib_table *dn_fib_get_table(int 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 void dn_fib_rule_put(struct dn_fib_rule *);
extern __u16 dn_fib_rules_policy(__u16 saddr, struct dn_fib_res *res, unsigned *flags);
extern unsigned dnet_addr_type(__u16 addr);
extern int dn_fib_lookup(const 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)
dn_fib_rule_put(res->r);
}
extern struct dn_fib_table *dn_fib_tables[];
#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 u16 dnet_make_mask(int n)
{
if (n)
return htons(~((1<<(16-n))-1));
return 0;
}
#endif /* _NET_DN_FIB_H */

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;
dn_address 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;
unsigned char 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 */

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, int gfp);
extern void dn_nsp_send_disc(struct sock *sk, unsigned char type,
unsigned short reason, int 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, int 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, int 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
{
unsigned char msgflg __attribute__((packed));
unsigned short dstaddr __attribute__((packed));
unsigned short srcaddr __attribute__((packed));
};
struct nsp_data_opt_msg
{
unsigned short acknum __attribute__((packed));
unsigned short segnum __attribute__((packed));
unsigned short lsflgs __attribute__((packed));
};
struct nsp_data_opt_msg1
{
unsigned short acknum __attribute__((packed));
unsigned short segnum __attribute__((packed));
};
/* Acknowledgment Message (data/other data) */
struct nsp_data_ack_msg
{
unsigned char msgflg __attribute__((packed));
unsigned short dstaddr __attribute__((packed));
unsigned short srcaddr __attribute__((packed));
unsigned short acknum __attribute__((packed));
};
/* Connect Acknowledgment Message */
struct nsp_conn_ack_msg
{
unsigned char msgflg __attribute__((packed));
unsigned short dstaddr __attribute__((packed));
};
/* Connect Initiate/Retransmit Initiate/Connect Confirm */
struct nsp_conn_init_msg
{
unsigned char msgflg __attribute__((packed));
#define NSP_CI 0x18 /* Connect Initiate */
#define NSP_RCI 0x68 /* Retrans. Conn Init */
unsigned short dstaddr __attribute__((packed));
unsigned short srcaddr __attribute__((packed));
unsigned char services __attribute__((packed));
#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 */
unsigned char info __attribute__((packed));
unsigned short segsize __attribute__((packed));
};
/* Disconnect Initiate/Disconnect Confirm */
struct nsp_disconn_init_msg
{
unsigned char msgflg __attribute__((packed));
unsigned short dstaddr __attribute__((packed));
unsigned short srcaddr __attribute__((packed));
unsigned short reason __attribute__((packed));
};
struct srcobj_fmt
{
char format __attribute__((packed));
unsigned char task __attribute__((packed));
unsigned short grpcode __attribute__((packed));
unsigned short usrcode __attribute__((packed));
char 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(unsigned short seq1, unsigned short seq2)
{
seq1 &= 0x0fff;
seq2 &= 0x0fff;
return (int)((seq1 - seq2) & 0x0fff) > 2048;
}
static __inline__ int dn_after(unsigned short seq1, unsigned short seq2)
{
seq1 &= 0x0fff;
seq2 &= 0x0fff;
return (int)((seq2 - seq1) & 0x0fff) > 2048;
}
static __inline__ int dn_equal(unsigned short seq1, unsigned short seq2)
{
return ((seq1 ^ seq2) & 0x0fff) == 0;
}
static __inline__ int dn_before_or_equal(unsigned short seq1, unsigned short seq2)
{
return (dn_before(seq1, seq2) || dn_equal(seq1, seq2));
}
static __inline__ void seq_add(unsigned short *seq, unsigned short off)
{
(*seq) += off;
(*seq) &= 0x0fff;
}
static __inline__ int seq_next(unsigned short seq1, unsigned short seq2)
{
return dn_equal(seq1 + 1, seq2);
}
/*
* Can we delay the ack ?
*/
static __inline__ int sendack(unsigned short 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 */

View File

@@ -0,0 +1,112 @@
#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, int 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;
struct dn_route *rt_next;
} u;
__u16 rt_saddr;
__u16 rt_daddr;
__u16 rt_gateway;
__u16 rt_local_src; /* Source used for forwarding packets */
__u16 rt_src_map;
__u16 rt_dst_map;
unsigned rt_flags;
unsigned rt_type;
struct flowi fl;
};
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 */

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(*(__u16 *) ipv6h) >> 4;
}
static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask,
__u8 value)
{
__u32 check = ntohs(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 = htons(check);
iph->tos = dsfield;
}
static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask,
__u8 value)
{
__u16 tmp;
tmp = ntohs(*(__u16 *) ipv6h);
tmp = (tmp & ((mask << 4) | 0xf00f)) | (value << 4);
*(__u16 *) ipv6h = htons(tmp);
}
#endif

View File

@@ -0,0 +1,265 @@
/*
* 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/config.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 dst_entry *next;
atomic_t __refcnt; /* client references */
int __use;
struct dst_entry *child;
struct net_device *dev;
int obsolete;
int flags;
#define DST_HOST 1
#define DST_NOXFRM 2
#define DST_NOPOLICY 4
#define DST_NOHASH 8
unsigned long lastuse;
unsigned long expires;
unsigned short header_len; /* more 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;
int error;
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;
struct rcu_head rcu_head;
char info[0];
};
struct dst_ops
{
unsigned short family;
unsigned short 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 *, 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 (*get_mss)(struct dst_entry *dst, u32 mtu);
int entry_size;
atomic_t entries;
kmem_cache_t *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_path_metric(const struct dst_entry *dst, int metric)
{
return dst->path->metrics[metric-1];
}
static inline u32
dst_pmtu(const struct dst_entry *dst)
{
u32 mtu = dst_path_metric(dst, RTAX_MTU);
/* Yes, _exactly_. This is paranoia. */
barrier();
return mtu;
}
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);
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)
{
int err;
for (;;) {
err = skb->dst->output(skb);
if (likely(err == 0))
return err;
if (unlikely(err != NET_XMIT_BYPASS))
return err;
}
}
/* 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;
}
}
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 */

View File

@@ -0,0 +1,59 @@
#ifndef _NET_ESP_H
#define _NET_ESP_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 */
u8 *ivec; /* ivec buffer */
/* 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 padlen; /* 0..255 */
struct crypto_tfm *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_tfm *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 void
esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset,
int len, u8 *auth_data)
{
struct crypto_tfm *tfm = esp->auth.tfm;
char *icv = esp->auth.work_icv;
memset(auth_data, 0, esp->auth.icv_trunc_len);
crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len);
skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update);
crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv);
memcpy(auth_data, icv, esp->auth.icv_trunc_len);
}
#endif

View File

@@ -0,0 +1,94 @@
/*
*
* 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;
union {
struct {
__u32 daddr;
__u32 saddr;
__u32 fwmark;
__u8 tos;
__u8 scope;
} ip4_u;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
__u32 flowlabel;
} ip6_u;
struct {
__u16 daddr;
__u16 saddr;
__u32 fwmark;
__u8 scope;
} dn_u;
} nl_u;
#define fld_dst nl_u.dn_u.daddr
#define fld_src nl_u.dn_u.saddr
#define fld_fwmark nl_u.dn_u.fwmark
#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_fwmark nl_u.ip4_u.fwmark
#define fl4_tos nl_u.ip4_u.tos
#define fl4_scope nl_u.ip4_u.scope
__u8 proto;
__u8 flags;
union {
struct {
__u16 sport;
__u16 dport;
} ports;
struct {
__u8 type;
__u8 code;
} icmpt;
struct {
__u16 sport;
__u16 dport;
__u8 objnum;
__u8 objnamel; /* Not 16 bits since max val is 16 */
__u8 objname[16]; /* Not zero terminated */
} dnports;
__u32 spi;
} 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
} __attribute__((__aligned__(BITS_PER_LONG/8)));
#define FLOW_DIR_IN 0
#define FLOW_DIR_OUT 1
#define FLOW_DIR_FWD 2
typedef void (*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

View File

@@ -0,0 +1,48 @@
#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;
struct rtattr * xstats;
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

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, <bir7@leland.Stanford.Edu>
* 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/config.h>
#include <linux/icmp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/protocol.h>
#include <net/snmp.h>
#include <linux/ip.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)
extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 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_opt {
struct icmp_filter filter;
};
struct ipv6_pinfo;
/* WARNING: don't change the layout of the members in raw_sock! */
struct raw_sock {
struct sock sk;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct ipv6_pinfo *pinet6;
#endif
struct inet_opt inet;
struct raw_opt raw4;
};
#define raw4_sk(__sk) (&((struct raw_sock *)__sk)->raw4)
#endif /* _ICMP_H */

View File

@@ -0,0 +1,270 @@
/*
* 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
/* 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;
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 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];
u8 entropy[8];
struct timer_list regen_timer;
struct inet6_ifaddr *tempaddr_list;
__u8 work_eui64[8];
__u8 work_digest[16];
#endif
struct neigh_parms *nd_parms;
struct inet6_dev *next;
struct ipv6_devconf cnf;
struct ipv6_devstat stats;
unsigned long tstamp; /* ipv6InterfaceTable update timestamp */
};
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;
}
#endif
#endif

View File

@@ -0,0 +1,44 @@
#ifndef _INET_COMMON_H
#define _INET_COMMON_H
extern struct proto_ops inet_stream_ops;
extern struct proto_ops inet_dgram_ops;
/*
* INET4 prototypes used by INET6
*/
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 atomic_t inet_sock_nr;
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,108 @@
#ifndef _INET_ECN_H_
#define _INET_ECN_H_
#include <linux/ip.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) |= __constant_htons(INET_ECN_ECT_0 << 4); \
} while (0)
static inline void IP_ECN_set_ce(struct iphdr *iph)
{
u32 check = 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;
/*
* The following gives us:
* INET_ECN_ECT_1 => check += htons(0xFFFD)
* INET_ECN_ECT_0 => check += htons(0xFFFE)
*/
check += htons(0xFFFB) + htons(ecn);
iph->check = check + (check>=0xFFFF);
iph->tos |= INET_ECN_CE;
}
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 void IP6_ECN_set_ce(struct ipv6hdr *iph)
{
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
return;
*(u32*)iph |= htonl(INET_ECN_CE << 20);
}
static inline void IP6_ECN_clear(struct ipv6hdr *iph)
{
*(u32*)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);
}
#endif

View File

@@ -0,0 +1,67 @@
/*
* INETPEER - A storage for permanent information about peers
*
* Version: $Id: inetpeer.h,v 1.2 2002/01/12 07:54:56 davem 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
{
struct inet_peer *avl_left, *avl_right;
struct inet_peer *unused_next, **unused_prevp;
atomic_t refcnt;
unsigned long dtime; /* the time of last use of not
* referenced entries */
__u32 v4daddr; /* peer's address */
__u16 avl_height;
__u16 ip_id_count; /* IP ID for the next packet */
__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(__u32 daddr, int create);
extern spinlock_t inet_peer_unused_lock;
extern struct inet_peer *inet_peer_unused_head;
extern struct inet_peer **inet_peer_unused_tailp;
/* can be called from BH context or outside */
static inline void inet_putpeer(struct inet_peer *p)
{
spin_lock_bh(&inet_peer_unused_lock);
if (atomic_dec_and_test(&p->refcnt)) {
p->unused_prevp = inet_peer_unused_tailp;
p->unused_next = NULL;
*inet_peer_unused_tailp = p;
inet_peer_unused_tailp = &p->unused_next;
p->dtime = jiffies;
}
spin_unlock_bh(&inet_peer_unused_lock);
}
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 */

View File

@@ -0,0 +1,311 @@
/*
* 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, <bir7@leland.Stanford.Edu>
* 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/config.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/in_route.h>
#include <net/route.h>
#include <net/arp.h>
#include <net/snmp.h>
struct sock;
struct inet_skb_parm
{
struct ip_options opt; /* Compiled IP options */
unsigned char flags;
#define IPSKB_MASQUERADED 1
#define IPSKB_TRANSLATED 2
#define IPSKB_FORWARDED 4
#define IPSKB_XFRM_TUNNEL_SIZE 8
};
struct ipcm_cookie
{
u32 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 */
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,
u32 saddr, u32 daddr,
struct ip_options *opt);
extern int ip_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt);
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 (*out)(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(u32 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];
u32 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);
extern int ip_finish_output(struct sk_buff *skb);
struct ipv4_config
{
int log_martians;
int autoconfig;
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;
#ifdef CONFIG_INET
/* 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 = iph->check;
check += htons(0x0100);
iph->check = 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(u32 addr, char *buf)
{
addr=ntohl(addr);
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;
}
#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
*/
struct sk_buff *ip_defrag(struct sk_buff *skb);
extern void ipfrag_flush(void);
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, u32 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, int user);
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 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,
u16 port, u32 info, u8 *payload);
extern void ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport,
u32 info);
extern int ipv4_proc_init(void);
/* 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,
void **context);
#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__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
struct in6_addr *daddr,
__u16 len,
unsigned short proto,
unsigned int csum)
{
int carry;
__u32 ulen;
__u32 uproto;
csum += saddr->s6_addr32[0];
carry = (csum < saddr->s6_addr32[0]);
csum += carry;
csum += saddr->s6_addr32[1];
carry = (csum < saddr->s6_addr32[1]);
csum += carry;
csum += saddr->s6_addr32[2];
carry = (csum < saddr->s6_addr32[2]);
csum += carry;
csum += saddr->s6_addr32[3];
carry = (csum < saddr->s6_addr32[3]);
csum += carry;
csum += daddr->s6_addr32[0];
carry = (csum < daddr->s6_addr32[0]);
csum += carry;
csum += daddr->s6_addr32[1];
carry = (csum < daddr->s6_addr32[1]);
csum += carry;
csum += daddr->s6_addr32[2];
carry = (csum < daddr->s6_addr32[2]);
csum += carry;
csum += daddr->s6_addr32[3];
carry = (csum < daddr->s6_addr32[3]);
csum += carry;
ulen = htonl((__u32) len);
csum += ulen;
carry = (csum < ulen);
csum += carry;
uproto = htonl(proto);
csum += uproto;
carry = (csum < uproto);
csum += carry;
return csum_fold(csum);
}
#endif
#endif

View File

@@ -0,0 +1,185 @@
/*
* 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 <net/dst.h>
#include <net/flow.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
struct rt6_info;
struct fib6_node
{
struct fib6_node *parent;
struct fib6_node *left;
struct fib6_node *right;
struct fib6_node *subtree;
struct rt6_info *leaf;
__u16 fn_bit; /* bit key */
__u16 fn_flags;
__u32 fn_sernum;
};
/*
* routing information
*
*/
struct rt6key
{
struct in6_addr addr;
int plen;
};
struct rt6_info
{
union {
struct dst_entry dst;
struct rt6_info *next;
} 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 rt6key rt6i_dst;
struct rt6key rt6i_src;
u8 rt6i_protocol;
};
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;
};
extern struct fib6_walker_t fib6_walker_list;
extern rwlock_t fib6_walker_lock;
static inline void fib6_walker_link(struct fib6_walker_t *w)
{
write_lock_bh(&fib6_walker_lock);
w->next = fib6_walker_list.next;
w->prev = &fib6_walker_list;
w->next->prev = w;
w->prev->next = w;
write_unlock_bh(&fib6_walker_lock);
}
static inline void fib6_walker_unlink(struct fib6_walker_t *w)
{
write_lock_bh(&fib6_walker_lock);
w->next->prev = w->prev;
w->prev->next = w->next;
w->prev = w->next = w;
write_unlock_bh(&fib6_walker_lock);
}
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 *);
extern struct fib6_node ip6_routing_table;
/*
* exported functions
*/
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_tree(struct fib6_node *root,
int (*func)(struct rt6_info *, void *arg),
int prune, void *arg);
extern int fib6_walk(struct fib6_walker_t *w);
extern int fib6_walk_continue(struct fib6_walker_t *w);
extern int fib6_add(struct fib6_node *root,
struct rt6_info *rt,
struct nlmsghdr *nlh,
void *rtattr);
extern int fib6_del(struct rt6_info *rt,
struct nlmsghdr *nlh,
void *rtattr);
extern void inet6_rt_notify(int event, struct rt6_info *rt,
struct nlmsghdr *nlh);
extern void fib6_run_gc(unsigned long dummy);
extern void fib6_gc_cleanup(void);
extern void fib6_init(void);
#endif
#endif

View File

@@ -0,0 +1,141 @@
#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
#ifdef __KERNEL__
#include <net/flow.h>
#include <net/ip6_fib.h>
#include <net/sock.h>
#include <linux/tcp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
struct pol_chain {
int type;
int priority;
struct fib6_node *rules;
struct pol_chain *next;
};
extern struct rt6_info ip6_null_entry;
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 int ip6_route_me_harder(struct sk_buff *skb);
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 in6_rtmsg *rtmsg,
struct nlmsghdr *,
void *rtattr);
extern int ip6_ins_rt(struct rt6_info *,
struct nlmsghdr *,
void *rtattr);
extern int ip6_del_rt(struct rt6_info *,
struct nlmsghdr *,
void *rtattr);
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);
extern void rt6_purge_dflt_routers(void);
extern void rt6_reset_dflt_pointer(struct rt6_info *rt);
extern void rt6_redirect(struct in6_addr *dest,
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);
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 ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *) dst;
write_lock(&sk->sk_dst_lock);
__sk_dst_set(sk, dst);
np->daddr_cache = daddr;
np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
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

View File

@@ -0,0 +1,40 @@
/*
* $Id$
*/
#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

View File

@@ -0,0 +1,270 @@
/*
* 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 <linux/config.h>
#include <net/flow.h>
#include <linux/seq_file.h>
/* WARNING: The ordering of these elements must match ordering
* of RTA_* rtnetlink attribute numbers.
*/
struct 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 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;
u32 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;
u32 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
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;
struct fib_info *fi;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule *r;
#endif
};
#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)
struct fib_table {
unsigned char 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 *table, struct rtmsg *r,
struct kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*tb_delete)(struct fib_table *table, struct rtmsg *r,
struct kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
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(int id)
{
if (id != RT_TABLE_LOCAL)
return ip_fib_main_table;
return ip_fib_local_table;
}
static inline struct fib_table *fib_new_table(int 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_tables[RT_TABLE_LOCAL])
#define ip_fib_main_table (fib_tables[RT_TABLE_MAIN])
extern struct fib_table * fib_tables[RT_TABLE_MAX+1];
extern int fib_lookup(const struct flowi *flp, struct fib_result *res);
extern struct fib_table *__fib_new_table(int id);
extern void fib_rule_put(struct fib_rule *r);
static inline struct fib_table *fib_get_table(int id)
{
if (id == 0)
id = RT_TABLE_MAIN;
return fib_tables[id];
}
static inline struct fib_table *fib_new_table(int id)
{
if (id == 0)
id = RT_TABLE_MAIN;
return fib_tables[id] ? : __fib_new_table(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 void ip_fib_init(void);
extern void fib_flush(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(u32 src, u32 dst, u8 tos, int oif,
struct net_device *dev, u32 *spec_dst, u32 *itag);
extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
/* Exported by fib_semantics.c */
extern int ip_fib_check_default(u32 gw, struct net_device *dev);
extern int fib_sync_down(u32 local, struct net_device *dev, int force);
extern int fib_sync_up(struct net_device *dev);
extern int fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
struct kern_rta *rta, struct rtentry *r);
extern u32 __fib_res_prefsrc(struct fib_result *res);
/* Exported by fib_hash.c */
extern struct fib_table *fib_hash_init(int id);
#ifdef CONFIG_IP_MULTIPLE_TABLES
/* Exported by fib_rules.c */
extern int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb);
extern u32 fib_rules_map_destination(u32 daddr, struct fib_result *res);
#ifdef CONFIG_NET_CLS_ROUTE
extern u32 fib_rules_tclass(struct fib_result *res);
#endif
extern void fib_rules_init(void);
#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
}
#endif /* _NET_FIB_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
#ifndef _NET_IPCOMP_H
#define _NET_IPCOMP_H
#define IPCOMP_SCRATCH_SIZE 65400
struct ipcomp_data {
u16 threshold;
struct crypto_tfm **tfms;
};
#endif

View File

@@ -0,0 +1,38 @@
/*
* $Id: ipconfig.h,v 1.4 2001/04/30 04:51:46 davem Exp $
*
* Copyright (C) 1997 Martin Mares
*
* Automatic IP Layer Configuration
*/
/* The following are initdata: */
extern int ic_enable; /* Enable or disable the whole shebang */
extern int ic_proto_enabled; /* Protocols enabled (see IC_xxx) */
extern int ic_host_name_set; /* Host name set by ipconfig? */
extern int ic_set_manually; /* IPconfig parameters set manually */
extern u32 ic_myaddr; /* My IP address */
extern u32 ic_netmask; /* Netmask for local subnet */
extern u32 ic_gateway; /* Gateway IP address */
extern u32 ic_servaddr; /* Boot server IP address */
extern u32 root_server_addr; /* Address of NFS server */
extern u8 root_server_path[]; /* Path to mount as root */
/* The following are persistent (not initdata): */
extern int ic_proto_used; /* Protocol used, if any */
extern u32 ic_nameserver; /* DNS server IP address */
extern u8 ic_domain[]; /* DNS (not NIS) domain name */
/* 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 */

View File

@@ -0,0 +1,51 @@
#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 (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { \
stats->tx_bytes += pkt_len; \
stats->tx_packets++; \
} else { \
stats->tx_errors++; \
stats->tx_aborted_errors++; \
} \
} while (0)
extern int sit_init(void);
extern void sit_cleanup(void);
#endif

View File

@@ -0,0 +1,446 @@
/*
* Linux INET6 implementation
*
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
* $Id: ipv6.h,v 1.1 2002/05/20 15:13:07 jgrimm 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_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 {
unsigned char nexthdr;
unsigned char reserved;
unsigned short frag_off;
__u32 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(field) SNMP_INC_STATS(ipv6_statistics, field)
#define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field)
#define IP6_INC_STATS_USER(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);
#define UDP6_INC_STATS(field) SNMP_INC_STATS(udp_stats_in6, field)
#define UDP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_stats_in6, field)
#define UDP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_stats_in6, field)
extern atomic_t inet6_sock_nr;
int snmp6_register_dev(struct inet6_dev *idev);
int snmp6_unregister_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 *auth;
struct ipv6_opt_hdr *dst1opt;
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
};
struct ip6_flowlabel
{
struct ip6_flowlabel *next;
u32 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, u32 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 ip6_call_ra_chain(struct sk_buff *skb, int sel);
extern int ipv6_parse_hopopts(struct sk_buff *skb, int);
extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
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_scope(const struct in6_addr *addr)
{
return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
}
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 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,
__u32 w1, __u32 w2,
__u32 w3, __u32 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_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);
}
/*
* 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);
/*
* 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,
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);
/*
* 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, int len);
extern int ipv6_ext_hdr(u8 nexthdr);
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 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, u16 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);
/*
* 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;
#endif /* __KERNEL__ */
#endif /* _NET_IPV6_H */

View File

@@ -0,0 +1,160 @@
#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 {
__u32 net;
__u8 node[IPX_NODE_LEN];
__u16 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 {
__u16 ipx_checksum __attribute__ ((packed));
#define IPX_NO_CHECKSUM 0xFFFF
__u16 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 */
__u32 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;
unsigned short 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 {
__u32 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;
u32 ipx_dest_net;
u32 ipx_source_net;
struct {
u32 netnum;
int index;
} last_hop;
};
struct ipx_opt {
struct ipx_address dest_addr;
struct ipx_interface *intrfc;
unsigned short 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;
};
#define ipx_sk(__sk) ((struct ipx_opt *)(__sk)->sk_protinfo)
#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(unsigned short);
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);
}
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,82 @@
/*********************************************************************
*
* 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ø 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 */
/* IrDA Socket */
struct irda_sock {
__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 */
struct sock *sk;
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;
};
#define irda_sk(__sk) ((struct irda_sock *)(__sk)->sk_protinfo)
#endif /* AF_IRDA_H */

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,86 @@
/*********************************************************************
*
* 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[];
extern char *ircomm_event[];
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,65 @@
/*********************************************************************
*
* 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>
#include <net/irda/ircomm_event.h>
int ircomm_open_lsap(struct ircomm_cb *self);
int ircomm_lmp_connect_request(struct ircomm_cb *self,
struct sk_buff *userdata,
struct ircomm_info *info);
int ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *skb);
int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
struct sk_buff *userdata,
struct ircomm_info *info);
int ircomm_lmp_data_request(struct ircomm_cb *self, struct sk_buff *skb,
int clen);
int ircomm_lmp_control_request(struct ircomm_cb *self,
struct sk_buff *userdata);
int ircomm_lmp_data_indication(void *instance, void *sap,
struct sk_buff *skb);
void ircomm_lmp_connect_confirm(void *instance, void *sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
struct sk_buff *skb);
void ircomm_lmp_connect_indication(void *instance, void *sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
struct sk_buff *skb);
void ircomm_lmp_disconnect_indication(void *instance, void *sap,
LM_REASON reason,
struct sk_buff *skb);
#endif

View File

@@ -0,0 +1,150 @@
/*********************************************************************
*
* 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_flush(struct ircomm_tty_cb *self);
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,70 @@
/*********************************************************************
*
* 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>
#include <net/irda/ircomm_event.h>
int ircomm_open_tsap(struct ircomm_cb *self);
int ircomm_ttp_connect_request(struct ircomm_cb *self,
struct sk_buff *userdata,
struct ircomm_info *info);
int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb);
int ircomm_ttp_disconnect_request(struct ircomm_cb *self,
struct sk_buff *userdata,
struct ircomm_info *info);
int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb,
int clen);
int ircomm_ttp_control_request(struct ircomm_cb *self,
struct sk_buff *userdata);
int ircomm_ttp_data_indication(void *instance, void *sap,
struct sk_buff *skb);
void ircomm_ttp_connect_confirm(void *instance, void *sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
struct sk_buff *skb);
void ircomm_ttp_connect_indication(void *instance, void *sap,
struct qos_info *qos,
__u32 max_sdu_size,
__u8 max_header_size,
struct sk_buff *skb);
void ircomm_ttp_disconnect_indication(void *instance, void *sap,
LM_REASON reason,
struct sk_buff *skb);
void ircomm_ttp_flow_indication(void *instance, void *sap, LOCAL_FLOW cmd);
#endif

View File

@@ -0,0 +1,141 @@
/*********************************************************************
*
* 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_stop(struct tty_struct *tty);
void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self);
extern void ircomm_tty_change_speed(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 termios *old_termios);
extern hashbin_t *ircomm_tty;
#endif

View File

@@ -0,0 +1,95 @@
/*********************************************************************
*
* 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_event[];
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 */

View File

@@ -0,0 +1,114 @@
/*********************************************************************
*
* 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ø 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/config.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...) (irda_debug >= (n)) ? (printk(KERN_DEBUG args)) : 0
#define ASSERT(expr, func) \
if(!(expr)) { \
printk( "Assertion failed! %s:%s:%d %s\n", \
__FILE__,__FUNCTION__,__LINE__,(#expr)); \
func }
#else
#define IRDA_DEBUG(n, args...)
#define ASSERT(expr, func) \
if(!(expr)) do { \
func } while (0)
#endif /* CONFIG_IRDA_DEBUG */
#define WARNING(args...) printk(KERN_WARNING args)
#define MESSAGE(args...) printk(KERN_INFO args)
#define ERROR(args...) printk(KERN_ERR args)
/*
* 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
#endif /* NET_IRDA_H */

View File

@@ -0,0 +1,303 @@
/*********************************************************************
*
* 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/config.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, SA_SHIRQ|SA_INTERRUPT) */
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_len(&dev->qdisc->q) == 0);
}
int irda_device_set_raw_mode(struct net_device* self, int status);
int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts);
int irda_device_change_speed(struct net_device *dev, __u32 speed);
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);
#ifdef CONFIG_ISA
void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode);
#endif
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 */

View File

@@ -0,0 +1,118 @@
/*********************************************************************
*
* 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ø 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_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb);
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);
void iriap_watchdog_timer_expired(void *data);
static inline void iriap_start_watchdog_timer(struct iriap_cb *self,
int timeout)
{
irda_start_timer(&self->watchdog_timer, timeout, self,
iriap_watchdog_timer_expired);
}
#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ø 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ø 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,45 @@
/*********************************************************************
*
* 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ø 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_start_kick_timer(struct irlan_cb *self, int timeout);
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_open_ctrl_tsap( struct irlan_cb *self);
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,225 @@
/*********************************************************************
*
* 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ø 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
#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER)
/*
* 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;
};
struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr);
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_unicast_addr(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);
void irlan_open_unicast_addr(struct irlan_cb *self);
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ø 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ø 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,33 @@
/*********************************************************************
*
* 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ø 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);
int irlan_print_filter(struct seq_file *seq, int filter_type);
#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ø 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

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ø 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/config.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)
#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_change_speed(struct irlap_cb *self, __u32 speed, int now);
void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *);
void irlap_init_qos_capabilities(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,143 @@
/*********************************************************************
*
* 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 */
struct xid_frame {
__u8 caddr; /* Connection address */
__u8 control;
__u8 ident; /* Should always be XID_FORMAT */
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
__u8 flags; /* Discovery flags */
__u8 slotnr;
__u8 version;
} IRDA_PACK;
struct test_frame {
__u8 caddr; /* Connection address */
__u8 control;
__u32 saddr; /* Source device address */
__u32 daddr; /* Destination device address */
} IRDA_PACK;
struct ua_frame {
__u8 caddr;
__u8 control;
__u32 saddr; /* Source device address */
__u32 daddr; /* Dest device address */
} IRDA_PACK;
struct i_frame {
__u8 caddr;
__u8 control;
} IRDA_PACK;
struct snrm_frame {
__u8 caddr;
__u8 control;
__u32 saddr;
__u32 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_i_frame(struct irlap_cb *, struct sk_buff *, 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

View File

@@ -0,0 +1,298 @@
/*********************************************************************
*
* 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ø 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/config.h>
#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
#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;
IRLMP_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_request(void);
void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock);
void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow);
int irlmp_slsap_inuse(__u8 slsap);
__u8 irlmp_find_free_slsap(void);
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ø 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,63 @@
/*********************************************************************
*
* 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ø 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/config.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

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ø 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ø 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

View File

@@ -0,0 +1,213 @@
/*********************************************************************
*
* 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ø 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);
void irttp_status_indication(void *instance,
LINK_STATUS link, LOCK_STATUS lock);
void irttp_flow_indication(void *instance, void *sap, 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,104 @@
/*********************************************************************
*
* 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_unpack(__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(void *self, __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 */

View File

@@ -0,0 +1,105 @@
/*********************************************************************
*
* 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/config.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);
__u32 irlap_requested_line_capacity(struct qos_info *qos);
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

View File

@@ -0,0 +1,104 @@
/*********************************************************************
*
* 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ø 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 <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ø 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

View File

@@ -0,0 +1,543 @@
/*
* This file define the new driver API for Wireless Extensions
*
* Version : 6 21.6.04
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 2001-2004 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 6
/*
* 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
*/
/**************************** 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 - SIOCSIWNAME]
*/
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;
/* This field will be *removed* in the next version of WE */
long spy_offset; /* DO NOT USE */
/* 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.
* 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).
*/
struct iw_public_data {
/* Driver enhanced spy support */
struct iw_spy_data * spy_data;
};
/**************************** PROTOTYPES ****************************/
/*
* Functions part of the Wireless Extensions (defined in net/core/wireless.c).
* Those may be called only within the kernel.
*/
/* Data needed by fs/compat_ioctl.c for 32->64 bit conversion */
extern const char iw_priv_type_size[];
/* 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/code/dev.c */
extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
/* 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((stream + event_len) < ends) {
iwe->len = event_len;
memcpy(stream, (char *) iwe, event_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 */
char * extra)
{
int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
/* Check if it's possible */
if((stream + event_len) < ends) {
iwe->len = event_len;
memcpy(stream, (char *) iwe, IW_EV_POINT_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((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;
}
#endif /* _IW_HANDLER_H */

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

View File

@@ -0,0 +1,99 @@
#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>
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;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt);
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);
extern int llc_mac_hdr_init(struct sk_buff *skb,
unsigned char *sa, 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));
extern void llc_sap_close(struct llc_sap *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 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 */
#endif /* LLC_H */

View File

@@ -0,0 +1,221 @@
#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_report_status(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_dm_rsp_f_set_f_flag(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_cmd_p_set_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_resend_i_cmd_p_set_1(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(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_ack_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_f_flag(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_p_flag_1(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_ac_set_f_flag_p(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_inc_npta_value(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_rr_rsp_f_set_ackpf(struct sock* sk,
struct sk_buff *skb);
extern int llc_conn_ac_send_i_rsp_f_set_ackpf(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 */

View File

@@ -0,0 +1,281 @@
#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_conn_resp(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_rst_resp(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_xxx_yyy(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_any_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_cmd_pbit_set_0(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_init_p_f_cycle(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_impossible(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_received(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 */

View File

@@ -0,0 +1,48 @@
#ifndef LLC_C_ST_H
#define LLC_C_ST_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 management */
/* connection states */
#define LLC_CONN_OUT_OF_SVC 0 /* prior to allocation */
#define LLC_CONN_STATE_ADM 1 /* disc, initial state */
#define LLC_CONN_STATE_SETUP 2 /* disconnected state */
#define LLC_CONN_STATE_NORMAL 3 /* connected state */
#define LLC_CONN_STATE_BUSY 4 /* connected state */
#define LLC_CONN_STATE_REJ 5 /* connected state */
#define LLC_CONN_STATE_AWAIT 6 /* connected state */
#define LLC_CONN_STATE_AWAIT_BUSY 7 /* connected state */
#define LLC_CONN_STATE_AWAIT_REJ 8 /* connected state */
#define LLC_CONN_STATE_D_CONN 9 /* disconnected state */
#define LLC_CONN_STATE_RESET 10 /* disconnected state */
#define LLC_CONN_STATE_ERROR 11 /* disconnected state */
#define LLC_CONN_STATE_TEMP 12 /* disconnected state */
#define NBR_CONN_STATES 12 /* size of state table */
#define NO_STATE_CHANGE 100
/* Connection state table structure */
struct llc_conn_state_trans {
llc_conn_ev_t ev;
u8 next_state;
llc_conn_ev_qfyr_t *ev_qualifiers;
llc_conn_action_t *ev_actions;
};
struct llc_conn_state {
u8 current_state;
struct llc_conn_state_trans **transitions;
};
extern struct llc_conn_state llc_conn_state_table[];
#endif /* LLC_C_ST_H */

View File

@@ -0,0 +1,117 @@
#ifndef LLC_CONN_H
#define LLC_CONN_H
/*
* Copyright (c) 1997 by Procom Technology, Inc.
* 2001, 2002 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/timer.h>
#include <net/llc_if.h>
#include <linux/llc.h>
#define LLC_EVENT 1
#define LLC_PACKET 2
#define LLC_P_TIME 2
#define LLC_ACK_TIME 1
#define LLC_REJ_TIME 3
#define LLC_BUSY_TIME 3
struct llc_timer {
struct timer_list timer;
u16 expire; /* timer expire time */
};
struct llc_opt {
struct sock *sk; /* sock that has this llc_opt */
struct sockaddr_llc addr; /* address sock is bound to */
u8 state; /* state of connection */
struct llc_sap *sap; /* pointer to parent SAP */
struct llc_addr laddr; /* lsap/mac pair */
struct llc_addr daddr; /* dsap/mac pair */
struct net_device *dev; /* device to send to remote */
u8 retry_count; /* number of retries */
u8 ack_must_be_send;
u8 first_pdu_Ns;
u8 npta;
struct llc_timer ack_timer;
struct llc_timer pf_cycle_timer;
struct llc_timer rej_sent_timer;
struct llc_timer busy_state_timer; /* ind busy clr at remote LLC */
u8 vS; /* seq# next in-seq I-PDU tx'd*/
u8 vR; /* seq# next in-seq I-PDU rx'd*/
u32 n2; /* max nbr re-tx's for timeout*/
u32 n1; /* max nbr octets in I PDU */
u8 k; /* tx window size; max = 127 */
u8 rw; /* rx window size; max = 127 */
u8 p_flag; /* state flags */
u8 f_flag;
u8 s_flag;
u8 data_flag;
u8 remote_busy_flag;
u8 cause_flag;
struct sk_buff_head pdu_unack_q; /* PUDs sent/waiting ack */
u16 link; /* network layer link number */
u8 X; /* a temporary variable */
u8 ack_pf; /* this flag indicates what is
the P-bit of acknowledge */
u8 failed_data_req; /* recognize that already exist a
failed llc_data_req_handler
(tx_buffer_full or unacceptable
state */
u8 dec_step;
u8 inc_cntr;
u8 dec_cntr;
u8 connect_step;
u8 last_nr; /* NR of last pdu received */
u32 rx_pdu_hdr; /* used for saving header of last pdu
received and caused sending FRMR.
Used for resending FRMR */
};
#define llc_sk(__sk) ((struct llc_opt *)(__sk)->sk_protinfo)
static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
{
skb->cb[sizeof(skb->cb) - 1] = type;
}
static __inline__ char llc_backlog_type(struct sk_buff *skb)
{
return skb->cb[sizeof(skb->cb) - 1];
}
extern struct sock *llc_sk_alloc(int family, int priority);
extern void llc_sk_free(struct sock *sk);
extern void llc_sk_reset(struct sock *sk);
extern int llc_sk_init(struct sock *sk);
/* Access to a connection */
extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr,
u8 first_p_bit);
extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr,
u8 first_f_bit);
extern int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr,
u16 *how_many_unacked);
extern struct sock *llc_lookup_established(struct llc_sap *sap,
struct llc_addr *daddr,
struct llc_addr *laddr);
extern struct sock *llc_lookup_listener(struct llc_sap *sap,
struct llc_addr *laddr);
extern void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
extern u8 llc_data_accept_state(u8 state);
extern void llc_build_offset_table(void);
extern int llc_release_sockets(struct llc_sap *sap);
#endif /* LLC_CONN_H */

View File

@@ -0,0 +1,101 @@
#ifndef LLC_IF_H
#define LLC_IF_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.
*/
/* Defines LLC interface to network layer */
/* Available primitives */
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/llc.h>
#include <net/llc.h>
#define LLC_DATAUNIT_PRIM 1
#define LLC_CONN_PRIM 2
#define LLC_DATA_PRIM 3
#define LLC_DISC_PRIM 4
#define LLC_RESET_PRIM 5
#define LLC_FLOWCONTROL_PRIM 6 /* Not supported at this time */
#define LLC_DISABLE_PRIM 7
#define LLC_XID_PRIM 8
#define LLC_TEST_PRIM 9
#define LLC_SAP_ACTIVATION 10
#define LLC_SAP_DEACTIVATION 11
#define LLC_NBR_PRIMITIVES 11
#define LLC_IND 1
#define LLC_CONFIRM 2
/* Primitive type */
#define LLC_PRIM_TYPE_REQ 1
#define LLC_PRIM_TYPE_IND 2
#define LLC_PRIM_TYPE_RESP 3
#define LLC_PRIM_TYPE_CONFIRM 4
/* Reset reasons, remote entity or local LLC */
#define LLC_RESET_REASON_REMOTE 1
#define LLC_RESET_REASON_LOCAL 2
/* Disconnect reasons */
#define LLC_DISC_REASON_RX_DM_RSP_PDU 0
#define LLC_DISC_REASON_RX_DISC_CMD_PDU 1
#define LLC_DISC_REASON_ACK_TMR_EXP 2
/* Confirm reasons */
#define LLC_STATUS_CONN 0 /* connect confirm & reset confirm */
#define LLC_STATUS_DISC 1 /* connect confirm & reset confirm */
#define LLC_STATUS_FAILED 2 /* connect confirm & reset confirm */
#define LLC_STATUS_IMPOSSIBLE 3 /* connect confirm */
#define LLC_STATUS_RECEIVED 4 /* data conn */
#define LLC_STATUS_REMOTE_BUSY 5 /* data conn */
#define LLC_STATUS_REFUSE 6 /* data conn */
#define LLC_STATUS_CONFLICT 7 /* disconnect conn */
#define LLC_STATUS_RESET_DONE 8 /* */
extern u8 llc_mac_null_var[IFHWADDRLEN];
/**
* llc_mac_null - determines if a address is a null mac address
* @mac: Mac address to test if null.
*
* Determines if a given address is a null mac address. Returns 0 if the
* address is not a null mac, 1 if the address is a null mac.
*/
static __inline__ int llc_mac_null(u8 *mac)
{
return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN);
}
static __inline__ int llc_addrany(struct llc_addr *addr)
{
return llc_mac_null(addr->mac) && !addr->lsap;
}
/**
* llc_mac_match - determines if two mac addresses are the same
* @mac1: First mac address to compare.
* @mac2: Second mac address to compare.
*
* Determines if two given mac address are the same. Returns 0 if there
* is not a complete match up to len, 1 if a complete match up to len is
* found.
*/
static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2)
{
return !memcmp(mac1, mac2, IFHWADDRLEN);
}
extern int llc_establish_connection(struct sock *sk, u8 *lmac,
u8 *dmac, u8 dsap);
extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
extern int llc_send_disc(struct sock *sk);
#endif /* LLC_IF_H */

View File

@@ -0,0 +1,437 @@
#ifndef LLC_PDU_H
#define LLC_PDU_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_ether.h>
#include <linux/if_tr.h>
/* Lengths of frame formats */
#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */
#define LLC_PDU_LEN_S 4
#define LLC_PDU_LEN_U 3 /* header and 1 control byte */
/* Known SAP addresses */
#define LLC_GLOBAL_SAP 0xFF
#define LLC_NULL_SAP 0x00 /* not network-layer visible */
#define LLC_MGMT_INDIV 0x02 /* station LLC mgmt indiv addr */
#define LLC_MGMT_GRP 0x03 /* station LLC mgmt group addr */
#define LLC_RDE_SAP 0xA6 /* route ... */
/* SAP field bit masks */
#define LLC_ISO_RESERVED_SAP 0x02
#define LLC_SAP_GROUP_DSAP 0x01
#define LLC_SAP_RESP_SSAP 0x01
/* Group/individual DSAP indicator is DSAP field */
#define LLC_PDU_GROUP_DSAP_MASK 0x01
#define LLC_PDU_IS_GROUP_DSAP(pdu) \
((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
#define LLC_PDU_IS_INDIV_DSAP(pdu) \
(!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
/* Command/response PDU indicator in SSAP field */
#define LLC_PDU_CMD_RSP_MASK 0x01
#define LLC_PDU_CMD 0
#define LLC_PDU_RSP 1
#define LLC_PDU_IS_CMD(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
#define LLC_PDU_IS_RSP(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
/* Get PDU type from 2 lowest-order bits of control field first byte */
#define LLC_PDU_TYPE_I_MASK 0x01 /* 16-bit control field */
#define LLC_PDU_TYPE_S_MASK 0x03
#define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */
#define LLC_PDU_TYPE_MASK 0x03
#define LLC_PDU_TYPE_I 0 /* first bit */
#define LLC_PDU_TYPE_S 1 /* first two bits */
#define LLC_PDU_TYPE_U 3 /* first two bits */
#define LLC_PDU_TYPE_IS_I(pdu) \
((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0)
#define LLC_PDU_TYPE_IS_U(pdu) \
(((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 1 : 0)
#define LLC_PDU_TYPE_IS_S(pdu) \
(((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 1 : 0)
/* U-format PDU control field masks */
#define LLC_U_PF_BIT_MASK 0x10 /* P/F bit mask */
#define LLC_U_PF_IS_1(pdu) ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 1 : 0)
#define LLC_U_PF_IS_0(pdu) ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 1 : 0)
#define LLC_U_PDU_CMD_MASK 0xEC /* cmd/rsp mask */
#define LLC_U_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
#define LLC_U_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
#define LLC_1_PDU_CMD_UI 0x00 /* Type 1 cmds/rsps */
#define LLC_1_PDU_CMD_XID 0xAC
#define LLC_1_PDU_CMD_TEST 0xE0
#define LLC_2_PDU_CMD_SABME 0x6C /* Type 2 cmds/rsps */
#define LLC_2_PDU_CMD_DISC 0x40
#define LLC_2_PDU_RSP_UA 0x60
#define LLC_2_PDU_RSP_DM 0x0C
#define LLC_2_PDU_RSP_FRMR 0x84
/* Type 1 operations */
/* XID information field bit masks */
/* LLC format identifier (byte 1) */
#define LLC_XID_FMT_ID 0x81 /* first byte must be this */
/* LLC types/classes identifier (byte 2) */
#define LLC_XID_CLASS_ZEROS_MASK 0xE0 /* these must be zeros */
#define LLC_XID_CLASS_MASK 0x1F /* AND with byte to get below */
#define LLC_XID_NULL_CLASS_1 0x01 /* if NULL LSAP...use these */
#define LLC_XID_NULL_CLASS_2 0x03
#define LLC_XID_NULL_CLASS_3 0x05
#define LLC_XID_NULL_CLASS_4 0x07
#define LLC_XID_NNULL_TYPE_1 0x01 /* if non-NULL LSAP...use these */
#define LLC_XID_NNULL_TYPE_2 0x02
#define LLC_XID_NNULL_TYPE_3 0x04
#define LLC_XID_NNULL_TYPE_1_2 0x03
#define LLC_XID_NNULL_TYPE_1_3 0x05
#define LLC_XID_NNULL_TYPE_2_3 0x06
#define LLC_XID_NNULL_ALL 0x07
/* Sender Receive Window (byte 3) */
#define LLC_XID_RW_MASK 0xFE /* AND with value to get below */
#define LLC_XID_MIN_RW 0x02 /* lowest-order bit always zero */
/* Type 2 operations */
#define LLC_2_SEQ_NBR_MODULO ((u8) 128)
/* I-PDU masks ('ctrl' is I-PDU control word) */
#define LLC_I_GET_NS(pdu) (u8)((pdu->ctrl_1 & 0xFE) >> 1)
#define LLC_I_GET_NR(pdu) (u8)((pdu->ctrl_2 & 0xFE) >> 1)
#define LLC_I_PF_BIT_MASK 0x01
#define LLC_I_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 1 : 0)
#define LLC_I_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 1 : 0)
/* S-PDU supervisory commands and responses */
#define LLC_S_PDU_CMD_MASK 0x0C
#define LLC_S_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
#define LLC_S_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
#define LLC_2_PDU_CMD_RR 0x00 /* rx ready cmd */
#define LLC_2_PDU_RSP_RR 0x00 /* rx ready rsp */
#define LLC_2_PDU_CMD_REJ 0x08 /* reject PDU cmd */
#define LLC_2_PDU_RSP_REJ 0x08 /* reject PDU rsp */
#define LLC_2_PDU_CMD_RNR 0x04 /* rx not ready cmd */
#define LLC_2_PDU_RSP_RNR 0x04 /* rx not ready rsp */
#define LLC_S_PF_BIT_MASK 0x01
#define LLC_S_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 1 : 0)
#define LLC_S_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 1 : 0)
#define PDU_SUPV_GET_Nr(pdu) ((pdu->ctrl_2 & 0xFE) >> 1)
#define PDU_GET_NEXT_Vr(sn) (++sn & ~LLC_2_SEQ_NBR_MODULO)
/* FRMR information field macros */
#define FRMR_INFO_LENGTH 5 /* 5 bytes of information */
/*
* info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer
* (if U-PDU) or word pointer to rejected PDU control field
*/
#define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \
info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \
LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \
(u16)*((u16 *) rej_ctrl) : \
(((u16) *((u8 *) rej_ctrl)) & 0x00FF))
/*
* Info is pointer to FRMR info field structure; 'vs' is a byte containing
* send state variable value in low-order 7 bits (insure the lowest-order
* bit remains zero (0))
*/
#define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1))
#define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1))
/*
* Info is pointer to FRMR info field structure; 'cr' is a byte containing
* the C/R bit value in the low-order bit
*/
#define FRMR_INFO_SET_C_R_BIT(info, cr) (info->curr_rsv |= (((u8) cr) & 0x01))
/*
* In the remaining five macros, 'info' is pointer to FRMR info field
* structure; 'ind' is a byte containing the bit value to set in the
* lowest-order bit)
*/
#define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \
(info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01)))
#define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \
(info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02)))
#define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \
(info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04)))
#define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \
(info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08)))
#define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \
(info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10)))
/* Sequence-numbered PDU format (4 bytes in length) */
struct llc_pdu_sn {
u8 dsap;
u8 ssap;
u8 ctrl_1;
u8 ctrl_2;
};
static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
{
return (struct llc_pdu_sn *)skb->nh.raw;
}
/* Un-numbered PDU format (3 bytes in length) */
struct llc_pdu_un {
u8 dsap;
u8 ssap;
u8 ctrl_1;
};
static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
{
return (struct llc_pdu_un *)skb->nh.raw;
}
static inline void *llc_set_pdu_hdr(struct sk_buff *skb, void *ptr)
{
return skb->nh.raw = ptr;
}
/**
* llc_pdu_header_init - initializes pdu header
* @skb: input skb that header must be set into it.
* @type: type of PDU (U, I or S).
* @ssap: source sap.
* @dsap: destination sap.
* @cr: command/response bit (0 or 1).
*
* This function sets DSAP, SSAP and command/Response bit in LLC header.
*/
static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
u8 ssap, u8 dsap, u8 cr)
{
const int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
struct llc_pdu_un *pdu = llc_set_pdu_hdr(skb, skb_push(skb, hlen));
pdu->dsap = dsap;
pdu->ssap = ssap;
pdu->ssap |= cr;
}
/**
* llc_pdu_decode_sa - extracs source address (MAC) of input frame
* @skb: input skb that source address must be extracted from it.
* @sa: pointer to source address (6 byte array).
*
* This function extracts source address(MAC) of input frame.
*/
static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
{
if (skb->protocol == ntohs(ETH_P_802_2))
memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN);
else if (skb->protocol == ntohs(ETH_P_TR_802_2))
memcpy(sa, tr_hdr(skb)->saddr, ETH_ALEN);
}
/**
* llc_pdu_decode_da - extracts dest address of input frame
* @skb: input skb that destination address must be extracted from it
* @sa: pointer to destination address (6 byte array).
*
* This function extracts destination address(MAC) of input frame.
*/
static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
{
if (skb->protocol == ntohs(ETH_P_802_2))
memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN);
else if (skb->protocol == ntohs(ETH_P_TR_802_2))
memcpy(da, tr_hdr(skb)->daddr, ETH_ALEN);
}
/**
* llc_pdu_decode_ssap - extracts source SAP of input frame
* @skb: input skb that source SAP must be extracted from it.
* @ssap: source SAP (output argument).
*
* This function extracts source SAP of input frame. Right bit of SSAP is
* command/response bit.
*/
static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
{
*ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
}
/**
* llc_pdu_decode_dsap - extracts dest SAP of input frame
* @skb: input skb that destination SAP must be extracted from it.
* @dsap: destination SAP (output argument).
*
* This function extracts destination SAP of input frame. right bit of
* DSAP designates individual/group SAP.
*/
static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
{
*dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
}
/**
* llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
* @skb: input skb that header must be set into it.
*
* This function sets third byte of LLC header as a UI PDU.
*/
static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
pdu->ctrl_1 = LLC_PDU_TYPE_U;
pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
}
/**
* llc_pdu_init_as_test_cmd - sets PDU as TEST
* @skb - Address of the skb to build
*
* Sets a PDU as TEST
*/
static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
pdu->ctrl_1 = LLC_PDU_TYPE_U;
pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
}
/**
* llc_pdu_init_as_test_rsp - build TEST response PDU
* @skb: Address of the skb to build
* @ev_skb: The received TEST command PDU frame
*
* Builds a pdu frame as a TEST response.
*/
static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
struct sk_buff *ev_skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
pdu->ctrl_1 = LLC_PDU_TYPE_U;
pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
if (ev_skb->protocol == ntohs(ETH_P_802_2)) {
struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
int dsize;
dsize = ntohs(eth_hdr(ev_skb)->h_proto) - 3;
memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
skb_put(skb, dsize);
}
}
/* LLC Type 1 XID command/response information fields format */
struct llc_xid_info {
u8 fmt_id; /* always 0x18 for LLC */
u8 type; /* different if NULL/non-NULL LSAP */
u8 rw; /* sender receive window */
};
/**
* llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
* @skb: input skb that header must be set into it.
*
* This function sets third,fourth,fifth and sixth bytes of LLC header as
* a XID PDU.
*/
static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
u8 svcs_supported, u8 rx_window)
{
struct llc_xid_info *xid_info;
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
pdu->ctrl_1 = LLC_PDU_TYPE_U;
pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
xid_info->type = svcs_supported;
xid_info->rw = rx_window << 1; /* size of receive window */
skb_put(skb, 3);
}
/**
* llc_pdu_init_as_xid_rsp - builds XID response PDU
* @skb: Address of the skb to build
* @svcs_supported: The class of the LLC (I or II)
* @rx_window: The size of the receive window of the LLC
*
* Builds a pdu frame as an XID response.
*/
static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
u8 svcs_supported, u8 rx_window)
{
struct llc_xid_info *xid_info;
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
pdu->ctrl_1 = LLC_PDU_TYPE_U;
pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
xid_info->fmt_id = LLC_XID_FMT_ID;
xid_info->type = svcs_supported;
xid_info->rw = rx_window << 1;
skb_put(skb, 3);
}
/* LLC Type 2 FRMR response information field format */
struct llc_frmr_info {
u16 rej_pdu_ctrl; /* bits 1-8 if U-PDU */
u8 curr_ssv; /* current send state variable val */
u8 curr_rsv; /* current receive state variable */
u8 ind_bits; /* indicator bits set with macro */
};
extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
extern void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
extern void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit);
extern void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
extern void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
extern void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
extern void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
extern void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
extern void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
extern void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
extern void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb,
struct llc_pdu_sn *prev_pdu,
u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
extern void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
extern void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
extern void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
extern void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit);
#endif /* LLC_PDU_H */

View File

@@ -0,0 +1,39 @@
#ifndef LLC_S_AC_H
#define LLC_S_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.
*/
/* SAP component actions */
#define SAP_ACT_UNITDATA_IND 1
#define SAP_ACT_SEND_UI 2
#define SAP_ACT_SEND_XID_C 3
#define SAP_ACT_SEND_XID_R 4
#define SAP_ACT_SEND_TEST_C 5
#define SAP_ACT_SEND_TEST_R 6
#define SAP_ACT_REPORT_STATUS 7
#define SAP_ACT_XID_IND 8
#define SAP_ACT_TEST_IND 9
/* All action functions must look like this */
typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_unitdata_ind(struct llc_sap *sap,
struct sk_buff *skb);
extern int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_report_status(struct llc_sap *sap,
struct sk_buff *skb);
extern int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb);
#endif /* LLC_S_AC_H */

View File

@@ -0,0 +1,67 @@
#ifndef LLC_S_EV_H
#define LLC_S_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 <linux/skbuff.h>
/* Defines SAP component events */
/* Types of events (possible values in 'ev->type') */
#define LLC_SAP_EV_TYPE_SIMPLE 1
#define LLC_SAP_EV_TYPE_CONDITION 2
#define LLC_SAP_EV_TYPE_PRIM 3
#define LLC_SAP_EV_TYPE_PDU 4 /* command/response PDU */
#define LLC_SAP_EV_TYPE_ACK_TMR 5
#define LLC_SAP_EV_TYPE_RPT_STATUS 6
#define LLC_SAP_EV_ACTIVATION_REQ 1
#define LLC_SAP_EV_RX_UI 2
#define LLC_SAP_EV_UNITDATA_REQ 3
#define LLC_SAP_EV_XID_REQ 4
#define LLC_SAP_EV_RX_XID_C 5
#define LLC_SAP_EV_RX_XID_R 6
#define LLC_SAP_EV_TEST_REQ 7
#define LLC_SAP_EV_RX_TEST_C 8
#define LLC_SAP_EV_RX_TEST_R 9
#define LLC_SAP_EV_DEACTIVATION_REQ 10
struct llc_sap_state_ev {
u8 prim;
u8 prim_type;
u8 type;
u8 reason;
u8 ind_cfm_flag;
struct llc_addr saddr;
struct llc_addr daddr;
};
static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb)
{
return (struct llc_sap_state_ev *)skb->cb;
}
struct llc_sap;
typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_deactivation_req(struct llc_sap *sap,
struct sk_buff *skb);
#endif /* LLC_S_EV_H */

View File

@@ -0,0 +1,32 @@
#ifndef LLC_S_ST_H
#define LLC_S_ST_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.
*/
#define LLC_NR_SAP_STATES 2 /* size of state table */
/* structures and types */
/* SAP state table structure */
struct llc_sap_state_trans {
llc_sap_ev_t ev;
u8 next_state;
llc_sap_action_t *ev_actions;
};
struct llc_sap_state {
u8 curr_state;
struct llc_sap_state_trans **transitions;
};
/* only access to SAP state table */
extern struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES];
#endif /* LLC_S_ST_H */

View File

@@ -0,0 +1,30 @@
#ifndef LLC_SAP_H
#define LLC_SAP_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.
*/
struct llc_sap;
struct sk_buff;
extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
extern struct sk_buff *llc_alloc_frame(void);
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
struct sk_buff *skb,
unsigned char *dmac,
unsigned char dsap);
extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
struct sk_buff *skb,
unsigned char *dmac,
unsigned char dsap);
#endif /* LLC_SAP_H */

View File

@@ -0,0 +1,131 @@
#ifndef _NDISC_H
#define _NDISC_H
/*
* ICMP codes for neighbour discovery messages
*/
#define NDISC_ROUTER_SOLICITATION 133
#define NDISC_ROUTER_ADVERTISEMENT 134
#define NDISC_NEIGHBOUR_SOLICITATION 135
#define NDISC_NEIGHBOUR_ADVERTISEMENT 136
#define NDISC_REDIRECT 137
/*
* ndisc options
*/
#define ND_OPT_SOURCE_LL_ADDR 1
#define ND_OPT_TARGET_LL_ADDR 2
#define ND_OPT_PREFIX_INFO 3
#define ND_OPT_REDIRECT_HDR 4
#define ND_OPT_MTU 5
#define MAX_RTR_SOLICITATION_DELAY HZ
#define ND_REACHABLE_TIME (30*HZ)
#define ND_RETRANS_TIMER HZ
#define ND_MIN_RANDOM_FACTOR (1/2)
#define ND_MAX_RANDOM_FACTOR (3/2)
#ifdef __KERNEL__
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/icmpv6.h>
#include <net/neighbour.h>
#include <asm/atomic.h>
extern struct neigh_table nd_tbl;
struct nd_msg {
struct icmp6hdr icmph;
struct in6_addr target;
__u8 opt[0];
};
struct rs_msg {
struct icmp6hdr icmph;
__u8 opt[0];
};
struct ra_msg {
struct icmp6hdr icmph;
__u32 reachable_time;
__u32 retrans_timer;
};
struct nd_opt_hdr {
__u8 nd_opt_type;
__u8 nd_opt_len;
} __attribute__((__packed__));
extern int ndisc_init(struct net_proto_family *ops);
extern void ndisc_cleanup(void);
extern int ndisc_rcv(struct sk_buff *skb);
extern void ndisc_send_ns(struct net_device *dev,
struct neighbour *neigh,
struct in6_addr *solicit,
struct in6_addr *daddr,
struct in6_addr *saddr);
extern void ndisc_send_rs(struct net_device *dev,
struct in6_addr *saddr,
struct in6_addr *daddr);
extern void ndisc_forwarding_on(void);
extern void ndisc_forwarding_off(void);
extern void ndisc_send_redirect(struct sk_buff *skb,
struct neighbour *neigh,
struct in6_addr *target);
extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir);
struct rt6_info * dflt_rt_lookup(void);
/*
* IGMP
*/
extern int igmp6_init(struct net_proto_family *ops);
extern void igmp6_cleanup(void);
extern int igmp6_event_query(struct sk_buff *skb);
extern int igmp6_event_report(struct sk_buff *skb);
extern void igmp6_cleanup(void);
#ifdef CONFIG_SYSCTL
extern int ndisc_ifinfo_sysctl_change(ctl_table *ctl,
int write,
struct file * filp,
void __user *buffer,
size_t *lenp,
loff_t *ppos);
#endif
extern void inet6_ifinfo_notify(int event,
struct inet6_dev *idev);
static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr)
{
if (dev)
return __neigh_lookup(&nd_tbl, addr, dev, 1);
return NULL;
}
#endif /* __KERNEL__ */
#endif

View File

@@ -0,0 +1,369 @@
#ifndef _NET_NEIGHBOUR_H
#define _NET_NEIGHBOUR_H
/*
* Generic neighbour manipulation
*
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
* Changes:
*
* Harald Welte: <laforge@gnumonks.org>
* - Add neighbour cache statistics like rtstat
*/
/* The following flags & states are exported to user space,
so that they should be moved to include/linux/ directory.
*/
/*
* Neighbor Cache Entry Flags
*/
#define NTF_PROXY 0x08 /* == ATF_PUBL */
#define NTF_ROUTER 0x80
/*
* Neighbor Cache Entry States.
*/
#define NUD_INCOMPLETE 0x01
#define NUD_REACHABLE 0x02
#define NUD_STALE 0x04
#define NUD_DELAY 0x08
#define NUD_PROBE 0x10
#define NUD_FAILED 0x20
/* Dummy states */
#define NUD_NOARP 0x40
#define NUD_PERMANENT 0x80
#define NUD_NONE 0x00
/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change
and make no address resolution or NUD.
NUD_PERMANENT is also cannot be deleted by garbage collectors.
*/
#ifdef __KERNEL__
#include <asm/atomic.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/sysctl.h>
#define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
#define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
#define NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
struct neighbour;
struct neigh_parms
{
struct neigh_parms *next;
int (*neigh_setup)(struct neighbour *);
struct neigh_table *tbl;
int entries;
void *priv;
void *sysctl_table;
int dead;
atomic_t refcnt;
struct rcu_head rcu_head;
int base_reachable_time;
int retrans_time;
int gc_staletime;
int reachable_time;
int delay_probe_time;
int queue_len;
int ucast_probes;
int app_probes;
int mcast_probes;
int anycast_delay;
int proxy_delay;
int proxy_qlen;
int locktime;
};
struct neigh_statistics
{
unsigned long allocs; /* number of allocated neighs */
unsigned long destroys; /* number of destroyed neighs */
unsigned long hash_grows; /* number of hash resizes */
unsigned long res_failed; /* nomber of failed resolutions */
unsigned long lookups; /* number of lookups */
unsigned long hits; /* number of hits (among lookups) */
unsigned long rcv_probes_mcast; /* number of received mcast ipv6 */
unsigned long rcv_probes_ucast; /* number of received ucast ipv6 */
unsigned long periodic_gc_runs; /* number of periodic GC runs */
unsigned long forced_gc_runs; /* number of forced GC runs */
};
#define NEIGH_CACHE_STAT_INC(tbl, field) \
do { \
preempt_disable(); \
(per_cpu_ptr((tbl)->stats, smp_processor_id())->field)++; \
preempt_enable(); \
} while (0)
struct neighbour
{
struct neighbour *next;
struct neigh_table *tbl;
struct neigh_parms *parms;
struct net_device *dev;
unsigned long used;
unsigned long confirmed;
unsigned long updated;
__u8 flags;
__u8 nud_state;
__u8 type;
__u8 dead;
atomic_t probes;
rwlock_t lock;
unsigned char ha[(MAX_ADDR_LEN+sizeof(unsigned long)-1)&~(sizeof(unsigned long)-1)];
struct hh_cache *hh;
atomic_t refcnt;
int (*output)(struct sk_buff *skb);
struct sk_buff_head arp_queue;
struct timer_list timer;
struct neigh_ops *ops;
u8 primary_key[0];
};
struct neigh_ops
{
int family;
void (*destructor)(struct neighbour *);
void (*solicit)(struct neighbour *, struct sk_buff*);
void (*error_report)(struct neighbour *, struct sk_buff*);
int (*output)(struct sk_buff*);
int (*connected_output)(struct sk_buff*);
int (*hh_output)(struct sk_buff*);
int (*queue_xmit)(struct sk_buff*);
};
struct pneigh_entry
{
struct pneigh_entry *next;
struct net_device *dev;
u8 key[0];
};
/*
* neighbour table manipulation
*/
struct neigh_table
{
struct neigh_table *next;
int family;
int entry_size;
int key_len;
__u32 (*hash)(const void *pkey, const struct net_device *);
int (*constructor)(struct neighbour *);
int (*pconstructor)(struct pneigh_entry *);
void (*pdestructor)(struct pneigh_entry *);
void (*proxy_redo)(struct sk_buff *skb);
char *id;
struct neigh_parms parms;
/* HACK. gc_* shoul follow parms without a gap! */
int gc_interval;
int gc_thresh1;
int gc_thresh2;
int gc_thresh3;
unsigned long last_flush;
struct timer_list gc_timer;
struct timer_list proxy_timer;
struct sk_buff_head proxy_queue;
atomic_t entries;
rwlock_t lock;
unsigned long last_rand;
struct neigh_parms *parms_list;
kmem_cache_t *kmem_cachep;
struct neigh_statistics *stats;
struct neighbour **hash_buckets;
unsigned int hash_mask;
__u32 hash_rnd;
unsigned int hash_chain_gc;
struct pneigh_entry **phash_buckets;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *pde;
#endif
};
/* flags for neigh_update() */
#define NEIGH_UPDATE_F_OVERRIDE 0x00000001
#define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002
#define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004
#define NEIGH_UPDATE_F_ISROUTER 0x40000000
#define NEIGH_UPDATE_F_ADMIN 0x80000000
extern void neigh_table_init(struct neigh_table *tbl);
extern int neigh_table_clear(struct neigh_table *tbl);
extern struct neighbour * neigh_lookup(struct neigh_table *tbl,
const void *pkey,
struct net_device *dev);
extern struct neighbour * neigh_lookup_nodev(struct neigh_table *tbl,
const void *pkey);
extern struct neighbour * neigh_create(struct neigh_table *tbl,
const void *pkey,
struct net_device *dev);
extern void neigh_destroy(struct neighbour *neigh);
extern int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
extern int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
u32 flags);
extern void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
extern int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
extern int neigh_resolve_output(struct sk_buff *skb);
extern int neigh_connected_output(struct sk_buff *skb);
extern int neigh_compat_output(struct sk_buff *skb);
extern struct neighbour *neigh_event_ns(struct neigh_table *tbl,
u8 *lladdr, void *saddr,
struct net_device *dev);
extern struct neigh_parms *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
extern void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
extern void neigh_parms_destroy(struct neigh_parms *parms);
extern unsigned long neigh_rand_reach_time(unsigned long base);
extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
struct sk_buff *skb);
extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat);
extern int pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev);
struct netlink_callback;
struct nlmsghdr;
extern int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb);
extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern void neigh_app_ns(struct neighbour *n);
extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
struct neigh_seq_state {
struct neigh_table *tbl;
void *(*neigh_sub_iter)(struct neigh_seq_state *state,
struct neighbour *n, loff_t *pos);
unsigned int bucket;
unsigned int flags;
#define NEIGH_SEQ_NEIGH_ONLY 0x00000001
#define NEIGH_SEQ_IS_PNEIGH 0x00000002
#define NEIGH_SEQ_SKIP_NOARP 0x00000004
};
extern void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *, unsigned int);
extern void *neigh_seq_next(struct seq_file *, void *, loff_t *);
extern void neigh_seq_stop(struct seq_file *, void *);
extern int neigh_sysctl_register(struct net_device *dev,
struct neigh_parms *p,
int p_id, int pdev_id,
char *p_name,
proc_handler *proc_handler);
extern void neigh_sysctl_unregister(struct neigh_parms *p);
static inline void __neigh_parms_put(struct neigh_parms *parms)
{
atomic_dec(&parms->refcnt);
}
static inline void neigh_parms_put(struct neigh_parms *parms)
{
if (atomic_dec_and_test(&parms->refcnt))
neigh_parms_destroy(parms);
}
static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
{
atomic_inc(&parms->refcnt);
return parms;
}
/*
* Neighbour references
*/
static inline void neigh_release(struct neighbour *neigh)
{
if (atomic_dec_and_test(&neigh->refcnt))
neigh_destroy(neigh);
}
static inline struct neighbour * neigh_clone(struct neighbour *neigh)
{
if (neigh)
atomic_inc(&neigh->refcnt);
return neigh;
}
#define neigh_hold(n) atomic_inc(&(n)->refcnt)
static inline void neigh_confirm(struct neighbour *neigh)
{
if (neigh)
neigh->confirmed = jiffies;
}
static inline int neigh_is_connected(struct neighbour *neigh)
{
return neigh->nud_state&NUD_CONNECTED;
}
static inline int neigh_is_valid(struct neighbour *neigh)
{
return neigh->nud_state&NUD_VALID;
}
static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
{
neigh->used = jiffies;
if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
return __neigh_event_send(neigh, skb);
return 0;
}
static inline struct neighbour *
__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
{
struct neighbour *n = neigh_lookup(tbl, pkey, dev);
if (n || !creat)
return n;
n = neigh_create(tbl, pkey, dev);
return IS_ERR(n) ? NULL : n;
}
static inline struct neighbour *
__neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
struct net_device *dev)
{
struct neighbour *n = neigh_lookup(tbl, pkey, dev);
if (n)
return n;
return neigh_create(tbl, pkey, dev);
}
#define LOCALLY_ENQUEUED -2
#endif
#endif

View File

@@ -0,0 +1,240 @@
/*
* Declarations of NET/ROM type objects.
*
* Jonathan Naylor G4KLX 9/4/95
*/
#ifndef _NETROM_H
#define _NETROM_H
#include <linux/netrom.h>
#include <linux/list.h>
#define NR_NETWORK_LEN 15
#define NR_TRANSPORT_LEN 5
#define NR_PROTO_IP 0x0C
#define NR_PROTOEXT 0x00
#define NR_CONNREQ 0x01
#define NR_CONNACK 0x02
#define NR_DISCREQ 0x03
#define NR_DISCACK 0x04
#define NR_INFO 0x05
#define NR_INFOACK 0x06
#define NR_CHOKE_FLAG 0x80
#define NR_NAK_FLAG 0x40
#define NR_MORE_FLAG 0x20
/* Define Link State constants. */
enum {
NR_STATE_0,
NR_STATE_1,
NR_STATE_2,
NR_STATE_3
};
#define NR_COND_ACK_PENDING 0x01
#define NR_COND_REJECT 0x02
#define NR_COND_PEER_RX_BUSY 0x04
#define NR_COND_OWN_RX_BUSY 0x08
#define NR_DEFAULT_T1 (120 * HZ) /* Outstanding frames - 120 seconds */
#define NR_DEFAULT_T2 (5 * HZ) /* Response delay - 5 seconds */
#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */
#define NR_DEFAULT_T4 (180 * HZ) /* Busy Delay - 180 seconds */
#define NR_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */
#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */
#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */
#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */
#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */
#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */
#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */
#define NR_MODULUS 256
#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */
#define NR_MAX_PACKET_SIZE 236 /* Maximum Packet Length - 236 */
typedef struct {
ax25_address user_addr, source_addr, dest_addr;
struct net_device *device;
unsigned char my_index, my_id;
unsigned char your_index, your_id;
unsigned char state, condition, bpqext, window;
unsigned short vs, vr, va, vl;
unsigned char n2, n2count;
unsigned long t1, t2, t4, idle;
unsigned short fraglen;
struct timer_list t1timer;
struct timer_list t2timer;
struct timer_list t4timer;
struct timer_list idletimer;
struct sk_buff_head ack_queue;
struct sk_buff_head reseq_queue;
struct sk_buff_head frag_queue;
struct sock *sk; /* Backlink to socket */
} nr_cb;
#define nr_sk(__sk) ((nr_cb *)(__sk)->sk_protinfo)
struct nr_neigh {
struct hlist_node neigh_node;
ax25_address callsign;
ax25_digi *digipeat;
ax25_cb *ax25;
struct net_device *dev;
unsigned char quality;
unsigned char locked;
unsigned short count;
unsigned int number;
unsigned char failed;
atomic_t refcount;
};
struct nr_route {
unsigned char quality;
unsigned char obs_count;
struct nr_neigh *neighbour;
};
struct nr_node {
struct hlist_node node_node;
ax25_address callsign;
char mnemonic[7];
unsigned char which;
unsigned char count;
struct nr_route routes[3];
atomic_t refcount;
spinlock_t node_lock;
};
/*********************************************************************
* nr_node & nr_neigh lists, refcounting and locking
*********************************************************************/
#define nr_node_hold(__nr_node) \
atomic_inc(&((__nr_node)->refcount))
static __inline__ void nr_node_put(struct nr_node *nr_node)
{
if (atomic_dec_and_test(&nr_node->refcount)) {
kfree(nr_node);
}
}
#define nr_neigh_hold(__nr_neigh) \
atomic_inc(&((__nr_neigh)->refcount))
static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
{
if (atomic_dec_and_test(&nr_neigh->refcount)) {
if (nr_neigh->digipeat != NULL)
kfree(nr_neigh->digipeat);
kfree(nr_neigh);
}
}
/* nr_node_lock and nr_node_unlock also hold/put the node's refcounter.
*/
static __inline__ void nr_node_lock(struct nr_node *nr_node)
{
nr_node_hold(nr_node);
spin_lock_bh(&nr_node->node_lock);
}
static __inline__ void nr_node_unlock(struct nr_node *nr_node)
{
spin_unlock_bh(&nr_node->node_lock);
nr_node_put(nr_node);
}
#define nr_neigh_for_each(__nr_neigh, node, list) \
hlist_for_each_entry(__nr_neigh, node, list, neigh_node)
#define nr_neigh_for_each_safe(__nr_neigh, node, node2, list) \
hlist_for_each_entry_safe(__nr_neigh, node, node2, list, neigh_node)
#define nr_node_for_each(__nr_node, node, list) \
hlist_for_each_entry(__nr_node, node, list, node_node)
#define nr_node_for_each_safe(__nr_node, node, node2, list) \
hlist_for_each_entry_safe(__nr_node, node, node2, list, node_node)
/*********************************************************************/
/* af_netrom.c */
extern int sysctl_netrom_default_path_quality;
extern int sysctl_netrom_obsolescence_count_initialiser;
extern int sysctl_netrom_network_ttl_initialiser;
extern int sysctl_netrom_transport_timeout;
extern int sysctl_netrom_transport_maximum_tries;
extern int sysctl_netrom_transport_acknowledge_delay;
extern int sysctl_netrom_transport_busy_delay;
extern int sysctl_netrom_transport_requested_window_size;
extern int sysctl_netrom_transport_no_activity_timeout;
extern int sysctl_netrom_routing_control;
extern int sysctl_netrom_link_fails_count;
extern int nr_rx_frame(struct sk_buff *, struct net_device *);
extern void nr_destroy_socket(struct sock *);
/* nr_dev.c */
extern int nr_rx_ip(struct sk_buff *, struct net_device *);
extern void nr_setup(struct net_device *);
/* nr_in.c */
extern int nr_process_rx_frame(struct sock *, struct sk_buff *);
/* nr_loopback.c */
extern void nr_loopback_init(void);
extern void nr_loopback_clear(void);
extern int nr_loopback_queue(struct sk_buff *);
/* nr_out.c */
extern void nr_output(struct sock *, struct sk_buff *);
extern void nr_send_nak_frame(struct sock *);
extern void nr_kick(struct sock *);
extern void nr_transmit_buffer(struct sock *, struct sk_buff *);
extern void nr_establish_data_link(struct sock *);
extern void nr_enquiry_response(struct sock *);
extern void nr_check_iframes_acked(struct sock *, unsigned short);
/* nr_route.c */
extern void nr_rt_device_down(struct net_device *);
extern struct net_device *nr_dev_first(void);
extern struct net_device *nr_dev_get(ax25_address *);
extern int nr_rt_ioctl(unsigned int, void __user *);
extern void nr_link_failed(ax25_cb *, int);
extern int nr_route_frame(struct sk_buff *, ax25_cb *);
extern struct file_operations nr_nodes_fops;
extern struct file_operations nr_neigh_fops;
extern void nr_rt_free(void);
/* nr_subr.c */
extern void nr_clear_queues(struct sock *);
extern void nr_frames_acked(struct sock *, unsigned short);
extern void nr_requeue_frames(struct sock *);
extern int nr_validate_nr(struct sock *, unsigned short);
extern int nr_in_rx_window(struct sock *, unsigned short);
extern void nr_write_internal(struct sock *, int);
extern void nr_transmit_refusal(struct sk_buff *, int);
extern void nr_disconnect(struct sock *, int);
/* nr_timer.c */
extern void nr_start_heartbeat(struct sock *);
extern void nr_start_t1timer(struct sock *);
extern void nr_start_t2timer(struct sock *);
extern void nr_start_t4timer(struct sock *);
extern void nr_start_idletimer(struct sock *);
extern void nr_stop_heartbeat(struct sock *);
extern void nr_stop_t1timer(struct sock *);
extern void nr_stop_t2timer(struct sock *);
extern void nr_stop_t4timer(struct sock *);
extern void nr_stop_idletimer(struct sock *);
extern int nr_t1timer_running(struct sock *);
/* sysctl_net_netrom.c */
extern void nr_register_sysctl(void);
extern void nr_unregister_sysctl(void);
#endif

View File

@@ -0,0 +1,10 @@
#ifndef _NET_P8022_H
#define _NET_P8022_H
extern struct datalink_proto *
register_8022_client(unsigned char type,
int (*func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt));
extern void unregister_8022_client(struct datalink_proto *proto);
#endif

View File

@@ -0,0 +1,284 @@
#ifndef __NET_PKT_ACT_H
#define __NET_PKT_ACT_H
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/bitops.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
#define tca_st(val) (struct tcf_##val *)
#define PRIV(a,name) ( tca_st(name) (a)->priv)
#if 0 /* control */
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else
#define DPRINTK(format,args...)
#endif
#if 0 /* data */
#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else
#define D2PRINTK(format,args...)
#endif
static __inline__ unsigned
tcf_hash(u32 index)
{
return index & MY_TAB_MASK;
}
/* probably move this from being inline
* and put into act_generic
*/
static inline void
tcf_hash_destroy(struct tcf_st *p)
{
unsigned h = tcf_hash(p->index);
struct tcf_st **p1p;
for (p1p = &tcf_ht[h]; *p1p; p1p = &(*p1p)->next) {
if (*p1p == p) {
write_lock_bh(&tcf_t_lock);
*p1p = p->next;
write_unlock_bh(&tcf_t_lock);
#ifdef CONFIG_NET_ESTIMATOR
gen_kill_estimator(&p->bstats, &p->rate_est);
#endif
kfree(p);
return;
}
}
BUG_TRAP(0);
}
static inline int
tcf_hash_release(struct tcf_st *p, int bind )
{
int ret = 0;
if (p) {
if (bind) {
p->bindcnt--;
}
p->refcnt--;
if(p->bindcnt <=0 && p->refcnt <= 0) {
tcf_hash_destroy(p);
ret = 1;
}
}
return ret;
}
static __inline__ int
tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
struct tc_action *a)
{
struct tcf_st *p;
int err =0, index = -1,i= 0, s_i = 0, n_i = 0;
struct rtattr *r ;
read_lock(&tcf_t_lock);
s_i = cb->args[0];
for (i = 0; i < MY_TAB_SIZE; i++) {
p = tcf_ht[tcf_hash(i)];
for (; p; p = p->next) {
index++;
if (index < s_i)
continue;
a->priv = p;
a->order = n_i;
r = (struct rtattr*) skb->tail;
RTA_PUT(skb, a->order, 0, NULL);
err = tcf_action_dump_1(skb, a, 0, 0);
if (0 > err) {
index--;
skb_trim(skb, (u8*)r - skb->data);
goto done;
}
r->rta_len = skb->tail - (u8*)r;
n_i++;
if (n_i >= TCA_ACT_MAX_PRIO) {
goto done;
}
}
}
done:
read_unlock(&tcf_t_lock);
if (n_i)
cb->args[0] += n_i;
return n_i;
rtattr_failure:
skb_trim(skb, (u8*)r - skb->data);
goto done;
}
static __inline__ int
tcf_del_walker(struct sk_buff *skb, struct tc_action *a)
{
struct tcf_st *p, *s_p;
struct rtattr *r ;
int i= 0, n_i = 0;
r = (struct rtattr*) skb->tail;
RTA_PUT(skb, a->order, 0, NULL);
RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
for (i = 0; i < MY_TAB_SIZE; i++) {
p = tcf_ht[tcf_hash(i)];
while (p != NULL) {
s_p = p->next;
if (ACT_P_DELETED == tcf_hash_release(p, 0)) {
module_put(a->ops->owner);
}
n_i++;
p = s_p;
}
}
RTA_PUT(skb, TCA_FCNT, 4, &n_i);
r->rta_len = skb->tail - (u8*)r;
return n_i;
rtattr_failure:
skb_trim(skb, (u8*)r - skb->data);
return -EINVAL;
}
static __inline__ int
tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type,
struct tc_action *a)
{
if (type == RTM_DELACTION) {
return tcf_del_walker(skb,a);
} else if (type == RTM_GETACTION) {
return tcf_dump_walker(skb,cb,a);
} else {
printk("tcf_generic_walker: unknown action %d\n",type);
return -EINVAL;
}
}
static __inline__ struct tcf_st *
tcf_hash_lookup(u32 index)
{
struct tcf_st *p;
read_lock(&tcf_t_lock);
for (p = tcf_ht[tcf_hash(index)]; p; p = p->next) {
if (p->index == index)
break;
}
read_unlock(&tcf_t_lock);
return p;
}
static __inline__ u32
tcf_hash_new_index(void)
{
do {
if (++idx_gen == 0)
idx_gen = 1;
} while (tcf_hash_lookup(idx_gen));
return idx_gen;
}
static inline int
tcf_hash_search(struct tc_action *a, u32 index)
{
struct tcf_st *p = tcf_hash_lookup(index);
if (p != NULL) {
a->priv = p;
return 1;
}
return 0;
}
#ifdef CONFIG_NET_ACT_INIT
static inline struct tcf_st *
tcf_hash_check(struct tc_st *parm, struct tc_action *a, int ovr, int bind)
{
struct tcf_st *p = NULL;
if (parm->index && (p = tcf_hash_lookup(parm->index)) != NULL) {
spin_lock(&p->lock);
if (bind) {
p->bindcnt++;
p->refcnt++;
}
spin_unlock(&p->lock);
a->priv = (void *) p;
}
return p;
}
static inline struct tcf_st *
tcf_hash_create(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
{
unsigned h;
struct tcf_st *p = NULL;
p = kmalloc(size, GFP_KERNEL);
if (p == NULL)
return p;
memset(p, 0, size);
p->refcnt = 1;
if (bind) {
p->bindcnt = 1;
}
spin_lock_init(&p->lock);
p->stats_lock = &p->lock;
p->index = parm->index ? : tcf_hash_new_index();
p->tm.install = jiffies;
p->tm.lastuse = jiffies;
#ifdef CONFIG_NET_ESTIMATOR
if (est)
gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
#endif
h = tcf_hash(p->index);
write_lock_bh(&tcf_t_lock);
p->next = tcf_ht[h];
tcf_ht[h] = p;
write_unlock_bh(&tcf_t_lock);
a->priv = (void *) p;
return p;
}
static inline struct tcf_st *
tcf_hash_init(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
{
struct tcf_st *p = tcf_hash_check (parm,a,ovr,bind);
if (!p)
p = tcf_hash_create(parm, est, a, size, ovr, bind);
return p;
}
#endif
#endif

View File

@@ -0,0 +1,230 @@
#ifndef __NET_PKT_CLS_H
#define __NET_PKT_CLS_H
#include <linux/pkt_cls.h>
#include <net/sch_generic.h>
#include <net/act_api.h>
/* Basic packet classifier frontend definitions. */
struct tcf_walker
{
int stop;
int skip;
int count;
int (*fn)(struct tcf_proto *, unsigned long node, struct tcf_walker *);
};
extern int register_tcf_proto_ops(struct tcf_proto_ops *ops);
extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
extern int ing_filter(struct sk_buff *skb);
static inline unsigned long
__cls_set_class(unsigned long *clp, unsigned long cl)
{
unsigned long old_cl;
old_cl = *clp;
*clp = cl;
return old_cl;
}
static inline unsigned long
cls_set_class(struct tcf_proto *tp, unsigned long *clp,
unsigned long cl)
{
unsigned long old_cl;
tcf_tree_lock(tp);
old_cl = __cls_set_class(clp, cl);
tcf_tree_unlock(tp);
return old_cl;
}
static inline void
tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
{
unsigned long cl;
cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid);
cl = cls_set_class(tp, &r->class, cl);
if (cl)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
}
static inline void
tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
{
unsigned long cl;
if ((cl = __cls_set_class(&r->class, 0)) != 0)
tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
}
#ifdef CONFIG_NET_CLS_ACT
static inline int
tcf_change_act_police(struct tcf_proto *tp, struct tc_action **action,
struct rtattr *act_police_tlv, struct rtattr *rate_tlv)
{
int ret;
struct tc_action *act;
act = kmalloc(sizeof(*act), GFP_KERNEL);
if (NULL == act)
return -ENOMEM;
memset(act, 0, sizeof(*act));
ret = tcf_action_init_1(act_police_tlv, rate_tlv, act, "police",
TCA_ACT_NOREPLACE, TCA_ACT_BIND);
if (ret < 0) {
tcf_action_destroy(act, TCA_ACT_UNBIND);
return ret;
}
act->type = TCA_OLD_COMPAT;
if (*action) {
tcf_tree_lock(tp);
act = xchg(action, act);
tcf_tree_unlock(tp);
tcf_action_destroy(act, TCA_ACT_UNBIND);
} else
*action = act;
return 0;
}
static inline int
tcf_change_act(struct tcf_proto *tp, struct tc_action **action,
struct rtattr *act_tlv, struct rtattr *rate_tlv)
{
int ret;
struct tc_action *act;
act = kmalloc(sizeof(*act), GFP_KERNEL);
if (NULL == act)
return -ENOMEM;
memset(act, 0, sizeof(*act));
ret = tcf_action_init(act_tlv, rate_tlv, act, NULL,
TCA_ACT_NOREPLACE, TCA_ACT_BIND);
if (ret < 0) {
tcf_action_destroy(act, TCA_ACT_UNBIND);
return ret;
}
if (*action) {
tcf_tree_lock(tp);
act = xchg(action, act);
tcf_tree_unlock(tp);
tcf_action_destroy(act, TCA_ACT_UNBIND);
} else
*action = act;
return 0;
}
static inline int
tcf_dump_act(struct sk_buff *skb, struct tc_action *action,
int act_type, int compat_type)
{
/*
* again for backward compatible mode - we want
* to work with both old and new modes of entering
* tc data even if iproute2 was newer - jhs
*/
if (action) {
struct rtattr * p_rta = (struct rtattr*) skb->tail;
if (action->type != TCA_OLD_COMPAT) {
RTA_PUT(skb, act_type, 0, NULL);
if (tcf_action_dump(skb, action, 0, 0) < 0)
goto rtattr_failure;
} else {
RTA_PUT(skb, compat_type, 0, NULL);
if (tcf_action_dump_old(skb, action, 0, 0) < 0)
goto rtattr_failure;
}
p_rta->rta_len = skb->tail - (u8*)p_rta;
}
return 0;
rtattr_failure:
return -1;
}
#endif /* CONFIG_NET_CLS_ACT */
#ifdef CONFIG_NET_CLS_IND
static inline int
tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
{
if (RTA_PAYLOAD(indev_tlv) >= IFNAMSIZ) {
printk("cls: bad indev name %s\n", (char *) RTA_DATA(indev_tlv));
return -EINVAL;
}
memset(indev, 0, IFNAMSIZ);
sprintf(indev, "%s", (char *) RTA_DATA(indev_tlv));
return 0;
}
static inline int
tcf_match_indev(struct sk_buff *skb, char *indev)
{
if (0 != indev[0]) {
if (NULL == skb->input_dev)
return 0;
else if (0 != strcmp(indev, skb->input_dev->name))
return 0;
}
return 1;
}
#endif /* CONFIG_NET_CLS_IND */
#ifdef CONFIG_NET_CLS_POLICE
static inline int
tcf_change_police(struct tcf_proto *tp, struct tcf_police **police,
struct rtattr *police_tlv, struct rtattr *rate_tlv)
{
struct tcf_police *p = tcf_police_locate(police_tlv, rate_tlv);
if (*police) {
tcf_tree_lock(tp);
p = xchg(police, p);
tcf_tree_unlock(tp);
tcf_police_release(p, TCA_ACT_UNBIND);
} else
*police = p;
return 0;
}
static inline int
tcf_dump_police(struct sk_buff *skb, struct tcf_police *police,
int police_type)
{
if (police) {
struct rtattr * p_rta = (struct rtattr*) skb->tail;
RTA_PUT(skb, police_type, 0, NULL);
if (tcf_police_dump(skb, police) < 0)
goto rtattr_failure;
p_rta->rta_len = skb->tail - (u8*)p_rta;
}
return 0;
rtattr_failure:
return -1;
}
#endif /* CONFIG_NET_CLS_POLICE */
#endif

View File

@@ -0,0 +1,249 @@
#ifndef __NET_PKT_SCHED_H
#define __NET_PKT_SCHED_H
#include <net/sch_generic.h>
struct qdisc_walker
{
int stop;
int skip;
int count;
int (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *);
};
extern rwlock_t qdisc_tree_lock;
#define QDISC_ALIGN 32
#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1)
static inline void *qdisc_priv(struct Qdisc *q)
{
return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST)
& ~QDISC_ALIGN_CONST);
}
/*
Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth
Normal IP packet size ~ 512byte, hence:
0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for
10Mbit ethernet.
10msec resolution -> <50Kbit/sec.
The result: [34]86 is not good choice for QoS router :-(
The things are not so bad, because we may use artifical
clock evaluated by integration of network data flow
in the most critical places.
Note: we do not use fastgettimeofday.
The reason is that, when it is not the same thing as
gettimeofday, it returns invalid timestamp, which is
not updated, when net_bh is active.
*/
/* General note about internal clock.
Any clock source returns time intervals, measured in units
close to 1usec. With source CONFIG_NET_SCH_CLK_GETTIMEOFDAY it is precisely
microseconds, otherwise something close but different chosen to minimize
arithmetic cost. Ratio usec/internal untis in form nominator/denominator
may be read from /proc/net/psched.
*/
#ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
typedef struct timeval psched_time_t;
typedef long psched_tdiff_t;
#define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
#define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ))
#define PSCHED_JIFFIE2US(delay) ((delay)*(1000000/HZ))
#else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
typedef u64 psched_time_t;
typedef long psched_tdiff_t;
#ifdef CONFIG_NET_SCH_CLK_JIFFIES
#if HZ < 96
#define PSCHED_JSCALE 14
#elif HZ >= 96 && HZ < 192
#define PSCHED_JSCALE 13
#elif HZ >= 192 && HZ < 384
#define PSCHED_JSCALE 12
#elif HZ >= 384 && HZ < 768
#define PSCHED_JSCALE 11
#elif HZ >= 768
#define PSCHED_JSCALE 10
#endif
#define PSCHED_GET_TIME(stamp) ((stamp) = (get_jiffies_64()<<PSCHED_JSCALE))
#define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE)
#define PSCHED_JIFFIE2US(delay) ((delay)<<PSCHED_JSCALE)
#endif /* CONFIG_NET_SCH_CLK_JIFFIES */
#ifdef CONFIG_NET_SCH_CLK_CPU
#include <asm/timex.h>
extern psched_tdiff_t psched_clock_per_hz;
extern int psched_clock_scale;
extern psched_time_t psched_time_base;
extern cycles_t psched_time_mark;
#define PSCHED_GET_TIME(stamp) \
do { \
cycles_t cur = get_cycles(); \
if (sizeof(cycles_t) == sizeof(u32)) { \
if (cur <= psched_time_mark) \
psched_time_base += 0x100000000ULL; \
psched_time_mark = cur; \
(stamp) = (psched_time_base + cur)>>psched_clock_scale; \
} else { \
(stamp) = cur>>psched_clock_scale; \
} \
} while (0)
#define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
#define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz)
#endif /* CONFIG_NET_SCH_CLK_CPU */
#endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
#ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
#define PSCHED_TDIFF(tv1, tv2) \
({ \
int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
int __delta = (tv1).tv_usec - (tv2).tv_usec; \
if (__delta_sec) { \
switch (__delta_sec) { \
default: \
__delta = 0; \
case 2: \
__delta += 1000000; \
case 1: \
__delta += 1000000; \
} \
} \
__delta; \
})
static inline int
psched_tod_diff(int delta_sec, int bound)
{
int delta;
if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1)
return bound;
delta = delta_sec * 1000000;
if (delta > bound)
delta = bound;
return delta;
}
#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
({ \
int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
int __delta = (tv1).tv_usec - (tv2).tv_usec; \
switch (__delta_sec) { \
default: \
__delta = psched_tod_diff(__delta_sec, bound); break; \
case 2: \
__delta += 1000000; \
case 1: \
__delta += 1000000; \
case 0: ; \
} \
__delta; \
})
#define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \
(tv1).tv_sec <= (tv2).tv_sec) || \
(tv1).tv_sec < (tv2).tv_sec)
#define PSCHED_TADD2(tv, delta, tv_res) \
({ \
int __delta = (tv).tv_usec + (delta); \
(tv_res).tv_sec = (tv).tv_sec; \
if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \
(tv_res).tv_usec = __delta; \
})
#define PSCHED_TADD(tv, delta) \
({ \
(tv).tv_usec += (delta); \
if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \
(tv).tv_usec -= 1000000; } \
})
/* Set/check that time is in the "past perfect";
it depends on concrete representation of system time
*/
#define PSCHED_SET_PASTPERFECT(t) ((t).tv_sec = 0)
#define PSCHED_IS_PASTPERFECT(t) ((t).tv_sec == 0)
#define PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; })
#else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
#define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2))
#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
min_t(long long, (tv1) - (tv2), bound)
#define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2))
#define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta))
#define PSCHED_TADD(tv, delta) ((tv) += (delta))
#define PSCHED_SET_PASTPERFECT(t) ((t) = 0)
#define PSCHED_IS_PASTPERFECT(t) ((t) == 0)
#define PSCHED_AUDIT_TDIFF(t)
#endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
extern struct Qdisc noop_qdisc;
extern struct Qdisc_ops noop_qdisc_ops;
extern struct Qdisc_ops pfifo_qdisc_ops;
extern struct Qdisc_ops bfifo_qdisc_ops;
extern int register_qdisc(struct Qdisc_ops *qops);
extern int unregister_qdisc(struct Qdisc_ops *qops);
extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
extern void dev_init_scheduler(struct net_device *dev);
extern void dev_shutdown(struct net_device *dev);
extern void dev_activate(struct net_device *dev);
extern void dev_deactivate(struct net_device *dev);
extern void qdisc_reset(struct Qdisc *qdisc);
extern void qdisc_destroy(struct Qdisc *qdisc);
extern struct Qdisc * qdisc_create_dflt(struct net_device *dev,
struct Qdisc_ops *ops);
extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
struct rtattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
extern int qdisc_restart(struct net_device *dev);
static inline void qdisc_run(struct net_device *dev)
{
while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
/* NOTHING */;
}
extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
struct tcf_result *res);
/* Calculate maximal size of packet seen by hard_start_xmit
routine of this device.
*/
static inline unsigned psched_mtu(struct net_device *dev)
{
unsigned mtu = dev->mtu;
return dev->hard_header ? mtu + dev->hard_header_len : mtu;
}
#endif

View File

@@ -0,0 +1,99 @@
/*
* 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 protocol dispatcher.
*
* Version: @(#)protocol.h 1.0.2 05/07/93
*
* Author: 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.
*
* Changes:
* Alan Cox : Added a name field and a frag handler
* field for later.
* Alan Cox : Cleaned up, and sorted types.
* Pedro Roque : inet6 protocols
*/
#ifndef _PROTOCOL_H
#define _PROTOCOL_H
#include <linux/config.h>
#include <linux/in6.h>
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#include <linux/ipv6.h>
#endif
#define MAX_INET_PROTOS 256 /* Must be a power of 2 */
/* This is used to register protocols. */
struct net_protocol {
int (*handler)(struct sk_buff *skb);
void (*err_handler)(struct sk_buff *skb, u32 info);
int no_policy;
};
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct inet6_protocol
{
int (*handler)(struct sk_buff **skb, unsigned int *nhoffp);
void (*err_handler)(struct sk_buff *skb,
struct inet6_skb_parm *opt,
int type, int code, int offset,
__u32 info);
unsigned int flags; /* INET6_PROTO_xxx */
};
#define INET6_PROTO_NOPOLICY 0x1
#define INET6_PROTO_FINAL 0x2
#endif
/* This is used to register socket interfaces for IP protocols. */
struct inet_protosw {
struct list_head list;
/* These two fields form the lookup key. */
unsigned short type; /* This is the 2nd argument to socket(2). */
int protocol; /* This is the L4 protocol number. */
struct proto *prot;
struct proto_ops *ops;
int capability; /* Which (if any) capability do
* we need to use this socket
* interface?
*/
char no_check; /* checksum on rcv/xmit/none? */
unsigned char flags; /* See INET_PROTOSW_* below. */
};
#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */
#define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */
extern struct net_protocol *inet_protocol_base;
extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
#endif
extern int inet_add_protocol(struct net_protocol *prot, unsigned char num);
extern int inet_del_protocol(struct net_protocol *prot, unsigned char num);
extern void inet_register_protosw(struct inet_protosw *p);
extern void inet_unregister_protosw(struct inet_protosw *p);
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
extern int inet6_add_protocol(struct inet6_protocol *prot, unsigned char num);
extern int inet6_del_protocol(struct inet6_protocol *prot, unsigned char num);
extern void inet6_register_protosw(struct inet_protosw *p);
extern void inet6_unregister_protosw(struct inet_protosw *p);
#endif
#endif /* _PROTOCOL_H */

View File

@@ -0,0 +1,7 @@
#ifndef _NET_PSNAP_H
#define _NET_PSNAP_H
extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *));
extern void unregister_snap_client(struct datalink_proto *proto);
#endif

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