Commit 21a19f5d authored by Dave Jones's avatar Dave Jones

Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/bk-linus

into tetrachloride.(none):/mnt/raid/src/kernel/2.5/agpgart
parents 63098c73 7e3683e3
......@@ -53,10 +53,12 @@ struct ArcProto rawmode_proto =
};
void arcnet_raw_init(void)
static int __init arcnet_raw_init(void)
{
int count;
printk(VERSION);
for (count = 0; count < 256; count++)
if (arc_proto_map[count] == arc_proto_default)
arc_proto_map[count] = &rawmode_proto;
......@@ -66,26 +68,18 @@ void arcnet_raw_init(void)
arc_bcast_proto = &rawmode_proto;
arc_proto_default = &rawmode_proto;
}
#ifdef MODULE
int __init init_module(void)
{
printk(VERSION);
arcnet_raw_init();
return 0;
}
void cleanup_module(void)
static void __exit arcnet_raw_exit(void)
{
arcnet_unregister_proto(&rawmode_proto);
}
MODULE_LICENSE("GPL");
#endif /* MODULE */
module_init(arcnet_raw_init);
module_exit(arcnet_raw_exit);
MODULE_LICENSE("GPL");
/* packet receiver */
......
......@@ -106,13 +106,15 @@ static int arcnet_rebuild_header(struct sk_buff *skb);
static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
static int go_tx(struct net_device *dev);
void __init arcnet_init(void)
static int debug = ARCNET_DEBUG;
MODULE_PARM(debug, "i");
MODULE_LICENSE("GPL");
static int __init arcnet_init(void)
{
static int arcnet_inited;
int count;
if (arcnet_inited++)
return;
arcnet_debug = debug;
printk(VERSION);
......@@ -138,47 +140,15 @@ void __init arcnet_init(void)
sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap),
sizeof(struct archdr));
#ifdef CONFIG_ARCNET /* We're not built as a module */
printk("arcnet: Available protocols:");
#ifdef CONFIG_ARCNET_1201
printk(" RFC1201");
arcnet_rfc1201_init();
#endif
#ifdef CONFIG_ARCNET_1051
printk(" RFC1051");
arcnet_rfc1051_init();
#endif
#ifdef CONFIG_ARCNET_RAW
printk(" RAW");
arcnet_raw_init();
#endif
printk("\n");
#ifdef CONFIG_ARCNET_COM90xx
com90xx_probe(NULL);
#endif
#endif
}
#ifdef MODULE
static int debug = ARCNET_DEBUG;
MODULE_PARM(debug, "i");
MODULE_LICENSE("GPL");
int __init init_module(void)
{
arcnet_debug = debug;
arcnet_init();
return 0;
}
void cleanup_module(void)
static void __exit arcnet_exit(void)
{
}
#endif
module_init(arcnet_init);
module_exit(arcnet_exit);
/*
* Dump the contents of an sk_buff
......
......@@ -54,10 +54,6 @@ static int __init com20020isa_probe(struct net_device *dev)
unsigned long airqmask;
struct arcnet_local *lp = dev->priv;
#ifndef MODULE
arcnet_init();
#endif
BUGLVL(D_NORMAL) printk(VERSION);
ioaddr = dev->base_addr;
......
......@@ -183,9 +183,6 @@ static struct pci_driver com20020pci_driver = {
static int __init com20020pci_init(void)
{
BUGLVL(D_NORMAL) printk(VERSION);
#ifndef MODULE
arcnet_init();
#endif
return pci_module_init(&com20020pci_driver);
}
......
......@@ -151,10 +151,6 @@ static int __init com90io_probe(struct net_device *dev)
int ioaddr = dev->base_addr, status;
unsigned long airqmask;
#ifndef MODULE
arcnet_init();
#endif
BUGLVL(D_NORMAL) printk(VERSION);
BUGLVL(D_NORMAL) printk("E-mail me if you actually test this driver, please!\n");
......
......@@ -29,7 +29,6 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/bootmem.h>
#include <asm/io.h>
#include <linux/arcdevice.h>
......@@ -100,7 +99,7 @@ static int numcards;
static int com90xx_skip_probe __initdata = 0;
int __init com90xx_probe(struct net_device *dev)
static int __init com90xx_probe(struct net_device *dev)
{
int count, status, ioaddr, numprint, airq, retval = -ENODEV,
openparen = 0;
......@@ -115,10 +114,6 @@ int __init com90xx_probe(struct net_device *dev)
if (!dev && com90xx_skip_probe)
return -ENODEV;
#ifndef MODULE
arcnet_init();
#endif
BUGLVL(D_NORMAL) printk(VERSION);
/* set up the arrays where we'll store the possible probe addresses */
......@@ -603,9 +598,6 @@ static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offse
}
#ifdef MODULE
/* Module parameters */
static int io; /* use the insmod io= irq= shmem= options */
......@@ -619,7 +611,7 @@ MODULE_PARM(shmem, "i");
MODULE_PARM(device, "s");
MODULE_LICENSE("GPL");
int init_module(void)
static int __init com90xx_init(void)
{
struct net_device *dev;
int err;
......@@ -642,8 +634,7 @@ int init_module(void)
return 0;
}
void cleanup_module(void)
static void __exit com90xx_exit(void)
{
struct net_device *dev;
struct arcnet_local *lp;
......@@ -663,44 +654,38 @@ void cleanup_module(void)
}
}
#else
module_init(com90xx_init);
module_exit(com90xx_exit);
#ifndef MODULE
static int __init com90xx_setup(char *s)
{
struct net_device *dev;
int ints[8];
com90xx_skip_probe = 1;
s = get_options(s, 8, ints);
if (!ints[0] && !*s) {
printk("com90xx: Disabled.\n");
return 1;
}
dev = alloc_bootmem(sizeof(struct net_device));
memset(dev, 0, sizeof(struct net_device));
dev->init = com90xx_probe;
switch (ints[0]) {
default: /* ERROR */
printk("com90xx: Too many arguments.\n");
case 3: /* Mem address */
dev->mem_start = ints[3];
shmem = ints[3];
case 2: /* IRQ */
dev->irq = ints[2];
irq = ints[2];
case 1: /* IO address */
dev->base_addr = ints[1];
io = ints[1];
}
if (*s)
strncpy(dev->name, s, 9);
strncpy(device, s, 9);
else
strcpy(dev->name, "arc%d");
if (register_netdev(dev))
printk(KERN_ERR "com90xx: Cannot register arcnet device\n");
strcpy(device, "arc%d");
return 1;
}
__setup("com90xx=", com90xx_setup);
#endif /* MODULE */
#endif
......@@ -53,8 +53,10 @@ struct ArcProto rfc1051_proto =
};
void __init arcnet_rfc1051_init(void)
static int __init arcnet_rfc1051_init(void)
{
printk(VERSION);
arc_proto_map[ARC_P_IP_RFC1051]
= arc_proto_map[ARC_P_ARP_RFC1051]
= &rfc1051_proto;
......@@ -63,27 +65,18 @@ void __init arcnet_rfc1051_init(void)
if (arc_bcast_proto == arc_proto_default)
arc_bcast_proto = &rfc1051_proto;
}
#ifdef MODULE
MODULE_LICENSE("GPL");
int __init init_module(void)
{
printk(VERSION);
arcnet_rfc1051_init();
return 0;
}
void cleanup_module(void)
static void __exit arcnet_rfc1051_exit(void)
{
arcnet_unregister_proto(&rfc1051_proto);
}
#endif /* MODULE */
module_init(arcnet_rfc1051_init);
module_exit(arcnet_rfc1051_exit);
MODULE_LICENSE("GPL");
/*
* Determine a packet's protocol ID.
......
......@@ -53,8 +53,10 @@ struct ArcProto rfc1201_proto =
};
void __init arcnet_rfc1201_init(void)
static int __init arcnet_rfc1201_init(void)
{
printk(VERSION);
arc_proto_map[ARC_P_IP]
= arc_proto_map[ARC_P_IPV6]
= arc_proto_map[ARC_P_ARP]
......@@ -66,27 +68,17 @@ void __init arcnet_rfc1201_init(void)
/* if someone else already owns the broadcast, we won't take it */
if (arc_bcast_proto == arc_proto_default)
arc_bcast_proto = &rfc1201_proto;
}
#ifdef MODULE
MODULE_LICENSE("GPL");
int __init init_module(void)
{
printk(VERSION);
arcnet_rfc1201_init();
return 0;
}
void cleanup_module(void)
static void __exit arcnet_rfc1201_exit(void)
{
arcnet_unregister_proto(&rfc1201_proto);
}
#endif /* MODULE */
module_init(arcnet_rfc1201_init);
module_exit(arcnet_rfc1201_exit);
/*
* Determine a packet's protocol ID.
......
......@@ -11,7 +11,6 @@
extern int dmascc_init(void);
extern int arcnet_init(void);
extern int scc_enet_init(void);
extern int fec_enet_init(void);
extern int sdla_setup(void);
......@@ -42,9 +41,6 @@ static struct net_probe pci_probes[] __initdata = {
#if defined(CONFIG_SDLA)
{sdla_c_setup, 0},
#endif
#if defined(CONFIG_ARCNET)
{arcnet_init, 0},
#endif
#if defined(CONFIG_SCC_ENET)
{scc_enet_init, 0},
#endif
......
......@@ -1837,7 +1837,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
}
uint64_t
ahc_linux_get_memsize()
ahc_linux_get_memsize(void)
{
struct sysinfo si;
......@@ -1852,7 +1852,7 @@ ahc_linux_get_memsize()
* scenario.
*/
static int
ahc_linux_next_unit()
ahc_linux_next_unit(void)
{
struct ahc_softc *ahc;
int unit;
......
......@@ -2658,7 +2658,7 @@ sg_allow_access(unsigned char opcode, char dev_type)
#ifdef CONFIG_PROC_FS
static int
sg_last_dev()
sg_last_dev(void)
{
int k;
unsigned long iflags;
......@@ -2770,7 +2770,7 @@ static struct sg_proc_leaf sg_proc_leaf_arr[] = {
extern struct proc_dir_entry *proc_scsi;
static int
sg_proc_init()
sg_proc_init(void)
{
int k, mask;
int num_leaves =
......@@ -2798,7 +2798,7 @@ sg_proc_init()
}
static void
sg_proc_cleanup()
sg_proc_cleanup(void)
{
int k;
int num_leaves =
......
......@@ -333,14 +333,5 @@ void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
void arcdev_setup(struct net_device *dev);
void arcnet_rx(struct net_device *dev, int bufnum);
void arcnet_init(void);
void arcnet_rfc1201_init(void);
void arcnet_rfc1051_init(void);
void arcnet_raw_init(void);
int com90xx_probe(struct net_device *dev);
#endif /* __KERNEL__ */
#endif /* _LINUX_ARCDEVICE_H */
......@@ -347,13 +347,14 @@ struct ipt_match
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
/* Arguments changed since 2.4, as this must now handle
non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
int (*match)(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop);
/* Called when user tries to insert an entry of this type. */
......@@ -367,7 +368,7 @@ struct ipt_match
/* Called when entry of this type deleted. */
void (*destroy)(void *matchinfo, unsigned int matchinfosize);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
/* Set this to THIS_MODULE. */
struct module *me;
};
......@@ -378,14 +379,6 @@ struct ipt_target
const char name[IPT_FUNCTION_MAXNAMELEN];
/* Returns verdict. */
unsigned int (*target)(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
const void *targinfo,
void *userdata);
/* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be
called. */
......@@ -399,7 +392,17 @@ struct ipt_target
/* Called when entry of this type deleted. */
void (*destroy)(void *targinfo, unsigned int targinfosize);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
/* Returns verdict. Argument order changed since 2.4, as this
must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
unsigned int (*target)(struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userdata);
/* Set this to THIS_MODULE. */
struct module *me;
};
......@@ -429,7 +432,7 @@ struct ipt_table
/* Man behind the curtain... */
struct ipt_table_info *private;
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
/* Set to THIS_MODULE. */
struct module *me;
};
......
......@@ -295,7 +295,6 @@ extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
extern void ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport,
u32 info);
extern int ip_seq_release(struct inode *inode, struct file *file);
extern int ipv4_proc_init(void);
/* sysctl helpers - any sysctl which holds a value that ends up being
......
......@@ -16,7 +16,6 @@ extern struct proto tcpv6_prot;
struct flowi;
/* extention headers */
extern void ipv6_hopopts_init(void);
extern void ipv6_rthdr_init(void);
extern void ipv6_frag_init(void);
extern void ipv6_nodata_init(void);
......
......@@ -2863,9 +2863,6 @@ int unregister_netdevice(struct net_device *dev)
extern void net_device_init(void);
extern void ip_auto_config(void);
#ifdef CONFIG_NET_DIVERT
extern void dv_init(void);
#endif /* CONFIG_NET_DIVERT */
/*
......@@ -2889,10 +2886,6 @@ static int __init net_dev_init(void)
for (i = 0; i < 16; i++)
INIT_LIST_HEAD(&ptype_base[i]);
#ifdef CONFIG_NET_DIVERT
dv_init();
#endif /* CONFIG_NET_DIVERT */
/*
* Initialise the packet receive queues.
*/
......
......@@ -123,6 +123,7 @@ void * dst_alloc(struct dst_ops * ops)
if (!dst)
return NULL;
memset(dst, 0, ops->entry_size);
atomic_set(&dst->__refcnt, 0);
dst->ops = ops;
dst->lastuse = jiffies;
dst->path = dst;
......
......@@ -40,11 +40,12 @@
const char sysctl_divert_version[32]="0.46"; /* Current version */
int __init dv_init(void)
static int __init dv_init(void)
{
printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version);
return 0;
}
module_init(dv_init);
/*
* Allocate a divert_blk for a device. This must be an ethernet nic.
......
......@@ -52,7 +52,7 @@
DECLARE_MUTEX(rtnl_sem);
void rtnl_lock()
void rtnl_lock(void)
{
rtnl_shlock();
rtnl_exlock();
......
......@@ -1389,7 +1389,7 @@ static struct file_operations arp_seq_fops = {
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ip_seq_release,
.release = seq_release_private,
};
static int __init arp_proc_init(void)
......
......@@ -1069,7 +1069,7 @@ static struct file_operations fib_seq_fops = {
.open = fib_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ip_seq_release,
.release = seq_release_private,
};
int __init fib_proc_init(void)
......
......@@ -111,9 +111,9 @@ static struct ipt_table nat_table = {
/* Source NAT */
static unsigned int ipt_snat_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......@@ -132,9 +132,9 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
}
static unsigned int ipt_dnat_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......
......@@ -214,9 +214,9 @@ ip_checkentry(const struct ipt_ip *ip)
static unsigned int
ipt_error(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......@@ -232,13 +232,10 @@ int do_match(struct ipt_entry_match *m,
const struct net_device *in,
const struct net_device *out,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
/* Stop iteration if it doesn't match */
if (!m->u.kernel.match->match(skb, in, out, m->data,
offset, hdr, datalen, hotdrop))
if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop))
return 1;
else
return 0;
......@@ -262,7 +259,6 @@ ipt_do_table(struct sk_buff **pskb,
static const char nulldevname[IFNAMSIZ] = { 0 };
u_int16_t offset;
struct iphdr *ip;
void *protohdr;
u_int16_t datalen;
int hotdrop = 0;
/* Initializing verdict to NF_DROP keeps gcc happy. */
......@@ -271,13 +267,8 @@ ipt_do_table(struct sk_buff **pskb,
void *table_base;
struct ipt_entry *e, *back;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* Initialization */
ip = (*pskb)->nh.iph;
protohdr = (u_int32_t *)ip + ip->ihl;
datalen = (*pskb)->len - ip->ihl * 4;
indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname;
......@@ -320,8 +311,7 @@ ipt_do_table(struct sk_buff **pskb,
if (IPT_MATCH_ITERATE(e, do_match,
*pskb, in, out,
offset, protohdr,
datalen, &hotdrop) != 0)
offset, &hotdrop) != 0)
goto no_match;
ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
......@@ -364,8 +354,8 @@ ipt_do_table(struct sk_buff **pskb,
= 0xeeeeeeec;
#endif
verdict = t->u.kernel.target->target(pskb,
hook,
in, out,
hook,
t->data,
userdata);
......@@ -382,7 +372,6 @@ ipt_do_table(struct sk_buff **pskb,
#endif
/* Target might have changed stuff. */
ip = (*pskb)->nh.iph;
protohdr = (u_int32_t *)ip + ip->ihl;
datalen = (*pskb)->len - ip->ihl * 4;
if (verdict == IPT_CONTINUE)
......@@ -1458,22 +1447,24 @@ port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
static int
tcp_find_option(u_int8_t option,
const struct tcphdr *tcp,
u_int16_t datalen,
const struct sk_buff *skb,
unsigned int optlen,
int invert,
int *hotdrop)
{
unsigned int i = sizeof(struct tcphdr);
const u_int8_t *opt = (u_int8_t *)tcp;
/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
char opt[60 - sizeof(struct tcphdr)];
unsigned int i;
duprintf("tcp_match: finding option\n");
/* If we don't have the whole header, drop packet. */
if (tcp->doff * 4 > datalen) {
if (skb_copy_bits(skb, skb->nh.iph->ihl*4 + sizeof(struct tcphdr),
opt, optlen) < 0) {
*hotdrop = 1;
return 0;
}
while (i < tcp->doff * 4) {
for (i = 0; i < optlen; ) {
if (opt[i] == option) return !invert;
if (opt[i] < 2) i++;
else i += opt[i+1]?:1;
......@@ -1488,25 +1479,29 @@ tcp_match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct tcphdr *tcp = hdr;
struct tcphdr tcph;
const struct ipt_tcp *tcpinfo = matchinfo;
/* To quote Alan:
Don't allow a fragment of TCP 8 bytes in. Nobody normal
causes this. Its a cracker trying to break in by doing a
flag overwrite to pass the direction checks.
*/
if (offset) {
/* To quote Alan:
if (offset == 1) {
duprintf("Dropping evil TCP offset=1 frag.\n");
*hotdrop = 1;
Don't allow a fragment of TCP 8 bytes in. Nobody normal
causes this. Its a cracker trying to break in by doing a
flag overwrite to pass the direction checks.
*/
if (offset == 1) {
duprintf("Dropping evil TCP offset=1 frag.\n");
*hotdrop = 1;
}
/* Must not be a fragment. */
return 0;
} else if (offset == 0 && datalen < sizeof(struct tcphdr)) {
}
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("Dropping evil TCP offset=0 tinygram.\n");
......@@ -1514,27 +1509,24 @@ tcp_match(const struct sk_buff *skb,
return 0;
}
/* FIXME: Try tcp doff >> packet len against various stacks --RR */
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
/* Must not be a fragment. */
return !offset
&& port_match(tcpinfo->spts[0], tcpinfo->spts[1],
ntohs(tcp->source),
!!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))
&& port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
ntohs(tcp->dest),
!!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))
&& FWINVTCP((((unsigned char *)tcp)[13]
& tcpinfo->flg_mask)
== tcpinfo->flg_cmp,
IPT_TCP_INV_FLAGS)
&& (!tcpinfo->option
|| tcp_find_option(tcpinfo->option, tcp, datalen,
tcpinfo->invflags
& IPT_TCP_INV_OPTION,
hotdrop));
if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
ntohs(tcph.source),
!!(tcpinfo->invflags & IPT_TCP_INV_SRCPT)))
return 0;
if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
ntohs(tcph.dest),
!!(tcpinfo->invflags & IPT_TCP_INV_DSTPT)))
return 0;
if (!FWINVTCP((((unsigned char *)&tcph)[13] & tcpinfo->flg_mask)
== tcpinfo->flg_cmp,
IPT_TCP_INV_FLAGS))
return 0;
if (tcpinfo->option &&
!tcp_find_option(tcpinfo->option, skb, tcph.doff*4 - sizeof(tcph),
tcpinfo->invflags & IPT_TCP_INV_OPTION,
hotdrop))
return 0;
return 1;
}
/* Called when user tries to insert an entry of this type. */
......@@ -1560,14 +1552,16 @@ udp_match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct udphdr *udp = hdr;
struct udphdr udph;
const struct ipt_udp *udpinfo = matchinfo;
if (offset == 0 && datalen < sizeof(struct udphdr)) {
/* Must not be a fragment. */
if (offset)
return 0;
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("Dropping evil UDP tinygram.\n");
......@@ -1575,13 +1569,11 @@ udp_match(const struct sk_buff *skb,
return 0;
}
/* Must not be a fragment. */
return !offset
&& port_match(udpinfo->spts[0], udpinfo->spts[1],
ntohs(udp->source),
!!(udpinfo->invflags & IPT_UDP_INV_SRCPT))
return port_match(udpinfo->spts[0], udpinfo->spts[1],
ntohs(udph.source),
!!(udpinfo->invflags & IPT_UDP_INV_SRCPT))
&& port_match(udpinfo->dpts[0], udpinfo->dpts[1],
ntohs(udp->dest),
ntohs(udph.dest),
!!(udpinfo->invflags & IPT_UDP_INV_DSTPT));
}
......@@ -1631,14 +1623,16 @@ icmp_match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct icmphdr *icmp = hdr;
struct icmphdr icmph;
const struct ipt_icmp *icmpinfo = matchinfo;
if (offset == 0 && datalen < 2) {
/* Must not be a fragment. */
if (offset)
return 0;
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &icmph, sizeof(icmph)) < 0){
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("Dropping evil ICMP tinygram.\n");
......@@ -1646,13 +1640,11 @@ icmp_match(const struct sk_buff *skb,
return 0;
}
/* Must not be a fragment. */
return !offset
&& icmp_type_code_match(icmpinfo->type,
icmpinfo->code[0],
icmpinfo->code[1],
icmp->type, icmp->code,
!!(icmpinfo->invflags&IPT_ICMP_INV));
return icmp_type_code_match(icmpinfo->type,
icmpinfo->code[0],
icmpinfo->code[1],
icmph.type, icmph.code,
!!(icmpinfo->invflags&IPT_ICMP_INV));
}
/* Called when user tries to insert an entry of this type. */
......
......@@ -23,37 +23,31 @@ MODULE_LICENSE("GPL");
static unsigned int
target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
const struct ipt_DSCP_info *dinfo = targinfo;
u_int8_t sh_dscp = ((dinfo->dscp << IPT_DSCP_SHIFT) & IPT_DSCP_MASK);
if ((iph->tos & IPT_DSCP_MASK) != sh_dscp) {
if (((*pskb)->nh.iph->tos & IPT_DSCP_MASK) != sh_dscp) {
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
* skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
diffs[0] = htons(iph->tos) ^ 0xFFFF;
iph->tos = (iph->tos & ~IPT_DSCP_MASK) | sh_dscp;
diffs[1] = htons(iph->tos);
iph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
iph->check^0xFFFF));
if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP;
diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
(*pskb)->nh.iph->tos = ((*pskb)->nh.iph->tos & ~IPT_DSCP_MASK)
| sh_dscp;
diffs[1] = htons((*pskb)->nh.iph->tos);
(*pskb)->nh.iph->check
= csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
(*pskb)->nh.iph->check
^ 0xFFFF));
(*pskb)->nfcache |= NFC_ALTERED;
}
return IPT_CONTINUE;
......
......@@ -19,105 +19,85 @@
MODULE_LICENSE("GPL");
/* set ECT codepoint from IP header.
* return 0 in case there was no ECT codepoint
* return 1 in case ECT codepoint has been overwritten
* return < 0 in case there was error */
* return 0 if there was an error. */
static inline int
set_ect_ip(struct sk_buff **pskb, struct iphdr *iph,
const struct ipt_ECN_info *einfo)
set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
if ((iph->tos & IPT_ECN_IP_MASK)
if (((*pskb)->nh.iph->tos & IPT_ECN_IP_MASK)
!= (einfo->ip_ect & IPT_ECN_IP_MASK)) {
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
* skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
diffs[0] = htons(iph->tos) ^ 0xFFFF;
iph->tos = iph->tos & ~IPT_ECN_IP_MASK;
iph->tos = iph->tos | (einfo->ip_ect & IPT_ECN_IP_MASK);
diffs[1] = htons(iph->tos);
iph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
iph->check^0xFFFF));
if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
return 0;
diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
(*pskb)->nh.iph->tos &= ~IPT_ECN_IP_MASK;
(*pskb)->nh.iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
diffs[1] = htons((*pskb)->nh.iph->tos);
(*pskb)->nh.iph->check
= csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
(*pskb)->nh.iph->check
^0xFFFF));
(*pskb)->nfcache |= NFC_ALTERED;
return 1;
}
return 0;
return 1;
}
/* Return 0 if there was an error. */
static inline int
set_ect_tcp(struct sk_buff **pskb, struct iphdr *iph,
const struct ipt_ECN_info *einfo)
set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
{
struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
u_int16_t *tcpflags = (u_int16_t *)tcph + 6;
struct tcphdr tcph;
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
* skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
/* Not enought header? */
if (skb_copy_bits(*pskb, (*pskb)->nh.iph->ihl*4, &tcph, sizeof(tcph))
< 0)
return 0;
diffs[0] = *tcpflags;
diffs[0] = ((u_int16_t *)&tcph)[6];
if (einfo->operation & IPT_ECN_OP_SET_ECE)
tcph.ece = einfo->proto.tcp.ece;
if (einfo->operation & IPT_ECN_OP_SET_ECE
&& tcph->ece != einfo->proto.tcp.ece) {
tcph->ece = einfo->proto.tcp.ece;
}
if (einfo->operation & IPT_ECN_OP_SET_CWR)
tcph.cwr = einfo->proto.tcp.cwr;
diffs[1] = ((u_int16_t *)&tcph)[6];
if (einfo->operation & IPT_ECN_OP_SET_CWR
&& tcph->cwr != einfo->proto.tcp.cwr) {
tcph->cwr = einfo->proto.tcp.cwr;
}
if (diffs[0] != *tcpflags) {
/* Only mangle if it's changed. */
if (diffs[0] != diffs[1]) {
diffs[0] = diffs[0] ^ 0xFFFF;
diffs[1] = *tcpflags;
tcph->check = csum_fold(csum_partial((char *)diffs,
if (!skb_ip_make_writable(pskb,
(*pskb)->nh.iph->ihl*4+sizeof(tcph)))
return 0;
tcph.check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
tcph->check^0xFFFF));
tcph.check^0xFFFF));
memcpy((*pskb)->data + (*pskb)->nh.iph->ihl*4,
&tcph, sizeof(tcph));
(*pskb)->nfcache |= NFC_ALTERED;
return 1;
}
return 0;
return 1;
}
static unsigned int
target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
const struct ipt_ECN_info *einfo = targinfo;
if (einfo->operation & IPT_ECN_OP_SET_IP)
set_ect_ip(pskb, iph, einfo);
if (!set_ect_ip(pskb, einfo))
return NF_DROP;
if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
&& iph->protocol == IPPROTO_TCP)
set_ect_tcp(pskb, iph, einfo);
&& (*pskb)->nh.iph->protocol == IPPROTO_TCP)
if (!set_ect_tcp(pskb, einfo))
return NF_DROP;
return IPT_CONTINUE;
}
......
......@@ -29,127 +29,151 @@ static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
/* One level of recursion won't kill us */
static void dump_packet(const struct ipt_log_info *info,
struct iphdr *iph, unsigned int len, int recurse)
const struct sk_buff *skb,
unsigned int iphoff)
{
void *protoh = (u_int32_t *)iph + iph->ihl;
unsigned int datalen = len - iph->ihl * 4;
struct iphdr iph;
if (skb_copy_bits(skb, iphoff, &iph, sizeof(iph)) < 0) {
printk("TRUNCATED");
return;
}
/* Important fields:
* TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
NIPQUAD(iph.saddr), NIPQUAD(iph.daddr));
/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
ntohs(iph->tot_len), iph->tos & IPTOS_TOS_MASK,
iph->tos & IPTOS_PREC_MASK, iph->ttl, ntohs(iph->id));
ntohs(iph.tot_len), iph.tos & IPTOS_TOS_MASK,
iph.tos & IPTOS_PREC_MASK, iph.ttl, ntohs(iph.id));
/* Max length: 6 "CE DF MF " */
if (ntohs(iph->frag_off) & IP_CE)
if (ntohs(iph.frag_off) & IP_CE)
printk("CE ");
if (ntohs(iph->frag_off) & IP_DF)
if (ntohs(iph.frag_off) & IP_DF)
printk("DF ");
if (ntohs(iph->frag_off) & IP_MF)
if (ntohs(iph.frag_off) & IP_MF)
printk("MF ");
/* Max length: 11 "FRAG:65535 " */
if (ntohs(iph->frag_off) & IP_OFFSET)
printk("FRAG:%u ", ntohs(iph->frag_off) & IP_OFFSET);
if (ntohs(iph.frag_off) & IP_OFFSET)
printk("FRAG:%u ", ntohs(iph.frag_off) & IP_OFFSET);
if ((info->logflags & IPT_LOG_IPOPT)
&& iph->ihl * 4 != sizeof(struct iphdr)) {
unsigned int i;
&& iph.ihl * 4 != sizeof(struct iphdr)) {
unsigned char opt[4 * 15 - sizeof(struct iphdr)];
unsigned int i, optsize;
optsize = iph.ihl * 4 - sizeof(struct iphdr);
if (skb_copy_bits(skb, iphoff+sizeof(iph), opt, optsize) < 0) {
printk("TRUNCATED");
return;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
printk("OPT (");
for (i = sizeof(struct iphdr); i < iph->ihl * 4; i++)
printk("%02X", ((u_int8_t *)iph)[i]);
for (i = 0; i < optsize; i++)
printk("%02X", opt[i]);
printk(") ");
}
switch (iph->protocol) {
switch (iph.protocol) {
case IPPROTO_TCP: {
struct tcphdr *tcph = protoh;
struct tcphdr tcph;
/* Max length: 10 "PROTO=TCP " */
printk("PROTO=TCP ");
if (ntohs(iph->frag_off) & IP_OFFSET)
if (ntohs(iph.frag_off) & IP_OFFSET)
break;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if (datalen < sizeof (*tcph)) {
printk("INCOMPLETE [%u bytes] ", datalen);
if (skb_copy_bits(skb, iphoff+iph.ihl*4, &tcph, sizeof(tcph))
< 0) {
printk("INCOMPLETE [%u bytes] ",
skb->len - iphoff - iph.ihl*4);
break;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
printk("SPT=%u DPT=%u ",
ntohs(tcph->source), ntohs(tcph->dest));
ntohs(tcph.source), ntohs(tcph.dest));
/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
if (info->logflags & IPT_LOG_TCPSEQ)
printk("SEQ=%u ACK=%u ",
ntohl(tcph->seq), ntohl(tcph->ack_seq));
ntohl(tcph.seq), ntohl(tcph.ack_seq));
/* Max length: 13 "WINDOW=65535 " */
printk("WINDOW=%u ", ntohs(tcph->window));
printk("WINDOW=%u ", ntohs(tcph.window));
/* Max length: 9 "RES=0x3F " */
printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(tcph) & TCP_RESERVED_BITS) >> 22));
printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(&tcph) & TCP_RESERVED_BITS) >> 22));
/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
if (tcph->cwr)
if (tcph.cwr)
printk("CWR ");
if (tcph->ece)
if (tcph.ece)
printk("ECE ");
if (tcph->urg)
if (tcph.urg)
printk("URG ");
if (tcph->ack)
if (tcph.ack)
printk("ACK ");
if (tcph->psh)
if (tcph.psh)
printk("PSH ");
if (tcph->rst)
if (tcph.rst)
printk("RST ");
if (tcph->syn)
if (tcph.syn)
printk("SYN ");
if (tcph->fin)
if (tcph.fin)
printk("FIN ");
/* Max length: 11 "URGP=65535 " */
printk("URGP=%u ", ntohs(tcph->urg_ptr));
printk("URGP=%u ", ntohs(tcph.urg_ptr));
if ((info->logflags & IPT_LOG_TCPOPT)
&& tcph->doff * 4 != sizeof(struct tcphdr)) {
unsigned int i;
&& tcph.doff * 4 != sizeof(struct tcphdr)) {
unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
unsigned int i, optsize;
optsize = tcph.doff * 4 - sizeof(struct tcphdr);
if (skb_copy_bits(skb, iphoff+iph.ihl*4 + sizeof(tcph),
opt, optsize) < 0) {
printk("TRUNCATED");
return;
}
/* Max length: 127 "OPT (" 15*4*2chars ") " */
printk("OPT (");
for (i =sizeof(struct tcphdr); i < tcph->doff * 4; i++)
printk("%02X", ((u_int8_t *)tcph)[i]);
for (i = 0; i < optsize; i++)
printk("%02X", opt[i]);
printk(") ");
}
break;
}
case IPPROTO_UDP: {
struct udphdr *udph = protoh;
struct udphdr udph;
/* Max length: 10 "PROTO=UDP " */
printk("PROTO=UDP ");
if (ntohs(iph->frag_off) & IP_OFFSET)
if (ntohs(iph.frag_off) & IP_OFFSET)
break;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if (datalen < sizeof (*udph)) {
printk("INCOMPLETE [%u bytes] ", datalen);
if (skb_copy_bits(skb, iphoff+iph.ihl*4, &udph, sizeof(udph))
< 0) {
printk("INCOMPLETE [%u bytes] ",
skb->len - iphoff - iph.ihl*4);
break;
}
/* Max length: 20 "SPT=65535 DPT=65535 " */
printk("SPT=%u DPT=%u LEN=%u ",
ntohs(udph->source), ntohs(udph->dest),
ntohs(udph->len));
ntohs(udph.source), ntohs(udph.dest),
ntohs(udph.len));
break;
}
case IPPROTO_ICMP: {
struct icmphdr *icmph = protoh;
struct icmphdr icmph;
static size_t required_len[NR_ICMP_TYPES+1]
= { [ICMP_ECHOREPLY] = 4,
[ICMP_DEST_UNREACH]
......@@ -171,89 +195,93 @@ static void dump_packet(const struct ipt_log_info *info,
/* Max length: 11 "PROTO=ICMP " */
printk("PROTO=ICMP ");
if (ntohs(iph->frag_off) & IP_OFFSET)
if (ntohs(iph.frag_off) & IP_OFFSET)
break;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if (datalen < 4) {
printk("INCOMPLETE [%u bytes] ", datalen);
if (skb_copy_bits(skb, iphoff+iph.ihl*4, &icmph, sizeof(icmph))
< 0) {
printk("INCOMPLETE [%u bytes] ",
skb->len - iphoff - iph.ihl*4);
break;
}
/* Max length: 18 "TYPE=255 CODE=255 " */
printk("TYPE=%u CODE=%u ", icmph->type, icmph->code);
printk("TYPE=%u CODE=%u ", icmph.type, icmph.code);
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if (icmph->type <= NR_ICMP_TYPES
&& required_len[icmph->type]
&& datalen < required_len[icmph->type]) {
printk("INCOMPLETE [%u bytes] ", datalen);
if (icmph.type <= NR_ICMP_TYPES
&& required_len[icmph.type]
&& skb->len-iphoff-iph.ihl*4 < required_len[icmph.type]) {
printk("INCOMPLETE [%u bytes] ",
skb->len - iphoff - iph.ihl*4);
break;
}
switch (icmph->type) {
switch (icmph.type) {
case ICMP_ECHOREPLY:
case ICMP_ECHO:
/* Max length: 19 "ID=65535 SEQ=65535 " */
printk("ID=%u SEQ=%u ",
ntohs(icmph->un.echo.id),
ntohs(icmph->un.echo.sequence));
ntohs(icmph.un.echo.id),
ntohs(icmph.un.echo.sequence));
break;
case ICMP_PARAMETERPROB:
/* Max length: 14 "PARAMETER=255 " */
printk("PARAMETER=%u ",
ntohl(icmph->un.gateway) >> 24);
ntohl(icmph.un.gateway) >> 24);
break;
case ICMP_REDIRECT:
/* Max length: 24 "GATEWAY=255.255.255.255 " */
printk("GATEWAY=%u.%u.%u.%u ", NIPQUAD(icmph->un.gateway));
printk("GATEWAY=%u.%u.%u.%u ",
NIPQUAD(icmph.un.gateway));
/* Fall through */
case ICMP_DEST_UNREACH:
case ICMP_SOURCE_QUENCH:
case ICMP_TIME_EXCEEDED:
/* Max length: 3+maxlen */
if (recurse) {
if (!iphoff) { /* Only recurse once. */
printk("[");
dump_packet(info,
(struct iphdr *)(icmph + 1),
datalen-sizeof(struct icmphdr),
0);
dump_packet(info, skb,
iphoff + iph.ihl*4+sizeof(icmph));
printk("] ");
}
/* Max length: 10 "MTU=65535 " */
if (icmph->type == ICMP_DEST_UNREACH
&& icmph->code == ICMP_FRAG_NEEDED)
printk("MTU=%u ", ntohs(icmph->un.frag.mtu));
if (icmph.type == ICMP_DEST_UNREACH
&& icmph.code == ICMP_FRAG_NEEDED)
printk("MTU=%u ", ntohs(icmph.un.frag.mtu));
}
break;
}
/* Max Length */
case IPPROTO_AH:
case IPPROTO_ESP: {
struct esphdr *esph = protoh;
int esp= (iph->protocol==IPPROTO_ESP);
struct esphdr esph;
int esp = (iph.protocol==IPPROTO_ESP);
/* Max length: 10 "PROTO=ESP " */
printk("PROTO=%s ",esp? "ESP" : "AH");
if (ntohs(iph->frag_off) & IP_OFFSET)
if (ntohs(iph.frag_off) & IP_OFFSET)
break;
/* Max length: 25 "INCOMPLETE [65535 bytes] " */
if (datalen < sizeof (*esph)) {
printk("INCOMPLETE [%u bytes] ", datalen);
if (skb_copy_bits(skb, iphoff+iph.ihl*4, &esph, sizeof(esph))
< 0) {
printk("INCOMPLETE [%u bytes] ",
skb->len - iphoff - iph.ihl*4);
break;
}
/* Length: 15 "SPI=0xF1234567 " */
printk("SPI=0x%x ", ntohl(esph->spi) );
printk("SPI=0x%x ", ntohl(esph.spi));
break;
}
/* Max length: 10 "PROTO 255 " */
default:
printk("PROTO=%u ", iph->protocol);
printk("PROTO=%u ", iph.protocol);
}
/* Proto Max log string length */
......@@ -272,13 +300,12 @@ static void dump_packet(const struct ipt_log_info *info,
static unsigned int
ipt_log_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
const struct ipt_log_info *loginfo = targinfo;
char level_string[4] = "< >";
......@@ -304,7 +331,8 @@ ipt_log_target(struct sk_buff **pskb,
if (in && !out) {
/* MAC logging for input chain only. */
printk("MAC=");
if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)iph) {
if ((*pskb)->dev && (*pskb)->dev->hard_header_len
&& (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
int i;
unsigned char *p = (*pskb)->mac.raw;
for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
......@@ -315,7 +343,7 @@ ipt_log_target(struct sk_buff **pskb,
printk(" ");
}
dump_packet(loginfo, iph, (*pskb)->len, 1);
dump_packet(loginfo, *pskb, 0);
printk("\n");
spin_unlock_bh(&log_lock);
......
......@@ -9,9 +9,9 @@
static unsigned int
target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......
......@@ -57,9 +57,9 @@ masquerade_check(const char *tablename,
static unsigned int
masquerade_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......
......@@ -65,18 +65,22 @@ static int route_mirror(struct sk_buff *skb)
return 0;
}
static void
ip_rewrite(struct sk_buff *skb)
static int ip_rewrite(struct sk_buff **pskb)
{
struct iphdr *iph = skb->nh.iph;
u32 odaddr = iph->saddr;
u32 osaddr = iph->daddr;
u32 odaddr, osaddr;
skb->nfcache |= NFC_ALTERED;
if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
return 0;
odaddr = (*pskb)->nh.iph->saddr;
osaddr = (*pskb)->nh.iph->daddr;
(*pskb)->nfcache |= NFC_ALTERED;
/* Rewrite IP header */
iph->daddr = odaddr;
iph->saddr = osaddr;
(*pskb)->nh.iph->daddr = odaddr;
(*pskb)->nh.iph->saddr = osaddr;
return 1;
}
/* Stolen from ip_finish_output2 */
......@@ -100,29 +104,28 @@ static void ip_direct_send(struct sk_buff *skb)
}
static unsigned int ipt_mirror_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
if (((*pskb)->dst != NULL) &&
route_mirror(*pskb)) {
ip_rewrite(*pskb);
if (((*pskb)->dst != NULL) && route_mirror(*pskb)) {
if (!ip_rewrite(pskb))
return NF_DROP;
/* If we are not at FORWARD hook (INPUT/PREROUTING),
* the TTL isn't decreased by the IP stack */
if (hooknum != NF_IP_FORWARD) {
struct iphdr *iph = (*pskb)->nh.iph;
if (iph->ttl <= 1) {
if ((*pskb)->nh.iph->ttl <= 1) {
/* this will traverse normal stack, and
* thus call conntrack on the icmp packet */
icmp_send(*pskb, ICMP_TIME_EXCEEDED,
ICMP_EXC_TTL, 0);
return NF_DROP;
}
ip_decrease_ttl(iph);
/* Made writable by ip_rewrite */
ip_decrease_ttl((*pskb)->nh.iph);
}
/* Don't let conntrack code see this packet:
......
......@@ -53,9 +53,9 @@ redirect_check(const char *tablename,
static unsigned int
redirect_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......
......@@ -29,152 +29,140 @@ static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
void (*attach)(struct sk_buff *, struct nf_ct_info *);
/* Avoid module unload race with ip_ct_attach being NULLed out */
if (nfct && (attach = ip_ct_attach) != NULL)
if (nfct && (attach = ip_ct_attach) != NULL) {
mb(); /* Just to be sure: must be read before executing this */
attach(new_skb, nfct);
}
}
/* Send RST reply */
static void send_reset(struct sk_buff *oldskb, int local)
static unsigned int send_reset(struct sk_buff **pskb, int local)
{
struct sk_buff *nskb;
struct tcphdr *otcph, *tcph;
struct tcphdr tcph;
struct rtable *rt;
unsigned int otcplen;
u_int16_t tmp_port;
u_int32_t tmp_addr;
int needs_ack;
int hh_len;
int needs_ack, hh_len, datalen;
struct nf_ct_info *oldnfct;
/* IP header checks: fragment, too short. */
if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
|| oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
return;
/* No RSTs for fragments. */
if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET))
return NF_DROP;
otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
if (skb_copy_bits(*pskb, (*pskb)->nh.iph->ihl*4,
&tcph, sizeof(tcph)) < 0)
return NF_DROP;
/* No RST for RST. */
if (otcph->rst)
return;
/* Check checksum. */
if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
oldskb->nh.iph->daddr,
csum_partial((char *)otcph, otcplen, 0)) != 0)
return;
if (tcph.rst)
return NF_DROP;
/* FIXME: Check checksum. */
{
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = oldskb->nh.iph->saddr,
{ .daddr = (*pskb)->nh.iph->saddr,
.saddr = (local ?
oldskb->nh.iph->daddr :
(*pskb)->nh.iph->daddr :
0),
.tos = RT_TOS(oldskb->nh.iph->tos) } } };
.tos = RT_TOS((*pskb)->nh.iph->tos) } } };
/* Routing: if not headed for us, route won't like source */
if (ip_route_output_key(&rt, &fl))
return;
return NF_DROP;
hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
}
/* Copy skb (even if skb is about to be dropped, we can't just
clone it because there may be other things, such as tcpdump,
interested in it). We also need to expand headroom in case
hh_len of incoming interface < hh_len of outgoing interface */
nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
GFP_ATOMIC);
if (!nskb) {
dst_release(&rt->u.dst);
return;
/* We're going to flip the header around, drop options and data. */
if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(tcph))) {
ip_rt_put(rt);
return NF_DROP;
}
dst_release(nskb->dst);
nskb->dst = &rt->u.dst;
(*pskb)->h.th = (void *)(*pskb)->nh.iph + sizeof(tcph);
datalen = (*pskb)->len - (*pskb)->nh.iph->ihl*4 - tcph.doff*4;
/* Change over route. */
dst_release((*pskb)->dst);
(*pskb)->dst = &rt->u.dst;
/* This packet will not be the same as the other: clear nf fields */
nf_conntrack_put(nskb->nfct);
nskb->nfct = NULL;
nskb->nfcache = 0;
(*pskb)->nfcache = 0;
#ifdef CONFIG_NETFILTER_DEBUG
nskb->nf_debug = 0;
(*pskb)->nf_debug = 0;
#endif
nskb->nfmark = 0;
tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
(*pskb)->nfmark = 0;
/* Swap source and dest */
tmp_addr = nskb->nh.iph->saddr;
nskb->nh.iph->saddr = nskb->nh.iph->daddr;
nskb->nh.iph->daddr = tmp_addr;
tmp_port = tcph->source;
tcph->source = tcph->dest;
tcph->dest = tmp_port;
tmp_addr = (*pskb)->nh.iph->saddr;
(*pskb)->nh.iph->saddr = (*pskb)->nh.iph->daddr;
(*pskb)->nh.iph->daddr = tmp_addr;
tmp_port = (*pskb)->h.th->source;
(*pskb)->h.th->source = (*pskb)->h.th->dest;
(*pskb)->h.th->dest = tmp_port;
/* Truncate to length (no data) */
tcph->doff = sizeof(struct tcphdr)/4;
skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
nskb->nh.iph->tot_len = htons(nskb->len);
(*pskb)->h.th->doff = sizeof(struct tcphdr)/4;
skb_trim(*pskb, (*pskb)->nh.iph->ihl*4 + sizeof(struct tcphdr));
(*pskb)->nh.iph->tot_len = htons((*pskb)->len);
if (tcph->ack) {
if ((*pskb)->h.th->ack) {
needs_ack = 0;
tcph->seq = otcph->ack_seq;
tcph->ack_seq = 0;
(*pskb)->h.th->seq = tcph.ack_seq;
(*pskb)->h.th->ack_seq = 0;
} else {
needs_ack = 1;
tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
+ otcplen - (otcph->doff<<2));
tcph->seq = 0;
(*pskb)->h.th->ack_seq = htonl(ntohl(tcph.seq)
+ tcph.syn + tcph.fin
+ datalen);
(*pskb)->h.th->seq = 0;
}
/* Reset flags */
((u_int8_t *)tcph)[13] = 0;
tcph->rst = 1;
tcph->ack = needs_ack;
memset((*pskb)->h.raw + 13, 0, 1);
(*pskb)->h.th->rst = 1;
(*pskb)->h.th->ack = needs_ack;
tcph->window = 0;
tcph->urg_ptr = 0;
(*pskb)->h.th->window = 0;
(*pskb)->h.th->urg_ptr = 0;
/* Adjust TCP checksum */
tcph->check = 0;
tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
nskb->nh.iph->saddr,
nskb->nh.iph->daddr,
csum_partial((char *)tcph,
sizeof(struct tcphdr), 0));
(*pskb)->h.th->check = 0;
(*pskb)->h.th->check
= tcp_v4_check((*pskb)->h.th,
sizeof(struct tcphdr),
(*pskb)->nh.iph->saddr,
(*pskb)->nh.iph->daddr,
csum_partial((*pskb)->h.raw,
sizeof(struct tcphdr), 0));
/* Adjust IP TTL, DF */
nskb->nh.iph->ttl = MAXTTL;
(*pskb)->nh.iph->ttl = MAXTTL;
/* Set DF, id = 0 */
nskb->nh.iph->frag_off = htons(IP_DF);
nskb->nh.iph->id = 0;
(*pskb)->nh.iph->frag_off = htons(IP_DF);
(*pskb)->nh.iph->id = 0;
/* Adjust IP checksum */
nskb->nh.iph->check = 0;
nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
nskb->nh.iph->ihl);
(*pskb)->nh.iph->check = 0;
(*pskb)->nh.iph->check = ip_fast_csum((*pskb)->nh.raw,
(*pskb)->nh.iph->ihl);
/* "Never happens" */
if (nskb->len > dst_pmtu(nskb->dst))
goto free_nskb;
if ((*pskb)->len > dst_pmtu((*pskb)->dst))
return NF_DROP;
connection_attach(nskb, oldskb->nfct);
/* Related to old connection. */
oldnfct = (*pskb)->nfct;
connection_attach(*pskb, oldnfct);
nf_conntrack_put(oldnfct);
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, *pskb, NULL, (*pskb)->dst->dev,
ip_finish_output);
return;
free_nskb:
kfree_skb(nskb);
return NF_STOLEN;
}
static void send_unreach(struct sk_buff *skb_in, int code)
static void send_unreach(const struct sk_buff *skb_in, int code)
{
struct iphdr *iph;
struct udphdr *udph;
struct icmphdr *icmph;
struct sk_buff *nskb;
u32 saddr;
u8 tos;
......@@ -189,8 +177,6 @@ static void send_unreach(struct sk_buff *skb_in, int code)
if (!xrlim_allow(&rt->u.dst, 1*HZ))
return;
iph = skb_in->nh.iph;
/* No replies to physical multicast/broadcast */
if (skb_in->pkt_type!=PACKET_HOST)
return;
......@@ -200,46 +186,41 @@ static void send_unreach(struct sk_buff *skb_in, int code)
return;
/* Only reply to fragment 0. */
if (iph->frag_off&htons(IP_OFFSET))
if (skb_in->nh.iph->frag_off&htons(IP_OFFSET))
return;
/* Ensure we have at least 8 bytes of proto header. */
if (skb_in->len < skb_in->nh.iph->ihl*4 + 8)
return;
/* if UDP checksum is set, verify it's correct */
if (iph->protocol == IPPROTO_UDP
&& skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) {
int datalen = skb_in->len - (iph->ihl<<2);
udph = (struct udphdr *)((char *)iph + (iph->ihl<<2));
if (udph->check
&& csum_tcpudp_magic(iph->saddr, iph->daddr,
datalen, IPPROTO_UDP,
csum_partial((char *)udph, datalen,
0)) != 0)
return;
}
/* If we send an ICMP error to an ICMP error a mess would result.. */
if (iph->protocol == IPPROTO_ICMP
&& skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) {
icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2));
if (skb_in->nh.iph->protocol == IPPROTO_ICMP) {
struct icmphdr icmph;
if (skb_copy_bits(skb_in, skb_in->nh.iph->ihl*4,
&icmph, sizeof(icmph)) < 0)
return;
/* Between echo-reply (0) and timestamp (13),
everything except echo-request (8) is an error.
Also, anything greater than NR_ICMP_TYPES is
unknown, and hence should be treated as an error... */
if ((icmph->type < ICMP_TIMESTAMP
&& icmph->type != ICMP_ECHOREPLY
&& icmph->type != ICMP_ECHO)
|| icmph->type > NR_ICMP_TYPES)
if ((icmph.type < ICMP_TIMESTAMP
&& icmph.type != ICMP_ECHOREPLY
&& icmph.type != ICMP_ECHO)
|| icmph.type > NR_ICMP_TYPES)
return;
}
saddr = iph->daddr;
saddr = skb_in->nh.iph->daddr;
if (!(rt->rt_flags & RTCF_LOCAL))
saddr = 0;
tos = (iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL;
tos = (skb_in->nh.iph->tos & IPTOS_TOS_MASK)
| IPTOS_PREC_INTERNETCONTROL;
{
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = iph->saddr,
{ .daddr = skb_in->nh.iph->saddr,
.saddr = saddr,
.tos = RT_TOS(tos) } } };
if (ip_route_output_key(&rt, &fl))
......@@ -266,40 +247,38 @@ static void send_unreach(struct sk_buff *skb_in, int code)
skb_reserve(nskb, hh_len);
/* Set up IP header */
iph = nskb->nh.iph
= (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
iph->version=4;
iph->ihl=5;
iph->tos=tos;
iph->tot_len = htons(length);
nskb->nh.iph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
nskb->nh.iph->version=4;
nskb->nh.iph->ihl=5;
nskb->nh.iph->tos=tos;
nskb->nh.iph->tot_len = htons(length);
/* PMTU discovery never applies to ICMP packets. */
iph->frag_off = 0;
nskb->nh.iph->frag_off = 0;
iph->ttl = MAXTTL;
ip_select_ident(iph, &rt->u.dst, NULL);
iph->protocol=IPPROTO_ICMP;
iph->saddr=rt->rt_src;
iph->daddr=rt->rt_dst;
iph->check=0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
nskb->nh.iph->ttl = MAXTTL;
ip_select_ident(nskb->nh.iph, &rt->u.dst, NULL);
nskb->nh.iph->protocol=IPPROTO_ICMP;
nskb->nh.iph->saddr=rt->rt_src;
nskb->nh.iph->daddr=rt->rt_dst;
nskb->nh.iph->check=0;
nskb->nh.iph->check = ip_fast_csum(nskb->nh.raw,
nskb->nh.iph->ihl);
/* Set up ICMP header. */
icmph = nskb->h.icmph
= (struct icmphdr *)skb_put(nskb, sizeof(struct icmphdr));
icmph->type = ICMP_DEST_UNREACH;
icmph->code = code;
icmph->un.gateway = 0;
icmph->checksum = 0;
nskb->h.icmph = (struct icmphdr *)skb_put(nskb,sizeof(struct icmphdr));
nskb->h.icmph->type = ICMP_DEST_UNREACH;
nskb->h.icmph->code = code;
nskb->h.icmph->un.gateway = 0;
nskb->h.icmph->checksum = 0;
/* Copy as much of original packet as will fit */
data = skb_put(nskb,
length - sizeof(struct iphdr) - sizeof(struct icmphdr));
/* FIXME: won't work with nonlinear skbs --RR */
memcpy(data, skb_in->nh.iph,
length - sizeof(struct iphdr) - sizeof(struct icmphdr));
icmph->checksum = ip_compute_csum((unsigned char *)icmph,
length - sizeof(struct iphdr));
skb_copy_bits(skb_in, 0, data,
length - sizeof(struct iphdr) - sizeof(struct icmphdr));
nskb->h.icmph->checksum = ip_compute_csum(nskb->h.raw,
length-sizeof(struct iphdr));
connection_attach(nskb, skb_in->nfct);
......@@ -308,9 +287,9 @@ static void send_unreach(struct sk_buff *skb_in, int code)
}
static unsigned int reject(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......@@ -344,7 +323,7 @@ static unsigned int reject(struct sk_buff **pskb,
send_unreach(*pskb, ICMP_HOST_ANO);
break;
case IPT_TCP_RESET:
send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
return send_reset(pskb, hooknum == NF_IP_LOCAL_IN);
case IPT_ICMP_ECHOREPLY:
/* Doesn't happen. */
break;
......
......@@ -36,9 +36,9 @@ optlen(const u_int8_t *opt, unsigned int offset)
static unsigned int
ipt_tcpmss_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
......@@ -49,15 +49,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
unsigned int i;
u_int8_t *opt;
/* raw socket (tcpdump) may have clone of incoming skb: don't
disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
}
if (!skb_ip_make_writable(pskb, (*pskb)->len))
return NF_DROP;
iph = (*pskb)->nh.iph;
tcplen = (*pskb)->len - iph->ihl*4;
......
......@@ -9,35 +9,30 @@
static unsigned int
target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
const struct ipt_tos_target_info *tosinfo = targinfo;
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
if (((*pskb)->nh.iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP;
diffs[0] = htons(iph->tos) ^ 0xFFFF;
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
diffs[1] = htons(iph->tos);
iph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
iph->check^0xFFFF));
diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
(*pskb)->nh.iph->tos
= ((*pskb)->nh.iph->tos & IPTOS_PREC_MASK)
| tosinfo->tos;
diffs[1] = htons((*pskb)->nh.iph->tos);
(*pskb)->nh.iph->check
= csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
(*pskb)->nh.iph->check
^0xFFFF));
(*pskb)->nfcache |= NFC_ALTERED;
}
return IPT_CONTINUE;
......
......@@ -155,9 +155,9 @@ struct sk_buff *ulog_alloc_skb(unsigned int size)
}
static unsigned int ipt_ulog_target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo, void *userinfo)
{
ulog_buff_t *ub;
......@@ -238,8 +238,9 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
else
pm->outdev_name[0] = '\0';
if (copy_len)
memcpy(pm->payload, (*pskb)->data, copy_len);
/* copy_len <= (*pskb)->len, so can't fail. */
if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
BUG();
/* check if we are building multi-part messages */
if (ub->qlen > 1) {
......
......@@ -35,14 +35,16 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ahhdr *ah = hdr;
struct ahhdr ah;
const struct ipt_ah *ahinfo = matchinfo;
if (offset == 0 && datalen < sizeof(struct ahhdr)) {
/* Must not be a fragment. */
if (offset)
return 0;
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &ah, sizeof(ah)) < 0) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("Dropping evil AH tinygram.\n");
......@@ -50,11 +52,9 @@ match(const struct sk_buff *skb,
return 0;
}
/* Must not be a fragment. */
return !offset
&& spi_match(ahinfo->spis[0], ahinfo->spis[1],
ntohl(ah->spi),
!!(ahinfo->invflags & IPT_AH_INV_SPI));
return spi_match(ahinfo->spis[0], ahinfo->spis[1],
ntohl(ah.spi),
!!(ahinfo->invflags & IPT_AH_INV_SPI));
}
/* Called when user tries to insert an entry of this type. */
......
......@@ -14,8 +14,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_conntrack_info *sinfo = matchinfo;
......
......@@ -19,8 +19,7 @@ MODULE_LICENSE("GPL");
static int match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchinfo,
int offset, const void *hdr, u_int16_t datalen,
int *hotdrop)
int offset, int *hotdrop)
{
const struct ipt_dscp_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
......
......@@ -19,34 +19,40 @@ MODULE_DESCRIPTION("IP tables ECN matching module");
MODULE_LICENSE("GPL");
static inline int match_ip(const struct sk_buff *skb,
const struct iphdr *iph,
const struct ipt_ecn_info *einfo)
{
return ((iph->tos&IPT_ECN_IP_MASK) == einfo->ip_ect);
return ((skb->nh.iph->tos&IPT_ECN_IP_MASK) == einfo->ip_ect);
}
static inline int match_tcp(const struct sk_buff *skb,
const struct iphdr *iph,
const struct ipt_ecn_info *einfo)
const struct ipt_ecn_info *einfo,
int *hotdrop)
{
struct tcphdr *tcph = (void *)iph + iph->ihl*4;
struct tcphdr tcph;
/* In practice, TCP match does this, so can't fail. But let's
be good citizens. */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) {
*hotdrop = 0;
return 0;
}
if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
if (tcph->ece == 1)
if (tcph.ece == 1)
return 0;
} else {
if (tcph->ece == 0)
if (tcph.ece == 0)
return 0;
}
}
if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
if (tcph->cwr == 1)
if (tcph.cwr == 1)
return 0;
} else {
if (tcph->cwr == 0)
if (tcph.cwr == 0)
return 0;
}
}
......@@ -56,20 +62,18 @@ static inline int match_tcp(const struct sk_buff *skb,
static int match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchinfo,
int offset, const void *hdr, u_int16_t datalen,
int *hotdrop)
int offset, int *hotdrop)
{
const struct ipt_ecn_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
if (info->operation & IPT_ECN_OP_MATCH_IP)
if (!match_ip(skb, iph, info))
if (!match_ip(skb, info))
return 0;
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
if (iph->protocol != IPPROTO_TCP)
if (skb->nh.iph->protocol != IPPROTO_TCP)
return 0;
if (!match_tcp(skb, iph, info))
if (!match_tcp(skb, info, hotdrop))
return 0;
}
......
......@@ -35,14 +35,16 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct esphdr *esp = hdr;
struct esphdr esp;
const struct ipt_esp *espinfo = matchinfo;
if (offset == 0 && datalen < sizeof(struct esphdr)) {
/* Must not be a fragment. */
if (offset)
return 0;
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &esp, sizeof(esp)) < 0) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("Dropping evil ESP tinygram.\n");
......@@ -50,11 +52,9 @@ match(const struct sk_buff *skb,
return 0;
}
/* Must not be a fragment. */
return !offset
&& spi_match(espinfo->spis[0], espinfo->spis[1],
ntohl(esp->spi),
!!(espinfo->invflags & IPT_ESP_INV_SPI));
return spi_match(espinfo->spis[0], espinfo->spis[1],
ntohl(esp.spi),
!!(espinfo->invflags & IPT_ESP_INV_SPI));
}
/* Called when user tries to insert an entry of this type. */
......
......@@ -28,8 +28,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_helper_info *info = matchinfo;
......
......@@ -15,8 +15,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_length_info *info = matchinfo;
......
......@@ -47,8 +47,6 @@ ipt_limit_match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master;
......
......@@ -12,8 +12,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_mac_info *info = matchinfo;
......
......@@ -11,8 +11,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_mark_info *info = matchinfo;
......
......@@ -39,15 +39,18 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct udphdr *udp = hdr;
u16 ports[2];
const struct ipt_multiport *multiinfo = matchinfo;
/* Must be big enough to read ports. */
if (offset == 0 && datalen < sizeof(struct udphdr)) {
/* Must not be a fragment. */
if (offset)
return 0;
/* Must be big enough to read ports (both UDP and TCP have
them at the start). */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("ipt_multiport:"
......@@ -56,11 +59,9 @@ match(const struct sk_buff *skb,
return 0;
}
/* Must not be a fragment. */
return !offset
&& ports_match(multiinfo->ports,
multiinfo->flags, multiinfo->count,
ntohs(udp->source), ntohs(udp->dest));
return ports_match(multiinfo->ports,
multiinfo->flags, multiinfo->count,
ntohs(ports[0]), ntohs(ports[1]));
}
/* Called when user tries to insert an entry of this type. */
......
......@@ -115,8 +115,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_owner_info *info = matchinfo;
......@@ -170,8 +168,11 @@ checkentry(const char *tablename,
return 0;
}
if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info)))
if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
printk("Matchsize %u != %Zu\n", matchsize,
IPT_ALIGN(sizeof(struct ipt_owner_info)));
return 0;
}
return 1;
}
......
......@@ -14,8 +14,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
int i;
......
......@@ -13,8 +13,6 @@ static int match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_pkttype_info *info = matchinfo;
......
......@@ -13,8 +13,6 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_state_info *sinfo = matchinfo;
......
......@@ -11,24 +11,32 @@
/* Returns 1 if the mss option is set and matched by the range, 0 otherwise */
static inline int
mssoption_match(u_int16_t min, u_int16_t max,
const struct tcphdr *tcp,
u_int16_t datalen,
const struct sk_buff *skb,
int invert,
int *hotdrop)
{
unsigned int i;
const u_int8_t *opt = (u_int8_t *)tcp;
struct tcphdr tcph;
/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
u8 opt[15 * 4 - sizeof(tcph)];
unsigned int i, optlen;
/* If we don't have the whole header, drop packet. */
if (tcp->doff * 4 > datalen) {
*hotdrop = 1;
return 0;
}
for (i = sizeof(struct tcphdr); i < tcp->doff * 4; ) {
if ((opt[i] == TCPOPT_MSS)
&& ((tcp->doff * 4 - i) >= TCPOLEN_MSS)
&& (opt[i+1] == TCPOLEN_MSS)) {
if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0)
goto dropit;
/* Malformed. */
if (tcph.doff*4 < sizeof(tcph))
goto dropit;
optlen = tcph.doff*4 - sizeof(tcph);
/* Truncated options. */
if (skb_copy_bits(skb, skb->nh.iph->ihl*4+sizeof(tcph), opt, optlen)<0)
goto dropit;
for (i = 0; i < optlen; ) {
if (opt[i] == TCPOPT_MSS
&& (optlen - i) >= TCPOLEN_MSS
&& opt[i+1] == TCPOLEN_MSS) {
u_int16_t mssval;
mssval = (opt[i+2] << 8) | opt[i+3];
......@@ -38,8 +46,11 @@ mssoption_match(u_int16_t min, u_int16_t max,
if (opt[i] < 2) i++;
else i += opt[i+1]?:1;
}
return invert;
dropit:
*hotdrop = 1;
return 0;
}
static int
......@@ -48,15 +59,11 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_tcpmss_match_info *info = matchinfo;
const struct tcphdr *tcph = (void *)skb->nh.iph + skb->nh.iph->ihl*4;
return mssoption_match(info->mss_min, info->mss_max, tcph,
skb->len - skb->nh.iph->ihl*4,
return mssoption_match(info->mss_min, info->mss_max, skb,
info->invert, hotdrop);
}
......
......@@ -11,14 +11,11 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_tos_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
return (iph->tos == info->tos) ^ info->invert;
return (skb->nh.iph->tos == info->tos) ^ info->invert;
}
static int
......
......@@ -19,24 +19,22 @@ MODULE_LICENSE("GPL");
static int match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchinfo,
int offset, const void *hdr, u_int16_t datalen,
int *hotdrop)
int offset, int *hotdrop)
{
const struct ipt_ttl_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
switch (info->mode) {
case IPT_TTL_EQ:
return (iph->ttl == info->ttl);
return (skb->nh.iph->ttl == info->ttl);
break;
case IPT_TTL_NE:
return (!(iph->ttl == info->ttl));
return (!(skb->nh.iph->ttl == info->ttl));
break;
case IPT_TTL_LT:
return (iph->ttl < info->ttl);
return (skb->nh.iph->ttl < info->ttl);
break;
case IPT_TTL_GT:
return (iph->ttl > info->ttl);
return (skb->nh.iph->ttl > info->ttl);
break;
default:
printk(KERN_WARNING "ipt_ttl: unknown mode %d\n",
......
......@@ -31,16 +31,17 @@ struct icmp_info
};
static int
check_ip(struct iphdr *iph, size_t length, int embedded);
check_ip(const struct sk_buff *skb, unsigned int offset);
/* ICMP-specific checks. */
static int
check_icmp(const struct icmphdr *icmph,
u_int16_t datalen,
check_icmp(const struct sk_buff *skb,
unsigned int offset,
unsigned int fragoff,
int more_frags,
int embedded)
{
struct icmphdr icmph;
static struct icmp_info info[]
= { [ICMP_ECHOREPLY]
= { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
......@@ -76,92 +77,95 @@ check_icmp(const struct icmphdr *icmph,
= { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
/* Can't do anything if it's a fragment. */
if (offset)
if (fragoff)
return 1;
/* Must cover type and code. */
if (datalen < 2) {
limpk("ICMP len=%u too short\n", datalen);
/* CHECK: Must have whole header.. */
if (skb_copy_bits(skb, offset, &icmph, sizeof(icmph)) < 0) {
limpk("ICMP len=%u too short\n", skb->len - offset);
return 0;
}
/* If not embedded. */
/* If not embedded in an ICMP error already. */
if (!embedded) {
/* Bad checksum? Don't print, just ignore. */
if (!more_frags
&& ip_compute_csum((unsigned char *) icmph, datalen) != 0)
return 0;
/* CHECK: Truncated ICMP (even if first fragment). */
if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
&& info[icmph->type].min_len != 0
&& datalen < info[icmph->type].min_len) {
if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
&& info[icmph.type].min_len != 0
&& skb->len - offset < info[icmph.type].min_len) {
limpk("ICMP type %u len %u too short\n",
icmph->type, datalen);
icmph.type, skb->len - offset);
return 0;
}
/* CHECK: Check within known error ICMPs. */
if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
&& info[icmph->type].err == ICMP_IS_ERROR) {
if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
&& info[icmph.type].err == ICMP_IS_ERROR) {
/* Max IP header size = 60 */
char inner[60 + 8];
struct iphdr *inner_ip = (struct iphdr *)inner;
/* CHECK: Embedded packet must be at least
length of iph + 8 bytes. */
struct iphdr *inner = (void *)icmph + 8;
/* datalen > 8 since all ICMP_IS_ERROR types
have min length > 8 */
if (datalen - 8 < sizeof(struct iphdr)) {
if (skb_copy_bits(skb, offset + sizeof(icmph),
inner, sizeof(struct iphdr)+8) < 0) {
limpk("ICMP error internal way too short\n");
return 0;
}
if (datalen - 8 < inner->ihl*4 + 8) {
/* iphhdr may actually be longer: still need 8
actual protocol bytes. */
if (offset + sizeof(icmph) + inner_ip->ihl*4 + 8
> skb->len) {
limpk("ICMP error internal too short\n");
return 0;
}
if (!check_ip(inner, datalen - 8, 1))
if (!check_ip(skb, offset + sizeof(icmph)))
return 0;
}
} else {
/* CHECK: Can't embed ICMP unless known non-error. */
if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
|| info[icmph->type].err != ICMP_NOT_ERROR) {
if (icmph.type >= sizeof(info)/sizeof(struct icmp_info)
|| info[icmph.type].err != ICMP_NOT_ERROR) {
limpk("ICMP type %u not embeddable\n",
icmph->type);
icmph.type);
return 0;
}
}
/* CHECK: Invalid ICMP codes. */
if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
&& (icmph->code < info[icmph->type].min_code
|| icmph->code > info[icmph->type].max_code)) {
if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
&& (icmph.code < info[icmph.type].min_code
|| icmph.code > info[icmph.type].max_code)) {
limpk("ICMP type=%u code=%u\n",
icmph->type, icmph->code);
icmph.type, icmph.code);
return 0;
}
/* CHECK: Above maximum length. */
if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
&& info[icmph->type].max_len != 0
&& datalen > info[icmph->type].max_len) {
if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
&& info[icmph.type].max_len != 0
&& skb->len - offset > info[icmph.type].max_len) {
limpk("ICMP type=%u too long: %u bytes\n",
icmph->type, datalen);
icmph.type, skb->len - offset);
return 0;
}
switch (icmph->type) {
switch (icmph.type) {
case ICMP_PARAMETERPROB: {
/* CHECK: Problem param must be within error packet's
* IP header. */
struct iphdr *iph = (void *)icmph + 8;
u_int32_t arg = ntohl(icmph->un.gateway);
u_int32_t arg = ntohl(icmph.un.gateway);
if (icmph->code == 0) {
if (icmph.code == 0) {
/* We've already made sure it's long enough. */
struct iphdr iph;
skb_copy_bits(skb, offset + sizeof(icmph), &iph,
sizeof(iph));
/* Code 0 means that upper 8 bits is pointer
to problem. */
if ((arg >> 24) >= iph->ihl*4) {
if ((arg >> 24) >= iph.ihl*4) {
limpk("ICMP PARAMETERPROB ptr = %u\n",
ntohl(icmph->un.gateway) >> 24);
ntohl(icmph.un.gateway) >> 24);
return 0;
}
arg &= 0x00FFFFFF;
......@@ -179,9 +183,9 @@ check_icmp(const struct icmphdr *icmph,
case ICMP_TIME_EXCEEDED:
case ICMP_SOURCE_QUENCH:
/* CHECK: Unused must be zero. */
if (icmph->un.gateway != 0) {
if (icmph.un.gateway != 0) {
limpk("ICMP type=%u unused = %u\n",
icmph->type, ntohl(icmph->un.gateway));
icmph.type, ntohl(icmph.un.gateway));
return 0;
}
break;
......@@ -192,32 +196,26 @@ check_icmp(const struct icmphdr *icmph,
/* UDP-specific checks. */
static int
check_udp(const struct iphdr *iph,
const struct udphdr *udph,
u_int16_t datalen,
check_udp(const struct sk_buff *skb,
unsigned int offset,
unsigned int fragoff,
int more_frags,
int embedded)
{
struct udphdr udph;
/* Can't do anything if it's a fragment. */
if (offset)
if (fragoff)
return 1;
/* CHECK: Must cover UDP header. */
if (datalen < sizeof(struct udphdr)) {
limpk("UDP len=%u too short\n", datalen);
if (skb_copy_bits(skb, offset, &udph, sizeof(udph)) < 0) {
limpk("UDP len=%u too short\n", skb->len - offset);
return 0;
}
/* Bad checksum? Don't print, just say it's unclean. */
/* FIXME: SRC ROUTE packets won't match checksum --RR */
if (!more_frags && !embedded && udph->check
&& csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
csum_partial((char *)udph, datalen, 0)) != 0)
return 0;
/* CHECK: Destination port can't be zero. */
if (!udph->dest) {
if (!udph.dest) {
limpk("UDP zero destination port\n");
return 0;
}
......@@ -225,24 +223,24 @@ check_udp(const struct iphdr *iph,
if (!more_frags) {
if (!embedded) {
/* CHECK: UDP length must match. */
if (ntohs(udph->len) != datalen) {
if (ntohs(udph.len) != skb->len - offset) {
limpk("UDP len too short %u vs %u\n",
ntohs(udph->len), datalen);
ntohs(udph.len), skb->len - offset);
return 0;
}
} else {
/* CHECK: UDP length be >= this truncated pkt. */
if (ntohs(udph->len) < datalen) {
if (ntohs(udph.len) < skb->len - offset) {
limpk("UDP len too long %u vs %u\n",
ntohs(udph->len), datalen);
ntohs(udph.len), skb->len - offset);
return 0;
}
}
} else {
/* CHECK: UDP length must be > this frag's length. */
if (ntohs(udph->len) <= datalen) {
if (ntohs(udph.len) <= skb->len - offset) {
limpk("UDP fragment len too short %u vs %u\n",
ntohs(udph->len), datalen);
ntohs(udph.len), skb->len - offset);
return 0;
}
}
......@@ -250,104 +248,104 @@ check_udp(const struct iphdr *iph,
return 1;
}
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
/* TCP-specific checks. */
static int
check_tcp(const struct iphdr *iph,
const struct tcphdr *tcph,
u_int16_t datalen,
check_tcp(const struct sk_buff *skb,
unsigned int offset,
unsigned int fragoff,
int more_frags,
int embedded)
{
u_int8_t *opt = (u_int8_t *)tcph;
u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
u_int8_t tcpflags;
struct tcphdr tcph;
unsigned char opt[15 * 4 - sizeof(struct tcphdr)];
u32 tcpflags;
int end_of_options = 0;
size_t i;
unsigned int i, optlen;
/* CHECK: Can't have offset=1: used to override TCP syn-checks. */
/* In fact, this is caught below (offset < 516). */
/* Can't do anything if it's a fragment. */
if (offset)
if (fragoff)
return 1;
/* CHECK: Smaller than minimal TCP hdr. */
if (datalen < sizeof(struct tcphdr)) {
if (skb_copy_bits(skb, offset, &tcph, sizeof(tcph)) < 0) {
u16 ports[2];
if (!embedded) {
limpk("Packet length %u < TCP header.\n", datalen);
limpk("Packet length %u < TCP header.\n",
skb->len - offset);
return 0;
}
/* Must have ports available (datalen >= 8), from
check_icmp which set embedded = 1 */
/* CHECK: TCP ports inside ICMP error */
if (!tcph->source || !tcph->dest) {
skb_copy_bits(skb, offset, ports, sizeof(ports));
if (!ports[0] || !ports[1]) {
limpk("Zero TCP ports %u/%u.\n",
htons(tcph->source), htons(tcph->dest));
htons(ports[0]), htons(ports[1]));
return 0;
}
return 1;
}
/* CHECK: Smaller than actual TCP hdr. */
if (datalen < tcph->doff * 4) {
/* CHECK: TCP header claims tiny size. */
if (tcph.doff * 4 < sizeof(tcph)) {
limpk("TCP header claims tiny size %u\n", tcph.doff * 4);
return 0;
}
/* CHECK: Packet smaller than actual TCP hdr. */
optlen = tcph.doff*4 - sizeof(tcph);
if (skb_copy_bits(skb, offset + sizeof(tcph), opt, optlen) < 0) {
if (!embedded) {
limpk("Packet length %u < actual TCP header.\n",
datalen);
skb->len - offset);
return 0;
} else
return 1;
}
/* Bad checksum? Don't print, just say it's unclean. */
/* FIXME: SRC ROUTE packets won't match checksum --RR */
if (!more_frags && !embedded
&& csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
csum_partial((char *)tcph, datalen, 0)) != 0)
return 0;
/* CHECK: TCP ports non-zero */
if (!tcph->source || !tcph->dest) {
if (!tcph.source || !tcph.dest) {
limpk("Zero TCP ports %u/%u.\n",
htons(tcph->source), htons(tcph->dest));
htons(tcph.source), htons(tcph.dest));
return 0;
}
tcpflags = tcp_flag_word(&tcph);
/* CHECK: TCP reserved bits zero. */
if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
if (tcpflags & TCP_RESERVED_BITS) {
limpk("TCP reserved bits not zero\n");
return 0;
}
tcpflags &= ~(TCP_DATA_OFFSET | TCP_FLAG_CWR | TCP_FLAG_ECE
| __constant_htonl(0x0000FFFF));
/* CHECK: TCP flags. */
tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
if (tcpflags != TH_SYN
&& tcpflags != (TH_SYN|TH_ACK)
&& tcpflags != TH_RST
&& tcpflags != (TH_RST|TH_ACK)
&& tcpflags != (TH_RST|TH_ACK|TH_PUSH)
&& tcpflags != (TH_FIN|TH_ACK)
&& tcpflags != TH_ACK
&& tcpflags != (TH_ACK|TH_PUSH)
&& tcpflags != (TH_ACK|TH_URG)
&& tcpflags != (TH_ACK|TH_URG|TH_PUSH)
&& tcpflags != (TH_FIN|TH_ACK|TH_PUSH)
&& tcpflags != (TH_FIN|TH_ACK|TH_URG)
&& tcpflags != (TH_FIN|TH_ACK|TH_URG|TH_PUSH)) {
limpk("TCP flags bad: %u\n", tcpflags);
if (tcpflags != TCP_FLAG_SYN
&& tcpflags != (TCP_FLAG_SYN|TCP_FLAG_ACK)
&& tcpflags != TCP_FLAG_RST
&& tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK)
&& tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK|TCP_FLAG_PSH)
&& tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK)
&& tcpflags != TCP_FLAG_ACK
&& tcpflags != (TCP_FLAG_ACK|TCP_FLAG_PSH)
&& tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG)
&& tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG|TCP_FLAG_PSH)
&& tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_PSH)
&& tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG)
&& tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG
|TCP_FLAG_PSH)) {
limpk("TCP flags bad: 0x%04X\n", ntohl(tcpflags) >> 16);
return 0;
}
for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
for (i = 0; i < optlen; ) {
switch (opt[i]) {
case 0:
end_of_options = 1;
......@@ -364,7 +362,7 @@ check_tcp(const struct iphdr *iph,
return 0;
}
/* CHECK: options at tail. */
else if (i+1 >= tcph->doff * 4) {
else if (i+1 >= optlen) {
limpk("TCP option %u at tail\n",
opt[i]);
return 0;
......@@ -376,8 +374,8 @@ check_tcp(const struct iphdr *iph,
return 0;
}
/* CHECK: oversize options. */
else if (&opt[i] + opt[i+1] > endhdr) {
limpk("TCP option %u at %Zu too long\n",
else if (i + opt[i+1] > optlen) {
limpk("TCP option %u at %u too long\n",
(unsigned int) opt[i], i);
return 0;
}
......@@ -392,34 +390,44 @@ check_tcp(const struct iphdr *iph,
/* Returns 1 if ok */
/* Standard IP checks. */
static int
check_ip(struct iphdr *iph, size_t length, int embedded)
check_ip(const struct sk_buff *skb, unsigned int offset)
{
u_int8_t *opt = (u_int8_t *)iph;
u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
int end_of_options = 0;
void *protoh;
size_t datalen;
unsigned int datalen, optlen;
unsigned int i;
unsigned int offset;
unsigned int fragoff;
struct iphdr iph;
unsigned char opt[15 * 4 - sizeof(struct iphdr)];
int embedded = offset;
/* Should only happen for local outgoing raw-socket packets. */
/* CHECK: length >= ip header. */
if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
limpk("Packet length %Zu < IP header.\n", length);
if (skb_copy_bits(skb, offset, &iph, sizeof(iph)) < 0) {
limpk("Packet length %u < IP header.\n", skb->len - offset);
return 0;
}
if (iph.ihl * 4 < sizeof(iph)) {
limpk("IP len %u < minimum IP header.\n", iph.ihl*4);
return 0;
}
optlen = iph.ihl * 4 - sizeof(iph);
if (skb_copy_bits(skb, offset+sizeof(struct iphdr), opt, optlen)<0) {
limpk("Packet length %u < IP header %u.\n",
skb->len - offset, iph.ihl * 4);
return 0;
}
offset = ntohs(iph->frag_off) & IP_OFFSET;
protoh = (void *)iph + iph->ihl * 4;
datalen = length - iph->ihl * 4;
fragoff = (ntohs(iph.frag_off) & IP_OFFSET);
datalen = skb->len - (offset + sizeof(struct iphdr) + optlen);
/* CHECK: Embedded fragment. */
if (embedded && offset) {
if (offset && fragoff) {
limpk("Embedded fragment.\n");
return 0;
}
for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
for (i = 0; i < optlen; ) {
switch (opt[i]) {
case 0:
end_of_options = 1;
......@@ -436,7 +444,7 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
return 0;
}
/* CHECK: options at tail. */
else if (i+1 >= iph->ihl * 4) {
else if (i+1 >= optlen) {
limpk("IP option %u at tail\n",
opt[i]);
return 0;
......@@ -448,7 +456,7 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
return 0;
}
/* CHECK: oversize options. */
else if (&opt[i] + opt[i+1] > endhdr) {
else if (i + opt[i+1] > optlen) {
limpk("IP option %u at %u too long\n",
opt[i], i);
return 0;
......@@ -461,30 +469,30 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
/* Fragment checks. */
/* CHECK: More fragments, but doesn't fill 8-byte boundary. */
if ((ntohs(iph->frag_off) & IP_MF)
&& (ntohs(iph->tot_len) % 8) != 0) {
limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
if ((ntohs(iph.frag_off) & IP_MF)
&& (ntohs(iph.tot_len) % 8) != 0) {
limpk("Truncated fragment %u long.\n", ntohs(iph.tot_len));
return 0;
}
/* CHECK: Oversize fragment a-la Ping of Death. */
if (offset * 8 + datalen > 65535) {
limpk("Oversize fragment to %u.\n", offset * 8);
if (fragoff * 8 + datalen > 65535) {
limpk("Oversize fragment to %u.\n", fragoff * 8);
return 0;
}
/* CHECK: DF set and offset or MF set. */
if ((ntohs(iph->frag_off) & IP_DF)
&& (offset || (ntohs(iph->frag_off) & IP_MF))) {
/* CHECK: DF set and fragoff or MF set. */
if ((ntohs(iph.frag_off) & IP_DF)
&& (fragoff || (ntohs(iph.frag_off) & IP_MF))) {
limpk("DF set and offset=%u, MF=%u.\n",
offset, ntohs(iph->frag_off) & IP_MF);
fragoff, ntohs(iph.frag_off) & IP_MF);
return 0;
}
/* CHECK: Zero-sized fragments. */
if ((offset || (ntohs(iph->frag_off) & IP_MF))
if ((fragoff || (ntohs(iph.frag_off) & IP_MF))
&& datalen == 0) {
limpk("Zero size fragment offset=%u\n", offset);
limpk("Zero size fragment offset=%u\n", fragoff);
return 0;
}
......@@ -500,52 +508,54 @@ check_ip(struct iphdr *iph, size_t length, int embedded)
here. */
#define MIN_LIKELY_MTU 128
/* CHECK: Min size of first frag = 128. */
if ((ntohs(iph->frag_off) & IP_MF)
&& offset == 0
&& ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
if ((ntohs(iph.frag_off) & IP_MF)
&& fragoff == 0
&& ntohs(iph.tot_len) < MIN_LIKELY_MTU) {
limpk("First fragment size %u < %u\n", ntohs(iph.tot_len),
MIN_LIKELY_MTU);
return 0;
}
/* CHECK: Min offset of frag = 128 - IP hdr len. */
if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
limpk("Fragment starts at %u < %u\n", offset * 8,
MIN_LIKELY_MTU - iph->ihl * 4);
if (fragoff && fragoff * 8 < MIN_LIKELY_MTU - iph.ihl * 4) {
limpk("Fragment starts at %u < %u\n", fragoff * 8,
MIN_LIKELY_MTU - iph.ihl * 4);
return 0;
}
/* CHECK: Protocol specification non-zero. */
if (iph->protocol == 0) {
if (iph.protocol == 0) {
limpk("Zero protocol\n");
return 0;
}
/* FIXME: This is already checked for in "Oversize fragment"
above --RR */
/* CHECK: Do not use what is unused.
* First bit of fragmentation flags should be unused.
* May be used by OS fingerprinting tools.
* 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
*/
if (ntohs(iph->frag_off)>>15) {
if (ntohs(iph.frag_off)>>15) {
limpk("IP unused bit set\n");
return 0;
}
/* Per-protocol checks. */
switch (iph->protocol) {
switch (iph.protocol) {
case IPPROTO_ICMP:
return check_icmp(protoh, datalen, offset,
(ntohs(iph->frag_off) & IP_MF),
return check_icmp(skb, offset + iph.ihl*4, fragoff,
(ntohs(iph.frag_off) & IP_MF),
embedded);
case IPPROTO_UDP:
return check_udp(iph, protoh, datalen, offset,
(ntohs(iph->frag_off) & IP_MF),
return check_udp(skb, offset + iph.ihl*4, fragoff,
(ntohs(iph.frag_off) & IP_MF),
embedded);
case IPPROTO_TCP:
return check_tcp(iph, protoh, datalen, offset,
(ntohs(iph->frag_off) & IP_MF),
return check_tcp(skb, offset + iph.ihl*4, fragoff,
(ntohs(iph.frag_off) & IP_MF),
embedded);
default:
/* Ignorance is bliss. */
......@@ -559,11 +569,9 @@ match(const struct sk_buff *skb,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
return !check_ip(skb->nh.iph, skb->len, 0);
return !check_ip(skb, 0);
}
/* Called when user tries to insert an entry of this type. */
......
......@@ -265,11 +265,3 @@ int __init ip_misc_proc_init(void)
goto out;
}
int ip_seq_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = (struct seq_file *)file->private_data;
kfree(seq->private);
seq->private = NULL;
return seq_release(inode, file);
}
......@@ -386,7 +386,7 @@ static struct file_operations rt_cache_seq_fops = {
.open = rt_cache_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ip_seq_release,
.release = seq_release_private,
};
int __init rt_cache_proc_init(void)
......
......@@ -2568,7 +2568,7 @@ static struct file_operations tcp_seq_fops = {
.open = tcp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ip_seq_release,
.release = seq_release_private,
};
int __init tcp_proc_init(void)
......
......@@ -1479,7 +1479,7 @@ static struct file_operations udp_seq_fops = {
.open = udp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = ip_seq_release,
.release = seq_release_private,
};
/* ------------------------------------------------------------------------ */
......
......@@ -127,8 +127,8 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
dev_hold(dev);
dst_release(&rt->u.dst);
} else if (ishost) {
sock_kfree_s(sk, pac, sizeof(*pac));
return -EADDRNOTAVAIL;
err = -EADDRNOTAVAIL;
goto out_free_pac;
} else {
/* router, no matching interface: just pick one */
......@@ -138,18 +138,17 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
dev = dev_get_by_index(ifindex);
if (dev == NULL) {
sock_kfree_s(sk, pac, sizeof(*pac));
return -ENODEV;
err = -ENODEV;
goto out_free_pac;
}
idev = in6_dev_get(dev);
if (!idev) {
sock_kfree_s(sk, pac, sizeof(*pac));
dev_put(dev);
if (ifindex)
return -ENODEV;
err = -ENODEV;
else
return -EADDRNOTAVAIL;
err = -EADDRNOTAVAIL;
goto out_dev_put;
}
/* reset ishost, now that we have a specific device */
ishost = !idev->cnf.forwarding;
......@@ -170,21 +169,17 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
err = -EADDRNOTAVAIL;
else if (!capable(CAP_NET_ADMIN))
err = -EPERM;
if (err) {
sock_kfree_s(sk, pac, sizeof(*pac));
dev_put(dev);
return err;
}
if (err)
goto out_dev_put;
} else if (!(ipv6_addr_type(addr) & IPV6_ADDR_ANYCAST) &&
!capable(CAP_NET_ADMIN))
return -EPERM;
!capable(CAP_NET_ADMIN)) {
err = -EPERM;
goto out_dev_put;
}
err = ipv6_dev_ac_inc(dev, addr);
if (err) {
sock_kfree_s(sk, pac, sizeof(*pac));
dev_put(dev);
return err;
}
if (err)
goto out_dev_put;
write_lock_bh(&ipv6_sk_ac_lock);
pac->acl_next = np->ipv6_ac_list;
......@@ -194,6 +189,12 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
dev_put(dev);
return 0;
out_dev_put:
dev_put(dev);
out_free_pac:
sock_kfree_s(sk, pac, sizeof(*pac));
return err;
}
/*
......
......@@ -441,8 +441,10 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
src_addr = solicited_addr;
in6_ifa_put(ifp);
} else {
if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0)) {
dst_free(dst);
return;
}
src_addr = &tmpaddr;
}
......@@ -450,11 +452,10 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
ndisc_rt_init(rt, dev, neigh);
dst = (struct dst_entry*)rt;
dst_clone(dst);
err = xfrm_lookup(&dst, &fl, NULL, 0);
if (err < 0) {
dst_release(dst);
dst_free(dst);
return;
}
......@@ -470,6 +471,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
if (skb == NULL) {
ND_PRINTK1("send_na: alloc skb failed\n");
dst_free(dst);
return;
}
......
......@@ -127,18 +127,21 @@ static void dbg_kfree(void * v, int line) {
* WAN device IOCTL handlers
*/
static int device_setup(struct wan_device *wandev, wandev_conf_t *u_conf);
static int device_stat(struct wan_device *wandev, wandev_stat_t *u_stat);
static int device_shutdown(struct wan_device *wandev);
static int device_new_if(struct wan_device *wandev, wanif_conf_t *u_conf);
static int device_del_if(struct wan_device *wandev, char *u_name);
static int wanrouter_device_setup(struct wan_device *wandev,
wandev_conf_t *u_conf);
static int wanrouter_device_stat(struct wan_device *wandev,
wandev_stat_t *u_stat);
static int wanrouter_device_shutdown(struct wan_device *wandev);
static int wanrouter_device_new_if(struct wan_device *wandev,
wanif_conf_t *u_conf);
static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name);
/*
* Miscellaneous
*/
static struct wan_device *find_device (char *name);
static int delete_interface (struct wan_device *wandev, char *name);
static struct wan_device *wanrouter_find_device(char *name);
static int wanrouter_delete_interface(struct wan_device *wandev, char *name);
void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
......@@ -148,19 +151,18 @@ void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
* Global Data
*/
static char fullname[] = "Sangoma WANPIPE Router";
static char copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
static char modname[] = ROUTER_NAME; /* short module name */
struct wan_device* router_devlist; /* list of registered devices */
static int devcnt;
static char wanrouter_fullname[] = "Sangoma WANPIPE Router";
static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
static char wanrouter_modname[] = ROUTER_NAME; /* short module name */
struct wan_device* wanrouter_router_devlist; /* list of registered devices */
/*
* Organize Unique Identifiers for encapsulation/decapsulation
*/
static unsigned char oui_ether[] = { 0x00, 0x00, 0x00 };
static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
#if 0
static unsigned char oui_802_2[] = { 0x00, 0x80, 0xC2 };
static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
#endif
#ifndef MODULE
......@@ -172,12 +174,13 @@ int wanrouter_init(void)
extern int sdladrv_init(void);
printk(KERN_INFO "%s v%u.%u %s\n",
fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
wanrouter_copyright);
err = wanrouter_proc_init();
if (err){
printk(KERN_INFO "%s: can't create entry in proc filesystem!\n", modname);
}
if (err)
printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
wanrouter_modname);
/*
* Initialise compiled in boards
......@@ -218,14 +221,14 @@ int init_module (void)
int err;
printk(KERN_INFO "%s v%u.%u %s\n",
fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
wanrouter_copyright);
err = wanrouter_proc_init();
if (err){
printk(KERN_INFO
"%s: can't create entry in proc filesystem!\n", modname);
}
if (err)
printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
wanrouter_modname);
return err;
}
......@@ -274,12 +277,12 @@ int register_wan_device(struct wan_device *wandev)
if (!namelen || (namelen > WAN_DRVNAME_SZ))
return -EINVAL;
if (find_device(wandev->name) != NULL)
if (wanrouter_find_device(wandev->name))
return -EEXIST;
#ifdef WANDEBUG
printk(KERN_INFO "%s: registering WAN device %s\n",
modname, wandev->name);
wanrouter_modname, wandev->name);
#endif
/*
......@@ -289,7 +292,7 @@ int register_wan_device(struct wan_device *wandev)
if (err) {
printk(KERN_INFO
"%s: can't create /proc/net/router/%s entry!\n",
modname, wandev->name);
wanrouter_modname, wandev->name);
return err;
}
......@@ -300,9 +303,8 @@ int register_wan_device(struct wan_device *wandev)
wandev->ndev = 0;
wandev->dev = NULL;
wandev->next = router_devlist;
router_devlist = wandev;
++devcnt;
wandev->next = wanrouter_router_devlist;
wanrouter_router_devlist = wandev;
MOD_INC_USE_COUNT; /* prevent module from unloading */
return 0;
}
......@@ -327,7 +329,7 @@ int unregister_wan_device(char *name)
if (name == NULL)
return -EINVAL;
for (wandev = router_devlist, prev = NULL;
for (wandev = wanrouter_router_devlist, prev = NULL;
wandev && strcmp(wandev->name, name);
prev = wandev, wandev = wandev->next)
;
......@@ -335,18 +337,18 @@ int unregister_wan_device(char *name)
return -ENODEV;
#ifdef WANDEBUG
printk(KERN_INFO "%s: unregistering WAN device %s\n", modname, name);
printk(KERN_INFO "%s: unregistering WAN device %s\n",
wanrouter_modname, name);
#endif
if (wandev->state != WAN_UNCONFIGURED)
device_shutdown(wandev);
wanrouter_device_shutdown(wandev);
if (prev)
prev->next = wandev->next;
else
router_devlist = wandev->next;
wanrouter_router_devlist = wandev->next;
--devcnt;
wanrouter_proc_delete(wandev);
MOD_DEC_USE_COUNT;
return 0;
......@@ -381,14 +383,15 @@ int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
skb_push(skb, 7);
skb->data[0] = 0;
skb->data[1] = NLPID_SNAP;
memcpy(&skb->data[2], oui_ether, sizeof(oui_ether));
memcpy(&skb->data[2], wanrouter_oui_ether,
sizeof(wanrouter_oui_ether));
*((unsigned short*)&skb->data[5]) = htons(type);
break;
default: /* Unknown packet type */
printk(KERN_INFO
"%s: unsupported Ethertype 0x%04X on interface %s!\n",
modname, type, dev->name);
wanrouter_modname, type, dev->name);
hdr_len = -EINVAL;
}
return hdr_len;
......@@ -418,10 +421,11 @@ unsigned short wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
break;
case NLPID_SNAP: /* SNAP encapsulation */
if (memcmp(&skb->data[cnt + 1], oui_ether, sizeof(oui_ether))){
if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,
sizeof(wanrouter_oui_ether))){
printk(KERN_INFO
"%s: unsupported SNAP OUI %02X-%02X-%02X "
"on interface %s!\n", modname,
"on interface %s!\n", wanrouter_modname,
skb->data[cnt+1], skb->data[cnt+2],
skb->data[cnt+3], dev->name);
return 0;
......@@ -435,7 +439,7 @@ unsigned short wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
default:
printk(KERN_INFO
"%s: unsupported NLPID 0x%02X on interface %s!\n",
modname, skb->data[cnt], dev->name);
wanrouter_modname, skb->data[cnt], dev->name);
return 0;
}
skb->protocol = ethertype;
......@@ -475,23 +479,23 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case ROUTER_SETUP:
err = device_setup(wandev, (void*)arg);
err = wanrouter_device_setup(wandev, (void*)arg);
break;
case ROUTER_DOWN:
err = device_shutdown(wandev);
err = wanrouter_device_shutdown(wandev);
break;
case ROUTER_STAT:
err = device_stat(wandev, (void*)arg);
err = wanrouter_device_stat(wandev, (void*)arg);
break;
case ROUTER_IFNEW:
err = device_new_if(wandev, (void*)arg);
err = wanrouter_device_new_if(wandev, (void*)arg);
break;
case ROUTER_IFDEL:
err = device_del_if(wandev, (void*)arg);
err = wanrouter_device_del_if(wandev, (void*)arg);
break;
case ROUTER_IFSTAT:
......@@ -519,7 +523,8 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
* o call driver's setup() entry point
*/
static int device_setup(struct wan_device *wandev, wandev_conf_t *u_conf)
static int wanrouter_device_setup(struct wan_device *wandev,
wandev_conf_t *u_conf)
{
void *data = NULL;
wandev_conf_t *conf;
......@@ -595,7 +600,7 @@ static int device_setup(struct wan_device *wandev, wandev_conf_t *u_conf)
* o call driver's shutdown() entry point
*/
static int device_shutdown(struct wan_device *wandev)
static int wanrouter_device_shutdown(struct wan_device *wandev)
{
struct net_device *dev;
int err=0;
......@@ -606,7 +611,8 @@ static int device_shutdown(struct wan_device *wandev)
printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name);
for (dev = wandev->dev; dev;) {
if ((err=delete_interface(wandev, dev->name)) != 0)
err = wanrouter_delete_interface(wandev, dev->name);
if (err)
return err;
/* The above function deallocates the current dev
* structure. Therefore, we cannot use dev->priv
......@@ -628,7 +634,8 @@ static int device_shutdown(struct wan_device *wandev)
* Get WAN device status & statistics.
*/
static int device_stat(struct wan_device *wandev, wandev_stat_t *u_stat)
static int wanrouter_device_stat(struct wan_device *wandev,
wandev_stat_t *u_stat)
{
wandev_stat_t stat;
......@@ -658,7 +665,8 @@ static int device_stat(struct wan_device *wandev, wandev_stat_t *u_stat)
* o register network interface
*/
static int device_new_if(struct wan_device *wandev, wanif_conf_t *u_conf)
static int wanrouter_device_new_if(struct wan_device *wandev,
wanif_conf_t *u_conf)
{
wanif_conf_t conf;
struct net_device *dev = NULL;
......@@ -718,7 +726,7 @@ static int device_new_if(struct wan_device *wandev, wanif_conf_t *u_conf)
#ifdef WANDEBUG
printk(KERN_INFO "%s: registering interface %s...\n",
modname, dev->name);
wanrouter_modname, dev->name);
#endif
err = register_netdev(dev);
......@@ -775,7 +783,7 @@ static int device_new_if(struct wan_device *wandev, wanif_conf_t *u_conf)
* o copy configuration data to kernel address space
*/
static int device_del_if(struct wan_device *wandev, char *u_name)
static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name)
{
char name[WAN_IFNAME_SZ + 1];
int err = 0;
......@@ -788,7 +796,7 @@ static int device_del_if(struct wan_device *wandev, char *u_name)
if (copy_from_user(name, u_name, WAN_IFNAME_SZ))
return -EFAULT;
err = delete_interface(wandev, name);
err = wanrouter_delete_interface(wandev, name);
if (err)
return err;
......@@ -816,11 +824,12 @@ static int device_del_if(struct wan_device *wandev, char *u_name)
* Return pointer to the WAN device data space or NULL if device not found.
*/
static struct wan_device *find_device(char *name)
static struct wan_device *wanrouter_find_device(char *name)
{
struct wan_device *wandev;
for (wandev = router_devlist;wandev && strcmp(wandev->name, name);
for (wandev = wanrouter_router_devlist;
wandev && strcmp(wandev->name, name);
wandev = wandev->next);
return wandev;
}
......@@ -842,7 +851,7 @@ static struct wan_device *find_device(char *name)
* sure that opened interfaces are not removed!
*/
static int delete_interface(struct wan_device *wandev, char *name)
static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
{
struct net_device *dev = NULL, *prev = NULL;
unsigned long smp_flags=0;
......
......@@ -314,7 +314,7 @@ struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
return pol;
}
void xfrm_policy_flush()
void xfrm_policy_flush(void)
{
struct xfrm_policy *xp;
int dir;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment