add support for iptables version 1.1.1 and 1.1.2 (alpha-state)

for testing the user-space-tools (add-ons for iptables) are in
the i4l-utilitys/isdnctrl directory
This commit is contained in:
Detlef Wengorz 2000-09-10 20:29:18 +00:00
parent 82cf44d24b
commit ad87b5f637
9 changed files with 831 additions and 54 deletions

View File

@ -31,6 +31,20 @@ if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
bool ' Rewrite socket and frame saddr-field (udp-ip4 only and very experimental)' CONFIG_ISDN_WITH_ABC_IPV4_RWUDP_SOCKADDR
fi
bool ' RX dont reset hanguptimeout' CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if [ "$CONFIG_NETFILTER" != "n" ]; then
if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
bool ' Iptables-support (IPV4 kernel >= 2.4.0)' CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
fi
if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then
bool ' Iptables-support (IPV6 kernel >= 2.4.0)' CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
fi
bool ' Iptables_DWISDN target support (kernel >= 2.4.0' CONFIG_ISDN_WITH_ABC_IPT_TARGET
if [ "$CONFIG_ISDN_WITH_ABC_IPT_TARGET" != "n" ]; then
int ' skb->nfmark bit (1-32) for tx without huptime-reset' CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT 25
int ' Bit (1-32) for send icmp-unreach in offline case ' CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT 26
fi
fi
bool ' Support (device-channel)<->(bind-groups)' CONFIG_ISDN_WITH_ABC_ICALL_BIND
bool ' Skip channel if used external (dial only)' CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
bool ' Support interface-auto-disable if config-error' CONFIG_ISDN_WITH_ABC_CONN_ERROR

View File

@ -33,10 +33,38 @@
static char *dwabcrevison = "$Revision$";
#include <asm/semaphore.h>
#define CONFIG_ISDN_WITH_ABC_NEED_DWSJIFFIES 1
#include <linux/isdn.h>
#include "isdn_common.h"
#include "isdn_net.h"
#if CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER || CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#include <linux/module.h>
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#include <linux/netfilter_ipv4/ip_tables.h>
static void dwabcnetfilter_init(void);
static void dwabcnetfilter_fini(void);
#define IPTV6_hook_priorities MYV6_nf_ip_hook_priorities
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#ifdef IPTV6_hook_priorities
/*
** stop compiler warning (redefine of nf_ip_hook_priorities)
*/
#define nf_ip_hook_priorities IPTV6_hook_priorities
#else
#define IPTV6_hook_priorities nf_ip_hook_priorities
#endif
#include <linux/netfilter_ipv6/ip6_tables.h>
static void dwabcv6netfilter_init(void);
static void dwabcv6netfilter_fini(void);
#endif
struct PSH {
u_long saddr;
u_long daddr;
@ -44,9 +72,9 @@ struct PSH {
u_short len;
};
#include <linux/skbuff.h>
#ifdef CONFIG_ISDN_WITH_ABC_IPV4_TCP_KEEPALIVE
#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/tcp.h>
#ifdef CONFIG_ISDN_WITH_ABC_IPV4_DYNADDR
@ -70,7 +98,7 @@ static struct isdn_ppp_comp_data BSD_COMP_INIT_DATA;
#endif
#define NBYTEORDER_30BYTES 0x1e00
#define DWABC_TMRES (HZ)
#define DWABC_TMRES (HZ / 10)
//#define KEEPALIVE_VERBOSE 1
//#define DYNADDR_VERBOSE 1
@ -540,16 +568,18 @@ void isdn_dw_clear_if(ulong pm,isdn_net_local *lp)
static void dw_abc_timer_func(u_long dont_need_yet)
{
static int recu = 0;
register u_long t;
if(!((t = ++isdn_dwabc_jiffies.msec_100) & 1))
if(isdn_dwabc_jiffies.msec_200++ & 1)
isdn_dwabc_jiffies.msec_400++;
if(!(t % 5))
if(isdn_dwabc_jiffies.msec_500++ & 1)
isdn_dwabc_jiffies.msec_1000++;
dw_abc_timer.expires = jiffies + DWABC_TMRES;
add_timer(&dw_abc_timer);
dwsjiffies++;
if(test_and_set_bit(0,&recu))
return;
clear_bit(0,&recu);
}
@ -1345,8 +1375,9 @@ void isdn_dw_abc_init_func(void)
init_timer(&dw_abc_timer);
dw_abc_timer.function = dw_abc_timer_func;
printk( KERN_INFO
"abc-extension %s\n"
"abc-extension %s Kernel 0x%06X\n"
"written by\nDetlef Wengorz <detlefw@isdn4linux.de>\n"
"Thanks for test's etc. to:\n"
"Mario Schugowski <mario@mediatronix.de>\n"
@ -1393,17 +1424,35 @@ void isdn_dw_abc_init_func(void)
#endif
#ifdef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
"CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS\n"
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
"CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER\n"
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
"CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER\n"
#endif
"loaded\n",
dwabcrevison);
dwabcrevison,LINUX_VERSION_CODE);
dwsjiffies = 0;
dw_abc_timer.expires = jiffies + DWABC_TMRES;
add_timer(&dw_abc_timer);
#ifdef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
dwabcnetfilter_init();
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
dwabcv6netfilter_init();
#endif
}
void isdn_dw_abc_release_func(void)
{
#ifdef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
dwabcnetfilter_fini();
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
dwabcv6netfilter_fini();
#endif
del_timer(&dw_abc_timer);
#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
dw_lcr_clear_all();
@ -1412,14 +1461,14 @@ void isdn_dw_abc_release_func(void)
isdn_tcp_keepalive_done();
#endif
printk( KERN_INFO
"abc-extension %s\n"
"abc-extension %s Kernel 0x%06X\n"
"written by\n"
"Detlef Wengorz <detlefw@isdn4linux.de>\n"
"Thanks for test's etc. to:\n"
"Mario Schugowski <mario@mediatronix.de>\n"
"unloaded\n"
"For more details see http://i4l.mediatronix.de\n",
dwabcrevison);
dwabcrevison,LINUX_VERSION_CODE);
}
@ -2274,4 +2323,565 @@ struct sk_buff *dwabc_bsd_compress(isdn_net_local *lp,struct sk_buff *skb,struct
struct sk_buff *dwabc_bsd_rx_pkt(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev)
{ return(skb); }
#endif
#if CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER || CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
static isdn_net_local *dwisdn_get_lp(const struct net_device *nd)
{
isdn_net_local *r = NULL;
if(nd != NULL) {
isdn_net_dev *p = dev->netdev;
int shl = 0;
for(;shl < 5000 && p != NULL && &p->dev != nd;shl++,p = p->next);
if(p != NULL && nd == &p->dev)
r = p->local;
}
return(r);
}
static int isdn_ipt_dwisdn( const struct net_device *in_ndev,
const struct net_device *out_ndev,
const void *info)
{
int retw = 0;
if(info != NULL) {
int shl = 0;
const IPTDWISDN_INFO *dw = (IPTDWISDN_INFO *)info;
isdn_net_local *lp = NULL;
if(dw->parcount > 0 &&
(*dw->inst & ~IPT_DWISDN_NOT) == IPT_DWISDN_IDEV) {
if(*dw->inst & IPT_DWISDN_NOT)
lp = dwisdn_get_lp(out_ndev);
else
lp = dwisdn_get_lp(in_ndev);
shl = 1;
} else lp = dwisdn_get_lp(out_ndev);
retw = lp != NULL;
for(;retw && shl < IPTDWISDN_MAXOPS && shl < dw->parcount; shl++) {
enum iptdwisdn inst = dw->inst[shl];
u_long v = dw->value[shl];
int not;
if((not = (inst & IPT_DWISDN_NOT)))
inst &= ~IPT_DWISDN_NOT;
switch(inst) {
default:
printk(KERN_DEBUG
"ipt_dwisdn instruction %0x unknown\n",inst);
retw = 0;
break;
case IPT_DWISDN_DIALMODE:
retw = 0;
switch(v) {
case 1:
retw = ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO;
break;
case 2:
retw = ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_MANUAL;
break;
case 3:
retw = ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF;
break;
}
break;
case IPT_DWISDN_CBOUT:
retw = 0;
if(lp->flags & ISDN_NET_CALLBACK) {
retw = !!(lp->flags & ISDN_NET_CBOUT);
if(not)
retw = !retw;
}
continue;
case IPT_DWISDN_OUTGOING:
if(lp->flags & ISDN_NET_CONNECTED)
retw = !!lp->outgoing;
else
retw = 0;
break;
case IPT_DWISDN_IDEV:
if(not)
lp = dwisdn_get_lp(out_ndev);
else
lp = dwisdn_get_lp(in_ndev);
retw = lp != NULL;
continue;
case IPT_DWISDN_CHARGE:
retw = lp->charge >= v;
break;
case IPT_DWISDN_CON:
retw = 0;
if(v & IPTCS_DWISN_OFFL) {
if(!(lp->flags & ISDN_NET_CONNECTED) &&
!lp->dialstate) {
retw = 1;
}
}
if(v & IPTCS_DWISN_ONL) {
if((lp->flags & ISDN_NET_CONNECTED) &&
!lp->dialstate) {
retw = 1;
}
}
if(v & IPTCS_DWISN_DIAL) {
if((lp->flags & ISDN_NET_CONNECTED) &&
lp->dialstate) {
retw = 1;
}
}
break;
}
if(not)
retw = !retw;
}
}
return(retw);
}
static int dwisdn_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)
/************************************************************************
*************************************************************************/
{
const IPTDWISDN_INFO *dw = matchinfo;
if(dw == NULL)
return(0);
return(isdn_ipt_dwisdn(in,out,dw));
}
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
static unsigned int DWISDN_target(
struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
const void *info,
void *userinfo)
{
unsigned int retw = IPT_CONTINUE;
if(info != NULL) {
int shl = 0;
const IPTDWISDN_INFO *dw = (IPTDWISDN_INFO *)info;
isdn_net_local *lp = dwisdn_get_lp(out);
struct sk_buff *p = (pskb != NULL) ? *pskb : NULL;
for(shl = 0;shl < IPTDWISDN_MAXOPS && shl < dw->parcount; shl++) {
enum tiptdwisdn inst = dw->inst[shl];
u_long v = dw->value[shl];
int not;
if((not = (inst & TIPT_DWISDN_NOT)))
inst &= ~TIPT_DWISDN_NOT;
switch(inst) {
default:
printk(KERN_DEBUG
"ipt_DWISDN instruction %0x unknown\n",inst);
break;
case TIPT_DWISDN_HUPRESET:
if(lp != NULL)
lp->huptimer = 0;
break;
case TIPT_DWISDN_DIALMODE:
if(lp != NULL) {
/* first all bits off */
lp->flags &= ~ISDN_NET_DIALMODE_MASK;
switch(v) {
case 1: lp->flags |= ISDN_NET_DM_AUTO; break;
case 2: lp->flags |= ISDN_NET_DM_MANUAL; break;
case 3: lp->flags |= ISDN_NET_DM_OFF; break;
}
}
break;
case TIPT_DWISDN_HANGUP:
if(lp != NULL && (lp->flags & ISDN_NET_CONNECTED))
isdn_net_hangup(&lp->netdev->dev);
break;
case TIPT_DWISDN_DIAL:
if(lp != NULL && !(lp->flags & ISDN_NET_CONNECTED))
isdn_net_force_dial_lp(lp);
break;
case TIPT_DWISDN_IDEV:
lp = dwisdn_get_lp((not) ? out : in);
break;
case TIPT_DWISDN_CLEAR:
v = 0;
if( CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT < 33 ) {
v |= (1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT -1));
}
if( CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT < 33 ) {
v |= (1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT -1));
}
if(p != NULL && (p->nfmark & v)) {
p->nfmark &= ~v;
p->nfcache |= NFC_ALTERED;
}
break;
case TIPT_DWISDN_SET:
v = 0;
if( CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT < 33 ) {
v |= (1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT -1));
}
if(p != NULL && (p->nfmark & v) != v) {
p->nfmark |= v;
p->nfcache |= NFC_ALTERED;
}
break;
case TIPT_DWISDN_UNREACH:
v = 0;
if( CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT < 33 ) {
v |= (1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT -1));
}
if(p != NULL && (p->nfmark & v) != v) {
p->nfmark |= v;
p->nfcache |= NFC_ALTERED;
}
break;
}
}
}
return(retw);
}
#endif
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
static int dwisdn_checkentry( const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
const IPTDWISDN_INFO *dw = matchinfo;
if (matchsize != IPT_ALIGN(sizeof(IPTDWISDN_INFO))) {
printk(KERN_WARNING
"ipt_dwisdn: sizeof(IPTDWISDN_INFO) wrong (I think wrong Version)\n");
return 0;
}
if(dw != NULL && dw->revision > IPTDWISDN_REVISION) {
printk(KERN_WARNING
"ipt_dwisdn: iptables-revison > kernel-revision (%hu/%hu)\n",
dw->revision,IPTDWISDN_REVISION);
return 0;
}
return(1);
}
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
static int DWISDN_checkentry( const char *tablename,
const struct ipt_entry *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
const IPTDWISDN_INFO *dt = targinfo;
if (targinfosize != IPT_ALIGN(sizeof(IPTDWISDN_INFO))) {
printk(KERN_WARNING
"ipt_DWISDN: sizeof(IPTDWISDN_INFO) wrong (I think wrong Version)\n");
return 0;
}
if(dt != NULL && dt->revision > IPTDWISDN_REVISION) {
printk(KERN_WARNING
"ipt_DWISDN: iptables-revison > kernel-revision (%hu/%hu)\n",
dt->revision,IPTDWISDN_REVISION);
return 0;
}
return 1;
}
static struct ipt_target ipt_DWISDN = {
{ NULL, NULL },
"DWISDN",
DWISDN_target,
DWISDN_checkentry,
NULL, THIS_MODULE,
};
#endif
static struct ipt_match ipt_dwisdn = {
{ NULL, NULL },
"dwisdn",
dwisdn_match,
dwisdn_checkentry,
NULL, THIS_MODULE
};
static void dwabcnetfilter_init(void)
{
int r = ipt_register_match(&ipt_dwisdn);
if(!r)
printk(KERN_WARNING "ipt_dwisdn: isdn-ipv4-netfilter installed\n");
else
printk(KERN_WARNING
"ipt_dwisdn: isdn-ipv4-netfilter install failed (%d)\n",r);
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
r = ipt_register_target(&ipt_DWISDN);
if(!r)
printk(KERN_WARNING "ipt_DWISDN: isdn-ipv4-netfilter installed\n");
else
printk(KERN_WARNING
"ipt_DWISDN: isdn-ipv4-netfilter install failed (%d)\n",r);
#endif
}
static void dwabcnetfilter_fini(void)
{
ipt_unregister_match(&ipt_dwisdn);
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
ipt_unregister_target(&ipt_DWISDN);
#endif
}
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
static int dwisdn_checkentry_v6( const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
const IPTDWISDN_INFO *dw = matchinfo;
if (matchsize != IP6T_ALIGN(sizeof(IPTDWISDN_INFO))) {
printk(KERN_WARNING
"ipt_dwisdn: sizeof(IPTDWISDN_INFO) wrong (I think wrong Version)\n");
return 0;
}
if(dw != NULL && dw->revision > IPTDWISDN_REVISION) {
printk(KERN_WARNING
"ipt_dwisdn: iptables-revison > kernel-revision (%hu/%hu)\n",
dw->revision,IPTDWISDN_REVISION);
return 0;
}
return(1);
}
static struct ip6t_match ip6t_dwisdn = {
{ NULL, NULL },
"dwisdn",
dwisdn_match,
dwisdn_checkentry_v6,
NULL, THIS_MODULE
};
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
static int DWISDN_checkentry_v6(
const char *tablename,
const struct ip6t_entry *ip,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
const IPTDWISDN_INFO *dt = targinfo;
if (targinfosize != IP6T_ALIGN(sizeof(IPTDWISDN_INFO))) {
printk(KERN_WARNING
"ipt_DWISDN: sizeof(IPTDWISDN_INFO) wrong (I think wrong Version)\n");
return 0;
}
if(dt != NULL && dt->revision > IPTDWISDN_REVISION) {
printk(KERN_WARNING
"ipt_DWISDN: iptables-revison > kernel-revision (%hu/%hu)\n",
dt->revision,IPTDWISDN_REVISION);
return 0;
}
return 1;
}
static struct ip6t_target ip6t_DWISDN = {
{ NULL, NULL },
"DWISDN",
DWISDN_target,
DWISDN_checkentry_v6,
NULL, THIS_MODULE,
};
#endif
static void dwabcv6netfilter_init(void)
{
int r = ip6t_register_match(&ip6t_dwisdn);
if(!r)
printk(KERN_WARNING "ipt_dwisdn: isdn-ipv6-netfilter installed\n");
else
printk(KERN_WARNING
"ipt_dwisdn: isdn-ipv6-netfilter install failed (%d)\n",r);
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
r = ip6t_register_target(&ip6t_DWISDN);
if(!r)
printk(KERN_WARNING "ipt_DWISDN: isdn-ipv6-netfilter installed\n");
else
printk(KERN_WARNING
"ipt_DWISDN: isdn-ipv6-netfilter install failed (%d)\n",r);
#endif
}
static void dwabcv6netfilter_fini(void)
{
ip6t_unregister_match(&ip6t_dwisdn);
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
ip6t_unregister_target(&ip6t_DWISDN);
#endif
}
#endif
#endif

View File

@ -1416,6 +1416,15 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
isdn_net_local *slp;
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
int retv = 0;
#if CONFIG_ISDN_WITH_ABC && CONFIG_ISDN_WITH_ABC_IPT_TARGET
ulong old_huptimer = lp->huptimer;
short d_reset_frame =
skb != NULL &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT < 33 &&
(skb->nfmark & ( 1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT - 1)));
#endif
if (((isdn_net_local *) (ndev->priv))->master) {
printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
@ -1426,12 +1435,19 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
/* For the other encaps the header has already been built */
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
#if CONFIG_ISDN_WITH_ABC && CONFIG_ISDN_WITH_ABC_IPT_TARGET
int r = isdn_ppp_xmit(skb, ndev);
if(d_reset_frame)
lp->huptimer = old_huptimer;
return(r);
#else
return isdn_ppp_xmit(skb, ndev);
#endif
}
#endif
nd = ((isdn_net_local *) ndev->priv)->netdev;
lp = isdn_net_get_locked_lp(nd);
if (!lp) {
printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
@ -1442,6 +1458,10 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
/* Reset hangup-timeout */
lp->huptimer = 0; // FIXME?
#ifdef CONFIG_ISDN_WITH_ABC
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
if(d_reset_frame)
lp->huptimer = old_huptimer;
#endif
#ifdef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
if( (lp->dw_abc_flags & ISDN_DW_ABC_FLAG_LEASED_LINE) &&
(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS) &&
@ -1451,7 +1471,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
dwabc_bsd_first_gen(lp);
}
#endif
{
struct sk_buff *t_skb = NULL;
@ -1755,6 +1775,25 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
#endif
if (!(lp->flags & ISDN_NET_CONNECTED)) {
int chi;
#ifdef CONFIG_ISDN_WITH_ABC
#ifdef CONFIG_ISDN_WITH_ABC_IPT_TARGET
if( CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT < 33 &&
(skb->nfmark & ( 1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_HBIT - 1)))) {
if( CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT > 0 &&
CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT < 33 &&
(skb->nfmark & ( 1lu << (CONFIG_ISDN_WITH_ABC_IPT_TARGET_DBIT - 1)))) {
isdn_net_unreachable(ndev, skb,
"dial rejected: Iptables_DWISDN --hutimer --unreach");
}
dev_kfree_skb(skb);
return 0;
}
#endif
#endif
/* only do autodial if allowed by config */
if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
@ -2081,6 +2120,10 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
#endif
#ifdef CONFIG_ISDN_WITH_ABC
struct net_device *ondev = ndev;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
ulong lp_huptimer = 0;
ulong olp_huptimer = 0;
#endif
#endif
cisco_hdr *ch;
@ -2097,7 +2140,10 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
lp->stats.rx_packets++;
lp->stats.rx_bytes += skb->len;
}
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
lp_huptimer = lp->huptimer;
olp_huptimer = olp->huptimer;
#endif
skb->dev = ndev;
skb->pkt_type = PACKET_HOST;
skb->mac.raw = skb->data;
@ -2107,26 +2153,14 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
switch (lp->p_encap) {
case ISDN_NET_ENCAP_ETHER:
/* Ethernet over ISDN */
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(!(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER)) {
#endif
olp->huptimer = 0;
lp->huptimer = 0;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
}
#endif
skb->protocol = isdn_net_type_trans(skb, ndev);
break;
case ISDN_NET_ENCAP_UIHDLC:
/* HDLC with UI-frame (for ispa with -h1 option) */
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(!(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER)) {
#endif
olp->huptimer = 0;
lp->huptimer = 0;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
}
#endif
skb_pull(skb, 2);
/* Fall through */
case ISDN_NET_ENCAP_RAWIP:
@ -2157,15 +2191,9 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
lp->stats.rx_bytes += skb->len - l;
}
}
#endif
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(!(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER)) {
#endif
olp->huptimer = 0;
lp->huptimer = 0;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
}
#endif
skb->protocol = htons(ETH_P_IP);
#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
if(isdn_dwabc_conerr_ippktok(skb))
@ -2216,14 +2244,8 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
/* Fall through */
case ISDN_NET_ENCAP_IPTYP:
/* IP with type field */
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(!(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER)) {
#endif
olp->huptimer = 0;
lp->huptimer = 0;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
}
#endif
skb->protocol = *(unsigned short *) &(skb->data[0]);
skb_pull(skb, 2);
if (*(unsigned short *) skb->data == 0xFFFF)
@ -2236,18 +2258,20 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
* huptimer on LCP packets.
*/
if (proto != PPP_LCP) {
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(!(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER)) {
#endif
olp->huptimer = 0;
lp->huptimer = 0;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
}
#endif
}
isdn_ppp_receive(lp->netdev, olp, skb);
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER) {
lp->huptimer = lp_huptimer + 1;
olp->huptimer = olp_huptimer+ 1;
}
#endif
return;
#endif
default:
#ifdef CONFIG_ISDN_X25
/* try if there are generic sync_device receiver routines */
@ -2256,6 +2280,12 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
cprot -> pops -> data_ind(cprot,skb);
#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
lp->dw_abc_bchan_errcnt = 0;
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER) {
lp->huptimer = lp_huptimer;
olp->huptimer = olp_huptimer;
}
#endif
#endif
return;
};
@ -2266,9 +2296,17 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
return;
}
#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
if(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER) {
lp->huptimer = lp_huptimer;
olp->huptimer = olp_huptimer;
}
#endif
#ifdef CONFIG_ISDN_WITH_ABC_IPV4_TCP_KEEPALIVE
if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_TCP_KEEPALIVE))
(void)isdn_dw_abc_ip4_keepalive_test(NULL,skb);
#endif
#endif
netif_rx(skb);
return;

View File

@ -70,10 +70,36 @@
#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
#undef CONFIG_ISDN_WITH_ABC_IPV4_RW_SOCKADDR
#undef CONFIG_ISDN_WITH_ABC_IPV4_RWUDP_SOCKADDR
#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPT_TARGET
#else
#include <linux/isdn_dwabc.h>
volatile u_long dwsjiffies;
#ifndef CONFIG_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#endif
#ifdef __KERNEL__
typedef struct DWABCJIFFIES {
u_long msec_1000;
u_long msec_500;
u_long msec_400;
u_long msec_200;
u_long msec_100;
} DWABCJIFFIES;
#ifdef CONFIG_ISDN_WITH_ABC_NEED_DWSJIFFIES
DWABCJIFFIES isdn_dwabc_jiffies;
#else
extern DWABCJIFFIES isdn_dwabc_jiffies;
#endif
#define dwsjiffies (isdn_dwabc_jiffies.msec_1000)
#endif
#define ISDN_DW_ABC_FLAG_NO_TCP_KEEPALIVE 0x00000001L
#define ISDN_DW_ABC_FLAG_NO_UDP_CHECK 0x00000002L
#define ISDN_DW_ABC_FLAG_NO_UDP_HANGUP 0x00000004L
@ -88,13 +114,13 @@ volatile u_long dwsjiffies;
#define ISDN_DW_ABC_FLAG_RWUDP_SOCKADDR 0x00000800L
#define ISDN_DW_ABC_FLAG_LEASED_LINE 0x00001000L
#define ISDN_DW_ABC_IFFLAG_NODCHAN 0x00000001L
#define ISDN_DW_ABC_IFFLAG_BSDAKTIV 0x00000002L
#define ISDN_DW_ABC_IFFLAG_NODCHAN 0x00000001L
#define ISDN_DW_ABC_IFFLAG_BSDAKTIV 0x00000002L
#define ISDN_DW_ABC_BITLOCK_SEND 0
#define ISDN_DW_ABC_BITLOCK_RECEIVE 1
#define ISDN_DW_ABC_BITLOCK_SEND 0
#define ISDN_DW_ABC_BITLOCK_RECEIVE 1
#define ISDN_DW_ABC_MAX_CH_P_RIVER (32)
#define ISDN_DW_ABC_MAX_CH_P_RIVER (32)
#endif

View File

@ -42,7 +42,84 @@ struct ISDN_DWABC_LCR_IOCTL {
u_long lcr_ioctl_callid; /* callid from lcr-subsystem */
u_long lcr_ioctl_flags; /* see above */
char lcr_ioctl_nr[32]; /* new destination phonenumber */
};
enum iptdwisdn {
IPT_DWISDN_NOT = 0x800,
IPT_DWISDN_CON = 1,
IPT_DWISDN_IDEV = 2,
IPT_DWISDN_CHARGE = 3,
IPT_DWISDN_OUTGOING = 4,
IPT_DWISDN_CBOUT = 5,
IPT_DWISDN_DIALMODE = 6,
};
enum iptdwisdn_constat {
IPTCS_DWISN_OFFL = 0x01,
IPTCS_DWISN_ONL = 0x02,
IPTCS_DWISN_DIAL = 0x04,
};
enum tiptdwisdn {
TIPT_DWISDN_NOT = 0x800,
TIPT_DWISDN_CLEAR = 1,
TIPT_DWISDN_SET = 2,
TIPT_DWISDN_DIAL = 3,
TIPT_DWISDN_HANGUP = 4,
TIPT_DWISDN_IDEV = 5,
TIPT_DWISDN_DIALMODE = 6,
TIPT_DWISDN_UNREACH = 7,
TIPT_DWISDN_HUPRESET = 8,
};
#ifdef IPT_ISDN_DWISDN_H_NEED_OPTS
#include <getopt.h>
static struct option IPT_dwisdn_opts[] = {
{"con_stat", 1,0,IPT_DWISDN_CON },
{"in_dev", 0,0,IPT_DWISDN_IDEV },
{"charge", 1,0,IPT_DWISDN_CHARGE },
{"outgoing", 0,0,IPT_DWISDN_OUTGOING },
{"cbout", 0,0,IPT_DWISDN_CBOUT },
{"dialmode", 1,0,IPT_DWISDN_DIALMODE },
{0},
};
#define IPTDWISDN_ANZOPS ((sizeof(IPT_dwisdn_opts)/sizeof(*IPT_dwisdn_opts))-1)
#endif
#ifdef IPT_ISDN_DWISDN_TIPTH_NEED_OPTS
#include <getopt.h>
static struct option TIPT_dwisdn_opts[] = {
{"clear", 0,0,TIPT_DWISDN_CLEAR },
{"huptimer", 0,0,TIPT_DWISDN_SET },
{"dial", 0,0,TIPT_DWISDN_DIAL },
{"hangup", 0,0,TIPT_DWISDN_HANGUP },
{"in_dev", 0,0,TIPT_DWISDN_IDEV },
{"dialmode", 1,0,TIPT_DWISDN_DIALMODE },
{"unreach", 0,0,TIPT_DWISDN_UNREACH },
{"hupreset", 0,0,TIPT_DWISDN_HUPRESET },
{0},
};
#define IPTDWISDN_ANZOPS ((sizeof(IPT_dwisdn_opts)/sizeof(*IPT_dwisdn_opts))-1)
#endif
#define IPTDWISDN_MAXOPS 16
#define IPTDWISDN_REVISION (u_short)2
typedef struct IPTDWISDN_INFO {
u_short revision;
u_short parcount;
u_char inst[IPTDWISDN_MAXOPS];
u_long value[IPTDWISDN_MAXOPS];
} IPTDWISDN_INFO;
#endif

View File

@ -46,6 +46,9 @@
#undef CONFIG_ISDN_WITH_ABC_CONN_ERROR
#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
#undef CONFIG_ISDN_WITH_ABC_FRAME_LIMIT
#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPT_TARGET
#undef ISDN_NEW_TBUSY
#delete #define ISDN_NEW_TBUSY
#define COMPAT_NO_SOFTNET

View File

@ -53,6 +53,9 @@
#undef CONFIG_ISDN_WITH_ABC_CONN_ERROR
#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
#undef CONFIG_ISDN_WITH_ABC_FRAME_LIMIT
#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPT_TARGET
#define COMPAT_NO_SOFTNET
#undef HAVE_DEVFS_FS
#define devfs_register_chrdev(m,n,f) register_chrdev(m,n,f)

View File

@ -48,6 +48,9 @@
#undef CONFIG_ISDN_WITH_ABC_CONN_ERROR
#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
#undef CONFIG_ISDN_WITH_ABC_FRAME_LIMIT
#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPT_TARGET
#define BIG_PHONE_NUMBERS
#undef COMPAT_NO_SOFTNET
#define HAVE_DEVFS_FS

View File

@ -48,6 +48,9 @@
#undef CONFIG_ISDN_WITH_ABC_CONN_ERROR
#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
#undef CONFIG_ISDN_WITH_ABC_FRAME_LIMIT
#undef CONFIG_ISDN_WITH_ABC_IPTABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPV6TABLES_NETFILTER
#undef CONFIG_ISDN_WITH_ABC_IPT_TARGET
#define BIG_PHONE_NUMBERS
#undef COMPAT_NO_SOFTNET
#define HAVE_DEVFS_FS