Dynamic Timeout-Rule-Handling vs. 971110 included
This commit is contained in:
parent
9d9814cd49
commit
0c64f33f52
|
@ -7,6 +7,11 @@ if [ "$CONFIG_INET" != "n" ]; then
|
||||||
bool 'Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
|
bool 'Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
|
||||||
bool 'Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
|
bool 'Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
|
||||||
fi
|
fi
|
||||||
|
bool 'Support dynamic timeout-rules' CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
if [ "$CONFIG_ISDN_TIMEOUT_RULES" != "n" ]; then
|
||||||
|
bool 'Use masqueraded addresses for rule-matching' CONFIG_ISDN_TIMRU_USE_MASQ
|
||||||
|
fi
|
||||||
|
bool 'Support budget-accounting' CONFIG_ISDN_BUDGET
|
||||||
fi
|
fi
|
||||||
bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO
|
bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO
|
||||||
if [ "$CONFIG_X25" != "n" ]; then
|
if [ "$CONFIG_X25" != "n" ]; then
|
||||||
|
|
|
@ -25,6 +25,12 @@ ifeq ($(CONFIG_ISDN),y)
|
||||||
ifdef CONFIG_ISDN_AUDIO
|
ifdef CONFIG_ISDN_AUDIO
|
||||||
L_OBJS += isdn_audio.o
|
L_OBJS += isdn_audio.o
|
||||||
endif
|
endif
|
||||||
|
ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
L_OBJS += isdn_timru.o
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_ISDN_BUDGET
|
||||||
|
L_OBJS += isdn_budget.o
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
ifeq ($(CONFIG_ISDN),m)
|
ifeq ($(CONFIG_ISDN),m)
|
||||||
M_OBJS += isdn.o
|
M_OBJS += isdn.o
|
||||||
|
@ -41,6 +47,12 @@ else
|
||||||
ifdef CONFIG_ISDN_AUDIO
|
ifdef CONFIG_ISDN_AUDIO
|
||||||
O_OBJS += isdn_audio.o
|
O_OBJS += isdn_audio.o
|
||||||
endif
|
endif
|
||||||
|
ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
O_OBJS += isdn_timru.o
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_ISDN_BUDGET
|
||||||
|
O_OBJS += isdn_budget.o
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/* isdn_budget.c
|
||||||
|
*
|
||||||
|
* Linux ISDN subsystem, budget-accounting for network interfaces.
|
||||||
|
*
|
||||||
|
* Copyright 1997 by Christian Lademann <cal@zls.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
30.06.97:cal:angelegt
|
||||||
|
04.11.97:cal:budget.period: int --> time_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
#define __NO_VERSION__
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/isdn.h>
|
||||||
|
#include "isdn_common.h"
|
||||||
|
#include "isdn_net.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
|
||||||
|
#define VERBOSE_PRINTK(v, l, p...) { \
|
||||||
|
if(dev->net_verbose >= (v)) { \
|
||||||
|
printk(l ## p); \
|
||||||
|
} else { ; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_net_budget(int type, struct device *ndev) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case ISDN_BUDGET_INIT:
|
||||||
|
for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) {
|
||||||
|
lp->budget [i] .amount = -1;
|
||||||
|
lp->budget [i] .used = 0;
|
||||||
|
lp->budget [i] .period = (time_t)0;
|
||||||
|
lp->budget [i] .period_started = (time_t)0;
|
||||||
|
lp->budget [i] .last_check = CURRENT_TIME;
|
||||||
|
lp->budget [i] .notified = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_CHECK_DIAL:
|
||||||
|
case ISDN_BUDGET_CHECK_CHARGE:
|
||||||
|
case ISDN_BUDGET_CHECK_ONLINE:
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) {
|
||||||
|
if(lp->budget [i] .amount < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(lp->budget [i] .period_started + lp->budget [i] .period < CURRENT_TIME) {
|
||||||
|
lp->budget [i] .used = 0;
|
||||||
|
lp->budget [i] .period_started = CURRENT_TIME;
|
||||||
|
lp->budget [i] .notified = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lp->budget [i] .used >= lp->budget [i] .amount)
|
||||||
|
ret |= (1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case ISDN_BUDGET_CHECK_DIAL:
|
||||||
|
if(! ret) {
|
||||||
|
lp->budget [ISDN_BUDGET_DIAL] .used++;
|
||||||
|
lp->budget [ISDN_BUDGET_DIAL] .last_check = CURRENT_TIME;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_CHECK_CHARGE:
|
||||||
|
lp->budget [ISDN_BUDGET_CHARGE] .used++;
|
||||||
|
lp->budget [ISDN_BUDGET_CHARGE] .last_check = CURRENT_TIME;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_CHECK_ONLINE:
|
||||||
|
if(lp->budget [ISDN_BUDGET_ONLINE] .last_check) {
|
||||||
|
lp->budget [ISDN_BUDGET_ONLINE] .used += (CURRENT_TIME - lp->budget [ISDN_BUDGET_ONLINE] .last_check);
|
||||||
|
}
|
||||||
|
|
||||||
|
lp->budget [ISDN_BUDGET_ONLINE] .last_check = CURRENT_TIME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(ret)
|
||||||
|
lp->flags |= ISDN_NET_STOPPED;
|
||||||
|
*/
|
||||||
|
for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) {
|
||||||
|
if(ret & (1 << i) && ! lp->budget [i] .notified) {
|
||||||
|
switch(i) {
|
||||||
|
case ISDN_BUDGET_DIAL:
|
||||||
|
printk(KERN_WARNING "isdn_budget: dial budget used up.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_CHARGE:
|
||||||
|
printk(KERN_WARNING "isdn_budget: charge budget used up.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_ONLINE:
|
||||||
|
printk(KERN_WARNING "isdn_budget: online budget used up.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printk(KERN_WARNING "isdn_budget: budget #%d used up.\n", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lp->budget [i] .notified = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_START_ONLINE:
|
||||||
|
lp->budget [ISDN_BUDGET_ONLINE] .last_check = CURRENT_TIME;
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_budget_ioctl(isdn_ioctl_budget *iocmd) {
|
||||||
|
isdn_net_dev *p = isdn_net_findif(iocmd->name);
|
||||||
|
|
||||||
|
if(p) {
|
||||||
|
switch(iocmd->command) {
|
||||||
|
case ISDN_BUDGET_SET_BUDGET:
|
||||||
|
if(! suser())
|
||||||
|
return(-EPERM);
|
||||||
|
|
||||||
|
if(iocmd->budget < 0 || iocmd->budget > ISDN_BUDGET_NUM_BUDGET)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
if(iocmd->amount < 0)
|
||||||
|
iocmd->amount = -1;
|
||||||
|
|
||||||
|
p->local->budget [iocmd->budget] .amount = iocmd->amount;
|
||||||
|
p->local->budget [iocmd->budget] .period = iocmd->period;
|
||||||
|
|
||||||
|
if(iocmd->used <= 0)
|
||||||
|
p->local->budget [iocmd->budget] .used = 0;
|
||||||
|
else
|
||||||
|
p->local->budget [iocmd->budget] .used = iocmd->used;
|
||||||
|
|
||||||
|
if(iocmd->period_started == (time_t)0)
|
||||||
|
p->local->budget [iocmd->budget] .period_started = CURRENT_TIME;
|
||||||
|
else
|
||||||
|
p->local->budget [iocmd->budget] .period_started = iocmd->period_started;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_BUDGET_GET_BUDGET:
|
||||||
|
if(iocmd->budget < 0 || iocmd->budget > ISDN_BUDGET_NUM_BUDGET)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
iocmd->amount = p->local->budget [iocmd->budget] .amount;
|
||||||
|
iocmd->used = p->local->budget [iocmd->budget] .used;
|
||||||
|
iocmd->period = p->local->budget [iocmd->budget] .period;
|
||||||
|
iocmd->period_started = p->local->budget [iocmd->budget] .period_started;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return(-EINVAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(-ENODEV);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -21,6 +21,9 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.56 1998/02/25 17:49:38 he
|
||||||
|
* Changed return codes caused be failing copy_{to,from}_user to -EFAULT
|
||||||
|
*
|
||||||
* Revision 1.55 1998/02/23 23:35:32 fritz
|
* Revision 1.55 1998/02/23 23:35:32 fritz
|
||||||
* Eliminated some compiler warnings.
|
* Eliminated some compiler warnings.
|
||||||
*
|
*
|
||||||
|
@ -295,7 +298,7 @@ isdn_MOD_DEC_USE_COUNT(void)
|
||||||
MOD_DEC_USE_COUNT;
|
MOD_DEC_USE_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
|
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) || defined(CONFIG_ISDN_TIMEOUT_RULES)
|
||||||
void
|
void
|
||||||
isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
|
isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
|
||||||
{
|
{
|
||||||
|
@ -1273,6 +1276,12 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
|
||||||
isdn_ioctl_struct iocts;
|
isdn_ioctl_struct iocts;
|
||||||
isdn_net_ioctl_phone phone;
|
isdn_net_ioctl_phone phone;
|
||||||
isdn_net_ioctl_cfg cfg;
|
isdn_net_ioctl_cfg cfg;
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
isdn_ioctl_timeout_rule timru;
|
||||||
|
#endif /* CONFIG_ISDN_TIMEOUT_RULES */
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
isdn_ioctl_budget budget;
|
||||||
|
#endif /* CONFIG_ISDN_BUDGET */
|
||||||
} iocpar;
|
} iocpar;
|
||||||
|
|
||||||
#define name iocpar.name
|
#define name iocpar.name
|
||||||
|
@ -1280,6 +1289,13 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
|
||||||
#define iocts iocpar.iocts
|
#define iocts iocpar.iocts
|
||||||
#define phone iocpar.phone
|
#define phone iocpar.phone
|
||||||
#define cfg iocpar.cfg
|
#define cfg iocpar.cfg
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
# define timru iocpar.timru
|
||||||
|
#endif /* CONFIG_ISDN_TIMEOUT_RULES */
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
# define budget iocpar.budget
|
||||||
|
#endif /* CONFIG_ISDN_BUDGET */
|
||||||
|
|
||||||
|
|
||||||
if (minor == ISDN_MINOR_STATUS) {
|
if (minor == ISDN_MINOR_STATUS) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
@ -1429,6 +1445,57 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return isdn_net_force_hangup(name);
|
return isdn_net_force_hangup(name);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
case IIOCNETARU:
|
||||||
|
/* Add a rule to a network-interface */
|
||||||
|
if (arg) {
|
||||||
|
if((ret = copy_from_user((char *) &timru, (char *) arg, sizeof(timru))))
|
||||||
|
return(ret);
|
||||||
|
return(isdn_timru_ioctl_add_rule(&timru));
|
||||||
|
} else
|
||||||
|
return(-EINVAL);
|
||||||
|
case IIOCNETDRU:
|
||||||
|
/* Delete a rule from a network-interface */
|
||||||
|
if (arg) {
|
||||||
|
if((ret = copy_from_user((char *) &timru, (char *) arg, sizeof(timru))))
|
||||||
|
return(ret);
|
||||||
|
return(isdn_timru_ioctl_del_rule(&timru));
|
||||||
|
} else
|
||||||
|
return(-EINVAL);
|
||||||
|
case IIOCNETGRU:
|
||||||
|
/* Get a rule of a network-interface */
|
||||||
|
if (arg) {
|
||||||
|
if((ret = copy_from_user((char *)&timru, (char *)arg, sizeof(timru))))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
if((ret = isdn_timru_ioctl_get_rule(&timru)))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
if((ret = copy_to_user((char *)arg, (char *)&timru, sizeof(timru))))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
} else
|
||||||
|
return(-EINVAL);
|
||||||
|
#endif /* CONFIG_ISDN_TIMEOUT_RULES */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
case IIOCNETBUD:
|
||||||
|
/* handle budget-accounting of a network-interface */
|
||||||
|
if (arg) {
|
||||||
|
if((ret = copy_from_user((char *)&budget, (char *)arg, sizeof(budget))))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
if((ret = isdn_budget_ioctl(&budget)))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
if((ret = copy_to_user((char *)arg, (char *)&budget, sizeof(budget))))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
} else
|
||||||
|
return(-EINVAL);
|
||||||
|
#endif /* CONFIG_ISDN_BUDGET */
|
||||||
#endif /* CONFIG_NETDEVICES */
|
#endif /* CONFIG_NETDEVICES */
|
||||||
case IIOCSETVER:
|
case IIOCSETVER:
|
||||||
dev->net_verbose = arg;
|
dev->net_verbose = arg;
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.9 1998/02/20 17:19:01 fritz
|
||||||
|
* Added common stub for sending commands to lowlevel.
|
||||||
|
*
|
||||||
* Revision 1.8 1997/10/09 21:28:49 fritz
|
* Revision 1.8 1997/10/09 21:28:49 fritz
|
||||||
* New HL<->LL interface:
|
* New HL<->LL interface:
|
||||||
* New BSENT callback with nr. of bytes included.
|
* New BSENT callback with nr. of bytes included.
|
||||||
|
@ -87,6 +90,6 @@ extern int isdn_readbchan(int, int, u_char *, u_char *, int, int);
|
||||||
extern int isdn_get_free_channel(int, int, int, int, int);
|
extern int isdn_get_free_channel(int, int, int, int, int);
|
||||||
extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
|
extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
|
||||||
extern int register_isdn(isdn_if * i);
|
extern int register_isdn(isdn_if * i);
|
||||||
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
|
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) || defined(CONFIG_ISDN_TIMEOUT_RULES)
|
||||||
extern void isdn_dumppkt(char *, u_char *, int, int);
|
extern void isdn_dumppkt(char *, u_char *, int, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.57 1998/02/25 18:31:13 fritz
|
||||||
|
* Added debugging output in adjust_header.
|
||||||
|
*
|
||||||
* Revision 1.56 1998/02/25 17:49:42 he
|
* Revision 1.56 1998/02/25 17:49:42 he
|
||||||
* Changed return codes caused be failing copy_{to,from}_user to -EFAULT
|
* Changed return codes caused be failing copy_{to,from}_user to -EFAULT
|
||||||
*
|
*
|
||||||
|
@ -280,9 +283,24 @@ char *isdn_net_revision = "$Revision$";
|
||||||
static void
|
static void
|
||||||
isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
|
isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP\n",
|
printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP\n",
|
||||||
dev->name, reason);
|
dev->name, reason);
|
||||||
|
|
||||||
|
if(skb)
|
||||||
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for(i = 0; i < DEV_NUMBUFFS; i++) {
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
while((skb = skb_dequeue(&dev->buffs[i]))) {
|
||||||
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -434,7 +452,11 @@ isdn_net_autohup()
|
||||||
if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
|
if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
|
||||||
anymore = 1;
|
anymore = 1;
|
||||||
l->huptimer++;
|
l->huptimer++;
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
if ((l->timeout_rules || l->huptimeout) && l->huptimer > l->huptimeout)
|
||||||
|
#else
|
||||||
if ((l->onhtime) && (l->huptimer > l->onhtime))
|
if ((l->onhtime) && (l->huptimer > l->onhtime))
|
||||||
|
#endif
|
||||||
if (l->hupflags & ISDN_MANCHARGE &&
|
if (l->hupflags & ISDN_MANCHARGE &&
|
||||||
l->hupflags & ISDN_CHARGEHUP) {
|
l->hupflags & ISDN_CHARGEHUP) {
|
||||||
while (jiffies - l->chargetime > l->chargeint)
|
while (jiffies - l->chargetime > l->chargeint)
|
||||||
|
@ -458,6 +480,17 @@ isdn_net_autohup()
|
||||||
isdn_net_hangup(&p->dev);
|
isdn_net_hangup(&p->dev);
|
||||||
} else if (l->hupflags & ISDN_INHUP)
|
} else if (l->hupflags & ISDN_INHUP)
|
||||||
isdn_net_hangup(&p->dev);
|
isdn_net_hangup(&p->dev);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
if(isdn_net_budget(ISDN_BUDGET_CHECK_ONLINE, &p->dev)) {
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(dev->global_flags & ISDN_GLOBAL_STOPPED || l->flags & ISDN_NET_STOPPED) {
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p = (isdn_net_dev *) p->next;
|
p = (isdn_net_dev *) p->next;
|
||||||
}
|
}
|
||||||
|
@ -596,6 +629,16 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
|
||||||
lp->chargetime = jiffies;
|
lp->chargetime = jiffies;
|
||||||
printk(KERN_DEBUG "isdn_net: chargetime of %s now %d\n",
|
printk(KERN_DEBUG "isdn_net: chargetime of %s now %d\n",
|
||||||
lp->name, lp->chargetime);
|
lp->name, lp->chargetime);
|
||||||
|
|
||||||
|
/* reset dial-timeout */
|
||||||
|
lp->dialstarted = 0;
|
||||||
|
lp->dialwait_timer = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
(void)isdn_net_budget(ISDN_BUDGET_START_ONLINE, &p->dev);
|
||||||
|
(void)isdn_net_budget(ISDN_BUDGET_CHECK_CHARGE, &p->dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Immediately send first skb to speed up arp */
|
/* Immediately send first skb to speed up arp */
|
||||||
#ifdef CONFIG_ISDN_PPP
|
#ifdef CONFIG_ISDN_PPP
|
||||||
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
|
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
|
||||||
|
@ -613,6 +656,13 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
|
||||||
if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb)))
|
if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb)))
|
||||||
lp->first_skb = NULL;
|
lp->first_skb = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
else {
|
||||||
|
/* recalc initial huptimeout,
|
||||||
|
there is no packet to match the rules. */
|
||||||
|
isdn_net_recalc_timeout(ISDN_TIMRU_BRINGUP, ISDN_TIMRU_PACKET_NONE, &p->dev, NULL, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -638,6 +688,11 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
|
||||||
lp->chargetime = jiffies;
|
lp->chargetime = jiffies;
|
||||||
printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %d\n",
|
printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %d\n",
|
||||||
lp->name, lp->chargetime);
|
lp->name, lp->chargetime);
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
if(isdn_net_budget(ISDN_BUDGET_CHECK_CHARGE, &p->dev)) {
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,6 +758,13 @@ isdn_net_dial(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
anymore = 1;
|
anymore = 1;
|
||||||
|
|
||||||
|
if(lp->dialtimeout > 0)
|
||||||
|
if(lp->dialstarted == 0 || jiffies > (lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
|
||||||
|
lp->dialstarted = jiffies;
|
||||||
|
lp->dialwait_timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
lp->dialstate++;
|
lp->dialstate++;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -723,6 +785,12 @@ isdn_net_dial(void)
|
||||||
* If list of phone-numbers is exhausted, increment
|
* If list of phone-numbers is exhausted, increment
|
||||||
* retry-counter.
|
* retry-counter.
|
||||||
*/
|
*/
|
||||||
|
if(dev->global_flags & ISDN_GLOBAL_STOPPED || lp->flags & ISDN_NET_STOPPED) {
|
||||||
|
isdn_net_unreachable(&p->dev, lp->first_skb, "dial suppressed: isdn stopped");
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
cmd.driver = lp->isdn_device;
|
cmd.driver = lp->isdn_device;
|
||||||
cmd.command = ISDN_CMD_SETL2;
|
cmd.command = ISDN_CMD_SETL2;
|
||||||
cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
|
cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
|
||||||
|
@ -747,6 +815,24 @@ isdn_net_dial(void)
|
||||||
lp->dialstate = 4;
|
lp->dialstate = 4;
|
||||||
printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
|
printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
if(isdn_net_budget(ISDN_BUDGET_CHECK_DIAL, &p->dev)) {
|
||||||
|
restore_flags(flags);
|
||||||
|
isdn_net_unreachable(&p->dev, lp->first_skb, "dial: budget(s) used up");
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(lp->dialtimeout > 0)
|
||||||
|
if(jiffies > (lp->dialstarted + lp->dialtimeout)) {
|
||||||
|
restore_flags(flags);
|
||||||
|
lp->dialwait_timer = jiffies + lp->dialwait;
|
||||||
|
lp->dialstarted = 0;
|
||||||
|
isdn_net_unreachable(&p->dev, lp->first_skb, "dial: timed out");
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(cmd.parm.setup.phone, "%s", lp->dial->num);
|
sprintf(cmd.parm.setup.phone, "%s", lp->dial->num);
|
||||||
/*
|
/*
|
||||||
* Switch to next number or back to start if at end of list.
|
* Switch to next number or back to start if at end of list.
|
||||||
|
@ -754,6 +840,17 @@ isdn_net_dial(void)
|
||||||
if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
|
if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
|
||||||
lp->dial = lp->phone[1];
|
lp->dial = lp->phone[1];
|
||||||
lp->dialretry++;
|
lp->dialretry++;
|
||||||
|
|
||||||
|
if (lp->dialretry > lp->dialmax) {
|
||||||
|
restore_flags(flags);
|
||||||
|
if (lp->dialtimeout == 0) {
|
||||||
|
lp->dialwait_timer = jiffies + lp->dialwait;
|
||||||
|
lp->dialstarted = 0;
|
||||||
|
isdn_net_unreachable(&p->dev, lp->first_skb, "dial: tried all numbers dialmax times");
|
||||||
|
}
|
||||||
|
isdn_net_hangup(&p->dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
restore_flags(flags);
|
restore_flags(flags);
|
||||||
cmd.driver = lp->isdn_device;
|
cmd.driver = lp->isdn_device;
|
||||||
|
@ -768,7 +865,7 @@ isdn_net_dial(void)
|
||||||
isdn_info_update();
|
isdn_info_update();
|
||||||
}
|
}
|
||||||
printk(KERN_INFO "%s: dialing %d %s...\n", lp->name,
|
printk(KERN_INFO "%s: dialing %d %s...\n", lp->name,
|
||||||
lp->dialretry - 1, cmd.parm.setup.phone);
|
lp->dialretry, cmd.parm.setup.phone);
|
||||||
lp->dtimer = 0;
|
lp->dtimer = 0;
|
||||||
#ifdef ISDN_DEBUG_NET_DIAL
|
#ifdef ISDN_DEBUG_NET_DIAL
|
||||||
printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
|
printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
|
||||||
|
@ -792,14 +889,11 @@ isdn_net_dial(void)
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
/* Wait for D-Channel-connect.
|
/* Wait for D-Channel-connect.
|
||||||
* If timeout and max retries not
|
* If timeout, switch back to state 3.
|
||||||
* reached, switch back to state 3.
|
* Dialmax-handling moved to state 3.
|
||||||
*/
|
*/
|
||||||
if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
|
if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
|
||||||
if (lp->dialretry < lp->dialmax) {
|
|
||||||
lp->dialstate = 3;
|
lp->dialstate = 3;
|
||||||
} else
|
|
||||||
isdn_net_hangup(&p->dev);
|
|
||||||
anymore = 1;
|
anymore = 1;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -1071,14 +1165,21 @@ isdn_net_xmit(struct device *ndev, isdn_net_local * lp, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#if CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
(void)isdn_net_recalc_timeout(ISDN_TIMRU_KEEPUP_OUT,
|
||||||
|
ISDN_TIMRU_PACKET_SKB, ndev, skb, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* For the other encaps the header has already been built */
|
/* For the other encaps the header has already been built */
|
||||||
#ifdef CONFIG_ISDN_PPP
|
#ifdef CONFIG_ISDN_PPP
|
||||||
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
|
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
|
||||||
return isdn_ppp_xmit(skb, ndev);
|
return isdn_ppp_xmit(skb, ndev);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
/* Reset hangup-timeout */
|
/* Reset hangup-timeout */
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
if (lp->cps > lp->triggercps) {
|
if (lp->cps > lp->triggercps) {
|
||||||
/* Device overloaded */
|
/* Device overloaded */
|
||||||
|
|
||||||
|
@ -1190,6 +1291,32 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
|
||||||
ulong flags;
|
ulong flags;
|
||||||
save_flags(flags);
|
save_flags(flags);
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
if(isdn_net_recalc_timeout(ISDN_TIMRU_BRINGUP,
|
||||||
|
ISDN_TIMRU_PACKET_SKB, ndev, skb, 0) <= 0) {
|
||||||
|
isdn_net_unreachable(ndev, skb, "dial rejected: packet may not bring up connection");
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
ndev->tbusy = 0;
|
||||||
|
restore_flags(flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(lp->dialwait_timer <= 0)
|
||||||
|
if(lp->dialstarted > 0 && lp->dialtimeout > 0 && jiffies < lp->dialstarted + lp->dialtimeout + lp->dialwait)
|
||||||
|
lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
|
||||||
|
|
||||||
|
if(lp->dialwait_timer > 0) {
|
||||||
|
if(jiffies < lp->dialwait_timer) {
|
||||||
|
isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
ndev->tbusy = 0;
|
||||||
|
restore_flags(flags);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
lp->dialwait_timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Grab a free ISDN-Channel */
|
/* Grab a free ISDN-Channel */
|
||||||
if ((chi =
|
if ((chi =
|
||||||
isdn_get_free_channel(ISDN_USAGE_NET,
|
isdn_get_free_channel(ISDN_USAGE_NET,
|
||||||
|
@ -1464,8 +1591,10 @@ isdn_net_receive(struct device *ndev, struct sk_buff *skb)
|
||||||
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
|
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
|
||||||
isdn_net_local *olp = lp; /* original 'lp' */
|
isdn_net_local *olp = lp; /* original 'lp' */
|
||||||
#ifdef CONFIG_ISDN_PPP
|
#ifdef CONFIG_ISDN_PPP
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
int proto = PPP_PROTOCOL(skb->data);
|
int proto = PPP_PROTOCOL(skb->data);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_ISDN_X25
|
#ifdef CONFIG_ISDN_X25
|
||||||
struct concap_proto *cprot = lp -> netdev -> cprot;
|
struct concap_proto *cprot = lp -> netdev -> cprot;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1494,20 +1623,26 @@ isdn_net_receive(struct device *ndev, struct sk_buff *skb)
|
||||||
switch (lp->p_encap) {
|
switch (lp->p_encap) {
|
||||||
case ISDN_NET_ENCAP_ETHER:
|
case ISDN_NET_ENCAP_ETHER:
|
||||||
/* Ethernet over ISDN */
|
/* Ethernet over ISDN */
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
olp->huptimer = 0;
|
olp->huptimer = 0;
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
skb->protocol = isdn_net_type_trans(skb, ndev);
|
skb->protocol = isdn_net_type_trans(skb, ndev);
|
||||||
break;
|
break;
|
||||||
case ISDN_NET_ENCAP_UIHDLC:
|
case ISDN_NET_ENCAP_UIHDLC:
|
||||||
/* HDLC with UI-frame (for ispa with -h1 option) */
|
/* HDLC with UI-frame (for ispa with -h1 option) */
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
olp->huptimer = 0;
|
olp->huptimer = 0;
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
skb_pull(skb, 2);
|
skb_pull(skb, 2);
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case ISDN_NET_ENCAP_RAWIP:
|
case ISDN_NET_ENCAP_RAWIP:
|
||||||
/* RAW-IP without MAC-Header */
|
/* RAW-IP without MAC-Header */
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
olp->huptimer = 0;
|
olp->huptimer = 0;
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
skb->protocol = htons(ETH_P_IP);
|
skb->protocol = htons(ETH_P_IP);
|
||||||
break;
|
break;
|
||||||
case ISDN_NET_ENCAP_CISCOHDLCK:
|
case ISDN_NET_ENCAP_CISCOHDLCK:
|
||||||
|
@ -1547,8 +1682,10 @@ isdn_net_receive(struct device *ndev, struct sk_buff *skb)
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case ISDN_NET_ENCAP_IPTYP:
|
case ISDN_NET_ENCAP_IPTYP:
|
||||||
/* IP with type field */
|
/* IP with type field */
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
olp->huptimer = 0;
|
olp->huptimer = 0;
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
skb->protocol = *(unsigned short *) &(skb->data[0]);
|
skb->protocol = *(unsigned short *) &(skb->data[0]);
|
||||||
skb_pull(skb, 2);
|
skb_pull(skb, 2);
|
||||||
if (*(unsigned short *) skb->data == 0xFFFF)
|
if (*(unsigned short *) skb->data == 0xFFFF)
|
||||||
|
@ -1556,6 +1693,7 @@ isdn_net_receive(struct device *ndev, struct sk_buff *skb)
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_ISDN_PPP
|
#ifdef CONFIG_ISDN_PPP
|
||||||
case ISDN_NET_ENCAP_SYNCPPP:
|
case ISDN_NET_ENCAP_SYNCPPP:
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
/*
|
/*
|
||||||
* If encapsulation is syncppp, don't reset
|
* If encapsulation is syncppp, don't reset
|
||||||
* huptimer on LCP packets.
|
* huptimer on LCP packets.
|
||||||
|
@ -1564,6 +1702,7 @@ isdn_net_receive(struct device *ndev, struct sk_buff *skb)
|
||||||
olp->huptimer = 0;
|
olp->huptimer = 0;
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
isdn_ppp_receive(lp->netdev, olp, skb);
|
isdn_ppp_receive(lp->netdev, olp, skb);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1581,6 +1720,13 @@ isdn_net_receive(struct device *ndev, struct sk_buff *skb)
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
isdn_net_recalc_timeout(ISDN_TIMRU_KEEPUP_IN,
|
||||||
|
ISDN_TIMRU_PACKET_SKB, ndev, skb, 0);
|
||||||
|
/* FIXME: olp->huptimer = lp->huptimer ? */
|
||||||
|
#endif
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2232,6 +2378,7 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
|
||||||
ulong flags;
|
ulong flags;
|
||||||
save_flags(flags);
|
save_flags(flags);
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
/* Grab a free ISDN-Channel */
|
/* Grab a free ISDN-Channel */
|
||||||
if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
|
if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
|
||||||
lp->l3_proto,
|
lp->l3_proto,
|
||||||
|
@ -2364,6 +2511,19 @@ isdn_net_new(char *name, struct device *master)
|
||||||
netdev->local->dialmax = 1;
|
netdev->local->dialmax = 1;
|
||||||
netdev->local->flags = ISDN_NET_CBHUP; /* Hangup before Callback */
|
netdev->local->flags = ISDN_NET_CBHUP; /* Hangup before Callback */
|
||||||
netdev->local->cbdelay = 25; /* Wait 5 secs before Callback */
|
netdev->local->cbdelay = 25; /* Wait 5 secs before Callback */
|
||||||
|
netdev->local->dialtimeout = -1; /* Infinite Dial-Timeout */
|
||||||
|
netdev->local->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
|
||||||
|
netdev->local->dialstarted = 0; /* Jiffies of last dial-start */
|
||||||
|
netdev->local->dialwait_timer = 0; /* Jiffies of earliest next dial-start */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
netdev->local->timeout_rules = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
(void)isdn_net_budget(ISDN_BUDGET_INIT, &netdev->dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Put into to netdev-chain */
|
/* Put into to netdev-chain */
|
||||||
netdev->next = (void *) dev->netdev;
|
netdev->next = (void *) dev->netdev;
|
||||||
dev->netdev = netdev;
|
dev->netdev = netdev;
|
||||||
|
@ -2562,6 +2722,8 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
|
||||||
lp->triggercps = cfg->triggercps;
|
lp->triggercps = cfg->triggercps;
|
||||||
lp->slavedelay = cfg->slavedelay * HZ;
|
lp->slavedelay = cfg->slavedelay * HZ;
|
||||||
lp->pppbind = cfg->pppbind;
|
lp->pppbind = cfg->pppbind;
|
||||||
|
lp->dialtimeout = cfg->dialtimeout >= 0 ? cfg->dialtimeout * HZ : -1;
|
||||||
|
lp->dialwait = cfg->dialwait * HZ;
|
||||||
if (cfg->secure)
|
if (cfg->secure)
|
||||||
lp->flags |= ISDN_NET_SECURE;
|
lp->flags |= ISDN_NET_SECURE;
|
||||||
else
|
else
|
||||||
|
@ -2583,6 +2745,10 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
|
||||||
lp->flags &= ~ISDN_NET_CALLBACK;
|
lp->flags &= ~ISDN_NET_CALLBACK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (cfg->stopped)
|
||||||
|
lp->flags |= ISDN_NET_STOPPED;
|
||||||
|
else
|
||||||
|
lp->flags &= ~ISDN_NET_STOPPED;
|
||||||
if (cfg->chargehup)
|
if (cfg->chargehup)
|
||||||
lp->hupflags |= ISDN_CHARGEHUP;
|
lp->hupflags |= ISDN_CHARGEHUP;
|
||||||
else
|
else
|
||||||
|
@ -2650,6 +2816,7 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
|
||||||
if (lp->flags & ISDN_NET_CBOUT)
|
if (lp->flags & ISDN_NET_CBOUT)
|
||||||
cfg->callback = 2;
|
cfg->callback = 2;
|
||||||
cfg->cbhup = (lp->flags & ISDN_NET_CBHUP) ? 1 : 0;
|
cfg->cbhup = (lp->flags & ISDN_NET_CBHUP) ? 1 : 0;
|
||||||
|
cfg->stopped = (lp->flags & ISDN_NET_STOPPED) ? 1 : 0;
|
||||||
cfg->chargehup = (lp->hupflags & 4) ? 1 : 0;
|
cfg->chargehup = (lp->hupflags & 4) ? 1 : 0;
|
||||||
cfg->ihup = (lp->hupflags & 8) ? 1 : 0;
|
cfg->ihup = (lp->hupflags & 8) ? 1 : 0;
|
||||||
cfg->cbdelay = lp->cbdelay;
|
cfg->cbdelay = lp->cbdelay;
|
||||||
|
@ -2659,6 +2826,8 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
|
||||||
cfg->chargeint = (lp->hupflags & ISDN_CHARGEHUP) ?
|
cfg->chargeint = (lp->hupflags & ISDN_CHARGEHUP) ?
|
||||||
(lp->chargeint / HZ) : 0;
|
(lp->chargeint / HZ) : 0;
|
||||||
cfg->pppbind = lp->pppbind;
|
cfg->pppbind = lp->pppbind;
|
||||||
|
cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
|
||||||
|
cfg->dialwait = lp->dialwait / HZ;
|
||||||
if (lp->slave)
|
if (lp->slave)
|
||||||
strcpy(cfg->slave, ((isdn_net_local *) lp->slave->priv)->name);
|
strcpy(cfg->slave, ((isdn_net_local *) lp->slave->priv)->name);
|
||||||
else
|
else
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.34 1998/02/25 17:49:48 he
|
||||||
|
* Changed return codes caused be failing copy_{to,from}_user to -EFAULT
|
||||||
|
*
|
||||||
* Revision 1.33 1998/02/20 17:11:54 fritz
|
* Revision 1.33 1998/02/20 17:11:54 fritz
|
||||||
* Changes for recent kernels.
|
* Changes for recent kernels.
|
||||||
*
|
*
|
||||||
|
@ -832,8 +835,10 @@ isdn_ppp_write(int min, struct file *file, const char *buf, int count)
|
||||||
{
|
{
|
||||||
isdn_net_local *lp;
|
isdn_net_local *lp;
|
||||||
struct ippp_struct *is;
|
struct ippp_struct *is;
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
int proto;
|
int proto;
|
||||||
unsigned char protobuf[4];
|
unsigned char protobuf[4];
|
||||||
|
#endif
|
||||||
|
|
||||||
is = file->private_data;
|
is = file->private_data;
|
||||||
|
|
||||||
|
@ -847,6 +852,7 @@ isdn_ppp_write(int min, struct file *file, const char *buf, int count)
|
||||||
if (!lp)
|
if (!lp)
|
||||||
printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
|
printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n");
|
||||||
else {
|
else {
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
/*
|
/*
|
||||||
* Don't reset huptimer for
|
* Don't reset huptimer for
|
||||||
* LCP packets. (Echo requests).
|
* LCP packets. (Echo requests).
|
||||||
|
@ -856,6 +862,7 @@ isdn_ppp_write(int min, struct file *file, const char *buf, int count)
|
||||||
proto = PPP_PROTOCOL(protobuf);
|
proto = PPP_PROTOCOL(protobuf);
|
||||||
if (proto != PPP_LCP)
|
if (proto != PPP_LCP)
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (lp->isdn_device < 0 || lp->isdn_channel < 0)
|
if (lp->isdn_device < 0 || lp->isdn_channel < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -875,6 +882,12 @@ isdn_ppp_write(int min, struct file *file, const char *buf, int count)
|
||||||
printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
|
printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
|
||||||
isdn_ppp_frame_log("xmit", skb->data, skb->len, 32);
|
isdn_ppp_frame_log("xmit", skb->data, skb->len, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
(void)isdn_net_recalc_timeout(ISDN_TIMRU_KEEPUP_OUT,
|
||||||
|
ISDN_TIMRU_PACKET_PPP, &lp->netdev->dev, skb->data, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb)) != count) {
|
if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb)) != count) {
|
||||||
if (lp->sav_skb) {
|
if (lp->sav_skb) {
|
||||||
dev_kfree_skb(lp->sav_skb);
|
dev_kfree_skb(lp->sav_skb);
|
||||||
|
@ -1225,15 +1238,24 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
|
||||||
isdn_ppp_receive_ccp(net_dev,lp,skb);
|
isdn_ppp_receive_ccp(net_dev,lp,skb);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
(void)isdn_net_recalc_timeout(ISDN_TIMRU_KEEPUP_IN,
|
||||||
|
ISDN_TIMRU_PACKET_PPP_NO_HEADER, dev, skb->data, proto);
|
||||||
|
#endif
|
||||||
isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot); /* push data to pppd device */
|
isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot); /* push data to pppd device */
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
netif_rx(skb);
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
/* net_dev->local->stats.rx_packets++; *//* done in isdn_net.c */
|
(void)isdn_net_recalc_timeout(ISDN_TIMRU_KEEPUP_IN,
|
||||||
|
ISDN_TIMRU_PACKET_SKB, dev, skb, 0);
|
||||||
|
#else
|
||||||
/* Reset hangup-timer */
|
/* Reset hangup-timer */
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
|
netif_rx(skb);
|
||||||
|
/* net_dev->local->stats.rx_packets++; *//* done in isdn_net.c */
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1335,7 +1357,9 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
|
||||||
}
|
}
|
||||||
ipt = ippp_table[lp->ppp_slot];
|
ipt = ippp_table[lp->ppp_slot];
|
||||||
|
|
||||||
|
#ifndef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
lp->huptimer = 0;
|
lp->huptimer = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* after this line .. requeueing in the device queue is no longer allowed!!!
|
* after this line .. requeueing in the device queue is no longer allowed!!!
|
||||||
|
|
|
@ -0,0 +1,905 @@
|
||||||
|
/* isdn_timru.c
|
||||||
|
*
|
||||||
|
* Linux ISDN subsystem, timeout-rules for network interfaces.
|
||||||
|
*
|
||||||
|
* Copyright 1997 by Christian Lademann <cal@zls.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
02.06.97:cal:
|
||||||
|
- ISDN_TIMRU_PACKET_NONE = 0 definiert, die anderen ISDN_TIMRU_PACKET_* -
|
||||||
|
Definitionen jeweils inkrementiert
|
||||||
|
|
||||||
|
- isdn_net_recalc_timeout():
|
||||||
|
- In der Schleife zum Finden einer passenden Regel wurde in jedem Fall
|
||||||
|
die Wildcard-Kette durchsucht. Jetzt nicht mehr.
|
||||||
|
- beim Testen einer Bringup-Regel wird der anfaengliche Timeout auf den
|
||||||
|
Hangup-Timeout des Devices gesetzt (lp->onhtime).
|
||||||
|
|
||||||
|
10.06.97:cal:
|
||||||
|
- isdn_net_recalc_timeout(): rule->neg-Handling gesaeubert: eine Regel passt
|
||||||
|
genau dann, wenn match(rule) XOR rule->neg und das bei allen Regeltypen.
|
||||||
|
- isdn_net_add_rule(): rule->timeout bei BRINGUP immer 1, sonst > 0.
|
||||||
|
- alle return(-1), die zu ioctl-Calls zurueckgehen --> return(-EINVAL).
|
||||||
|
- div. Leerzeilen geloescht / eingefuegt; alle return's "geklammert".
|
||||||
|
|
||||||
|
12.06.97:cal:
|
||||||
|
- isdn_net_recalc_timeout(): Falls IP-Masquerading verwendet wird, kann mit
|
||||||
|
der neuen Option CONFIG_TIMRU_USE_MASQ der Regel-Match auf die ursprueng-
|
||||||
|
lichen Adressen und nicht auf die der Firewall angewendet werden. Dazu ist
|
||||||
|
ein Patch in net/ipv4/ip_masq.c notwendig: ip_masq_in_get_2 muss
|
||||||
|
exportiert werden.
|
||||||
|
|
||||||
|
26.06.97:cal:
|
||||||
|
- isdn_net_add_rule(): rule->timeout darf bei BRINGUP >= 0 sein. Damit
|
||||||
|
laesst sich folgende Systax erreichen: "Falls Paket passt, starte die
|
||||||
|
Verbindung NICHT", wie es im Stand 970602 moeglich war.
|
||||||
|
- isdn_net_recalc_timeout(): BRINGUP: initial timeout wird auf den in der
|
||||||
|
passenden Regel gefundenen Timeout gesetzt. Ist dieser 0, so wird die
|
||||||
|
Verbindung nicht aufgebaut.
|
||||||
|
|
||||||
|
16.10.97:cal:
|
||||||
|
- isdn_net_recalc_timeout(): beachte Fake-Header, der bei ausgehenden
|
||||||
|
SyncPPP-Paketen eingesetzt wird;
|
||||||
|
TimRu's "recalc timeout:" - Meldungen in einer Zeile
|
||||||
|
|
||||||
|
04.11.97:cal:
|
||||||
|
- isdn_net.c, isdn_net_new(): Timeout-Rules nicht mehr automatisch
|
||||||
|
alloziieren;
|
||||||
|
- isdn_net.c, isdn_net_autohup(): AutoHup auch durchfuehren, wenn keine
|
||||||
|
Timeout-Rules alloziiert sind.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
- Masq-Adressen statt Paketadresse ausgeben, falls die Masq-Adressen verwendet
|
||||||
|
werden.
|
||||||
|
|
||||||
|
- Masq-Adressen-Verwendung als Option in den Regeln vorsehen
|
||||||
|
|
||||||
|
- TCP-Flags als Regel-Optionen
|
||||||
|
|
||||||
|
- weitere Verfeinerungen fuer Nicht-TCP/IP-Pakete
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
#define __NO_VERSION__
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/isdn.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
#include <linux/in.h>
|
||||||
|
#include <net/icmp.h>
|
||||||
|
#include <net/tcp.h>
|
||||||
|
#include <net/udp.h>
|
||||||
|
#ifdef CONFIG_ISDN_TIMRU_USE_MASQ
|
||||||
|
#ifdef CONFIG_IP_MASQUERADE
|
||||||
|
#include <net/ip_masq.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#include "isdn_common.h"
|
||||||
|
#include "isdn_net.h"
|
||||||
|
#ifdef CONFIG_ISDN_PPP
|
||||||
|
#include "isdn_ppp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
|
||||||
|
static int
|
||||||
|
isdn_timru_match(isdn_timeout_rule *this, isdn_timeout_rule *rule);
|
||||||
|
|
||||||
|
|
||||||
|
#define printk_ip(a) printk("%ld.%ld.%ld.%ld",(ntohl(a)>>24)&0xFF,\
|
||||||
|
(ntohl(a)>>16)&0xFF,\
|
||||||
|
(ntohl(a)>>8)&0xFF,\
|
||||||
|
(ntohl(a))&0xFF)
|
||||||
|
#define printk_port(a) printk("%d",ntohs(a))
|
||||||
|
|
||||||
|
|
||||||
|
#define VERBOSE_PRINTK(v, l, p...) { \
|
||||||
|
if(dev->net_verbose >= (v)) { \
|
||||||
|
printk(l ## p); \
|
||||||
|
} else { ; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_net_recalc_timeout(int type, int prot, struct device *ndev, void *buf, ulong arg) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct iphdr *ip;
|
||||||
|
struct icmphdr *icmp;
|
||||||
|
struct tcphdr *tcp;
|
||||||
|
struct udphdr *udp;
|
||||||
|
#ifdef CONFIG_ISDN_TIMRU_USE_MASQ
|
||||||
|
#ifdef CONFIG_IP_MASQUERADE
|
||||||
|
struct ip_masq *masq;
|
||||||
|
int m_prot;
|
||||||
|
__u32 m_saddr, m_daddr;
|
||||||
|
__u16 m_sport, m_dport;
|
||||||
|
int check_for_masq;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
isdn_timeout_rule match_rule;
|
||||||
|
|
||||||
|
/*
|
||||||
|
char *cbuf;
|
||||||
|
*/
|
||||||
|
int ppp_proto, ppp_hdrlen = 0, new_timeout;
|
||||||
|
|
||||||
|
|
||||||
|
match_rule.type = type;
|
||||||
|
match_rule.protfam = ISDN_TIMRU_PROTFAM_WILDCARD;
|
||||||
|
|
||||||
|
if(dev->net_verbose > 4) {
|
||||||
|
printk(KERN_DEBUG "recalc_timeout:");
|
||||||
|
switch(type) {
|
||||||
|
case ISDN_TIMRU_BRINGUP: printk("BRINGUP, "); break;
|
||||||
|
case ISDN_TIMRU_KEEPUP_IN: printk("KEEPUP_IN, "); break;
|
||||||
|
case ISDN_TIMRU_KEEPUP_OUT: printk("KEEPUP_OUT, "); break;
|
||||||
|
default:
|
||||||
|
printk("ERROR\n");
|
||||||
|
return(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(prot) {
|
||||||
|
case ISDN_TIMRU_PACKET_PPP:
|
||||||
|
case ISDN_TIMRU_PACKET_PPP_NO_HEADER:
|
||||||
|
if(prot == ISDN_TIMRU_PACKET_PPP) {
|
||||||
|
ppp_proto = PPP_PROTOCOL((char *)buf);
|
||||||
|
/*
|
||||||
|
cbuf = (char *)(buf + PPP_HDRLEN);
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
ppp_proto = (int)arg;
|
||||||
|
/*
|
||||||
|
cbuf = (char *)buf;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
match_rule.protfam = ISDN_TIMRU_PROTFAM_PPP;
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_WILDCARD;
|
||||||
|
|
||||||
|
switch(ppp_proto) {
|
||||||
|
case PPP_IPCP:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_IPCP;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/IPCP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_IPXCP:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_IPXCP;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/IPXCP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CCP:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_CCP;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/CCP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_LCP:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_LCP;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/LCP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_PAP:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_PAP;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/PAP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_LQR:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_LQR;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/LQR\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPP_CHAP:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_CHAP;
|
||||||
|
VERBOSE_PRINTK(5, "", "PPP/CHAP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
match_rule.rule.ppp.protocol = ISDN_TIMRU_PPP_WILDCARD;
|
||||||
|
|
||||||
|
if(dev->net_verbose >= 5) {
|
||||||
|
printk("PPP/? (%x)\n", ppp_proto);
|
||||||
|
isdn_dumppkt("R:", (u_char *)buf, 40, 40);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_PACKET_SKB:
|
||||||
|
skb = (struct sk_buff *)buf;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_PPP
|
||||||
|
if((type == ISDN_TIMRU_BRINGUP ||
|
||||||
|
type == ISDN_TIMRU_KEEPUP_OUT) &&
|
||||||
|
lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
|
||||||
|
/* jump over fake header. */
|
||||||
|
ppp_hdrlen = IPPP_MAX_HEADER;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
switch(ntohs(skb->protocol)) {
|
||||||
|
case ETH_P_IP:
|
||||||
|
/*
|
||||||
|
if(!(ip = skb->ip_hdr))
|
||||||
|
*/
|
||||||
|
ip = (struct iphdr *)(skb->data + ppp_hdrlen);
|
||||||
|
|
||||||
|
match_rule.protfam = ISDN_TIMRU_PROTFAM_IP;
|
||||||
|
match_rule.rule.ip.saddr.s_addr = ip->saddr;
|
||||||
|
match_rule.rule.ip.daddr.s_addr = ip->daddr;
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
|
||||||
|
switch(ip->protocol) {
|
||||||
|
case IPPROTO_ICMP:
|
||||||
|
if(!(icmp = (struct icmphdr *)((unsigned long *)ip+ip->ihl))) {
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/ICMP HDR-ERR\n");
|
||||||
|
} else {
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_ICMP;
|
||||||
|
match_rule.rule.ip.pt.type.from = icmp->type;
|
||||||
|
|
||||||
|
if(dev->net_verbose >= 5) {
|
||||||
|
printk("IP/ICMP ");
|
||||||
|
printk_ip(ip->saddr);
|
||||||
|
printk(" --> ");
|
||||||
|
printk_ip(ip->daddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(icmp->type);
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_IGMP:
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/IGMP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_IPIP:
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/IPIP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
if(!(tcp = (struct tcphdr *)((unsigned long *)ip+ip->ihl))) {
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/TCP HDR-ERR\n");
|
||||||
|
} else {
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_TCP;
|
||||||
|
match_rule.rule.ip.pt.port.s_from = tcp->source;
|
||||||
|
match_rule.rule.ip.pt.port.d_from = tcp->dest;
|
||||||
|
|
||||||
|
if(dev->net_verbose >= 5) {
|
||||||
|
printk("IP/TCP ");
|
||||||
|
printk_ip(ip->saddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(tcp->source);
|
||||||
|
printk(" --> ");
|
||||||
|
printk_ip(ip->daddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(tcp->dest);
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_EGP:
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/EGP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_PUP:
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
VERBOSE_PRINTK(5, "" "IP/PUP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
if(!(udp=(struct udphdr *)((unsigned long *)ip+ip->ihl))) {
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/UDP HDR-ERR\n");
|
||||||
|
} else {
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_UDP;
|
||||||
|
match_rule.rule.ip.pt.port.s_from = udp->source;
|
||||||
|
match_rule.rule.ip.pt.port.d_from = udp->dest;
|
||||||
|
|
||||||
|
if(dev->net_verbose >= 5) {
|
||||||
|
printk("IP/UDP ");
|
||||||
|
printk_ip(ip->saddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(udp->source);
|
||||||
|
printk(" --> ");
|
||||||
|
printk_ip(ip->daddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(udp->dest);
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_IDP:
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
VERBOSE_PRINTK(5, "", "IP/IDP\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
match_rule.rule.ip.protocol = ISDN_TIMRU_IP_WILDCARD;
|
||||||
|
if(dev->net_verbose >= 5) {
|
||||||
|
printk("IP/? (%x)\n", ip->protocol);
|
||||||
|
isdn_dumppkt("R:", (u_char *)skb, skb->len, 180);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETH_P_ARP:
|
||||||
|
VERBOSE_PRINTK(5, "", "ARP/?\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETH_P_IPX:
|
||||||
|
VERBOSE_PRINTK(5, "", "IPX/?\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETH_P_802_2:
|
||||||
|
VERBOSE_PRINTK(5, "", "802.2/?\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ETH_P_802_3:
|
||||||
|
VERBOSE_PRINTK(5, "", "802.3/?\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(dev->net_verbose >= 5) {
|
||||||
|
printk("?/? (%x)\n", ntohs(skb->protocol));
|
||||||
|
isdn_dumppkt("R:", (u_char *)skb, skb->len, 1800);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMRU_USE_MASQ
|
||||||
|
#ifdef CONFIG_IP_MASQUERADE
|
||||||
|
check_for_masq = 0;
|
||||||
|
m_saddr = m_daddr = (__u32)0;
|
||||||
|
m_sport = m_dport = (__u16)0;
|
||||||
|
m_prot = 0;
|
||||||
|
|
||||||
|
switch(match_rule.protfam) {
|
||||||
|
case ISDN_TIMRU_PROTFAM_IP:
|
||||||
|
m_saddr = match_rule.rule.ip.saddr.s_addr;
|
||||||
|
m_daddr = match_rule.rule.ip.daddr.s_addr;
|
||||||
|
|
||||||
|
switch(match_rule.rule.ip.protocol) {
|
||||||
|
case ISDN_TIMRU_IP_TCP:
|
||||||
|
m_prot = IPPROTO_TCP;
|
||||||
|
m_sport = match_rule.rule.ip.pt.port.s_from;
|
||||||
|
m_dport = match_rule.rule.ip.pt.port.d_from;
|
||||||
|
check_for_masq = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_IP_UDP:
|
||||||
|
m_prot = IPPROTO_UDP;
|
||||||
|
m_sport = match_rule.rule.ip.pt.port.s_from;
|
||||||
|
m_dport = match_rule.rule.ip.pt.port.d_from;
|
||||||
|
check_for_masq = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#ifdef CONFIG_IP_MASQUERADE_ICMP
|
||||||
|
case ISDN_TIMRU_IP_ICMP:
|
||||||
|
m_sport = match_rule.rule.ip.pt.type.from;
|
||||||
|
m_dport = 0;
|
||||||
|
check_for_masq = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(check_for_masq) {
|
||||||
|
masq = NULL;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case ISDN_TIMRU_BRINGUP:
|
||||||
|
case ISDN_TIMRU_KEEPUP_OUT:
|
||||||
|
if((masq = ip_masq_in_get_2(m_prot, m_daddr, m_dport, m_saddr, m_sport))) {
|
||||||
|
match_rule.rule.ip.saddr.s_addr = m_saddr;
|
||||||
|
match_rule.rule.ip.daddr.s_addr = m_daddr;
|
||||||
|
switch(m_prot) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
match_rule.rule.ip.pt.port.s_from = m_sport;
|
||||||
|
match_rule.rule.ip.pt.port.d_from = m_dport;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_KEEPUP_IN:
|
||||||
|
if((masq = ip_masq_in_get_2(m_prot, m_saddr, m_sport, m_daddr, m_dport))) {
|
||||||
|
match_rule.rule.ip.saddr.s_addr = m_daddr;
|
||||||
|
match_rule.rule.ip.daddr.s_addr = m_saddr;
|
||||||
|
switch(m_prot) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
match_rule.rule.ip.pt.port.s_from = m_sport;
|
||||||
|
match_rule.rule.ip.pt.port.d_from = m_dport;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(masq && dev->net_verbose >= 5) {
|
||||||
|
printk(KERN_DEBUG "MASQ-TIMRU: ");
|
||||||
|
printk_ip(masq->maddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(masq->mport);
|
||||||
|
printk(": ");
|
||||||
|
printk_ip(masq->saddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(masq->sport);
|
||||||
|
printk(" --> ");
|
||||||
|
printk_ip(masq->daddr);
|
||||||
|
printk("/");
|
||||||
|
printk_port(masq->dport);
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_timeout = lp->onhtime;
|
||||||
|
|
||||||
|
if(prot && lp->timeout_rules) {
|
||||||
|
isdn_timeout_rule *head, *tor;
|
||||||
|
int pf, found_match, i;
|
||||||
|
|
||||||
|
pf = match_rule.protfam;
|
||||||
|
found_match = 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
head = tor = lp->timeout_rules->timru[type][pf];
|
||||||
|
i = 0;
|
||||||
|
while(tor) {
|
||||||
|
if((isdn_timru_match(&match_rule, tor) > 0) ^ (tor->neg > 0)) {
|
||||||
|
found_match = 1;
|
||||||
|
new_timeout = tor->timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(found_match) {
|
||||||
|
#ifdef DEBUG_RULES
|
||||||
|
printk(KERN_DEBUG "Rule %d-%d-%d matches\n", type, pf, i);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tor->next == head)
|
||||||
|
tor = NULL;
|
||||||
|
else {
|
||||||
|
tor = tor->next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! found_match && pf != ISDN_TIMRU_PROTFAM_WILDCARD)
|
||||||
|
pf = ISDN_TIMRU_PROTFAM_WILDCARD;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! found_match) {
|
||||||
|
new_timeout = lp->timeout_rules->defaults[type];
|
||||||
|
#ifdef DEBUG_RULES
|
||||||
|
printk("No rule matches: using default\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == ISDN_TIMRU_BRINGUP) {
|
||||||
|
if(new_timeout > 0) {
|
||||||
|
lp->huptimeout = new_timeout;
|
||||||
|
lp->huptimer = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(new_timeout > lp->huptimeout
|
||||||
|
|| lp->huptimeout - lp->huptimer < new_timeout) {
|
||||||
|
lp->huptimeout = new_timeout;
|
||||||
|
lp->huptimer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(new_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
isdn_timru_match(isdn_timeout_rule *this, isdn_timeout_rule *rule) {
|
||||||
|
if(this->protfam != rule->protfam)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
switch(rule->protfam) {
|
||||||
|
case ISDN_TIMRU_PROTFAM_WILDCARD:
|
||||||
|
return(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_PROTFAM_PPP:
|
||||||
|
if(rule->rule.ppp.protocol == ISDN_TIMRU_PPP_WILDCARD
|
||||||
|
|| rule->rule.ppp.protocol == this->rule.ppp.protocol)
|
||||||
|
return(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_PROTFAM_IP:
|
||||||
|
if((this->rule.ip.saddr.s_addr & rule->rule.ip.smask.s_addr) != rule->rule.ip.saddr.s_addr
|
||||||
|
|| (this->rule.ip.daddr.s_addr & rule->rule.ip.dmask.s_addr) != rule->rule.ip.daddr.s_addr)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(rule->rule.ip.protocol == ISDN_TIMRU_IP_WILDCARD)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
if(rule->rule.ip.protocol != this->rule.ip.protocol)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
switch(rule->rule.ip.protocol) {
|
||||||
|
case ISDN_TIMRU_IP_ICMP:
|
||||||
|
if(this->rule.ip.pt.type.from < rule->rule.ip.pt.type.from
|
||||||
|
|| this->rule.ip.pt.type.from > rule->rule.ip.pt.type.to)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_IP_TCP:
|
||||||
|
case ISDN_TIMRU_IP_UDP:
|
||||||
|
if(this->rule.ip.pt.port.s_from < rule->rule.ip.pt.port.s_from
|
||||||
|
|| this->rule.ip.pt.port.s_from > rule->rule.ip.pt.port.s_to)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(this->rule.ip.pt.port.d_from < rule->rule.ip.pt.port.d_from
|
||||||
|
|| this->rule.ip.pt.port.d_from > rule->rule.ip.pt.port.d_to)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
isdn_timru_rule_equals(isdn_timeout_rule *this, isdn_timeout_rule *rule) {
|
||||||
|
if(this->neg != rule->neg
|
||||||
|
|| this->protfam != rule->protfam)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
switch(rule->protfam) {
|
||||||
|
case ISDN_TIMRU_PROTFAM_PPP:
|
||||||
|
if(this->rule.ppp.protocol != rule->rule.ppp.protocol)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_PROTFAM_IP:
|
||||||
|
if(this->rule.ip.protocol != rule->rule.ip.protocol
|
||||||
|
|| this->rule.ip.saddr.s_addr != rule->rule.ip.saddr.s_addr
|
||||||
|
|| this->rule.ip.smask.s_addr != rule->rule.ip.smask.s_addr
|
||||||
|
|| this->rule.ip.daddr.s_addr != rule->rule.ip.daddr.s_addr
|
||||||
|
|| this->rule.ip.dmask.s_addr != rule->rule.ip.dmask.s_addr)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
switch(rule->rule.ip.protocol) {
|
||||||
|
case ISDN_TIMRU_IP_ICMP:
|
||||||
|
if(this->rule.ip.pt.type.from != rule->rule.ip.pt.type.from
|
||||||
|
|| this->rule.ip.pt.type.to != rule->rule.ip.pt.type.to)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISDN_TIMRU_IP_TCP:
|
||||||
|
case ISDN_TIMRU_IP_UDP:
|
||||||
|
if(this->rule.ip.pt.port.s_from != rule->rule.ip.pt.port.s_from
|
||||||
|
|| this->rule.ip.pt.port.s_to != rule->rule.ip.pt.port.s_to
|
||||||
|
|| this->rule.ip.pt.port.d_from != rule->rule.ip.pt.port.d_from
|
||||||
|
|| this->rule.ip.pt.port.d_to != rule->rule.ip.pt.port.d_to)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_alloc_timeout_rules(struct device *ndev) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
int i, j;
|
||||||
|
ulong flags;
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
if(!(lp->timeout_rules = (struct isdn_timeout_rules *)kmalloc(sizeof(struct isdn_timeout_rules), GFP_KERNEL))) {
|
||||||
|
restore_flags(flags);
|
||||||
|
printk(KERN_WARNING "isdn_timru: failed to allocate memory.\n");
|
||||||
|
return(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((char *)lp->timeout_rules, 0, sizeof(struct isdn_timeout_rules));
|
||||||
|
|
||||||
|
for(i = 0; i < ISDN_TIMRU_NUM_CHECK; i++) {
|
||||||
|
lp->timeout_rules->defaults[i] = lp->onhtime;
|
||||||
|
for(j = 0; j < ISDN_TIMRU_NUM_PROTFAM; j++)
|
||||||
|
lp->timeout_rules->timru[i][j] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_free_timeout_rules(struct device *ndev) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
isdn_timeout_rule *head, *this, *next;
|
||||||
|
int i, j;
|
||||||
|
ulong flags;
|
||||||
|
|
||||||
|
if(!lp->timeout_rules)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
for(i = 0; i < ISDN_TIMRU_NUM_CHECK; i++)
|
||||||
|
for(j = 0; j < ISDN_TIMRU_NUM_CHECK; j++)
|
||||||
|
if((head = lp->timeout_rules->timru[i][j])) {
|
||||||
|
this = head;
|
||||||
|
do {
|
||||||
|
next = this->next;
|
||||||
|
kfree(this);
|
||||||
|
} while(next == head);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(lp->timeout_rules);
|
||||||
|
lp->timeout_rules = NULL;
|
||||||
|
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_add_rule(int where, struct device *ndev, isdn_timeout_rule *rule) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
isdn_timeout_rule **head;
|
||||||
|
ulong flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(!lp->timeout_rules)
|
||||||
|
if((ret = isdn_timru_alloc_timeout_rules(ndev)))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
if(rule->timeout < 0)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
|
||||||
|
head = &(lp->timeout_rules->timru[rule->type][rule->protfam]);
|
||||||
|
|
||||||
|
if(! *head)
|
||||||
|
rule->next = rule->prev = *head = rule;
|
||||||
|
else {
|
||||||
|
rule->next = *head;
|
||||||
|
rule->prev = (*head)->prev;
|
||||||
|
(*head)->prev->next = rule;
|
||||||
|
(*head)->prev = rule;
|
||||||
|
|
||||||
|
if(where == 0) /* add to head of chain */
|
||||||
|
*head = rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_del_rule(struct device *ndev, isdn_timeout_rule *rule) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
isdn_timeout_rule **head, *this;
|
||||||
|
ulong flags;
|
||||||
|
|
||||||
|
if(!lp->timeout_rules)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
|
||||||
|
head = &(lp->timeout_rules->timru[rule->type][rule->protfam]);
|
||||||
|
|
||||||
|
if(! *head) {
|
||||||
|
restore_flags(flags);
|
||||||
|
return(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
this = *head;
|
||||||
|
do {
|
||||||
|
if(isdn_timru_rule_equals(this, rule)) {
|
||||||
|
if(this->next != this) { /* more than one rule */
|
||||||
|
this->prev->next = this->next;
|
||||||
|
this->next->prev = this->prev;
|
||||||
|
|
||||||
|
if(this == *head)
|
||||||
|
*head = this->next;
|
||||||
|
} else
|
||||||
|
*head = NULL;
|
||||||
|
|
||||||
|
kfree(this);
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
} else
|
||||||
|
this = this->next;
|
||||||
|
} while(this == *head);
|
||||||
|
|
||||||
|
restore_flags(flags);
|
||||||
|
return(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_set_default(int type, struct device *ndev, int def) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
ulong flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(!lp->timeout_rules)
|
||||||
|
if((ret = isdn_timru_alloc_timeout_rules(ndev)))
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
if(def < 0)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
|
||||||
|
lp->timeout_rules->defaults[type] = def;
|
||||||
|
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_get_rule(struct device *ndev, isdn_timeout_rule **rule, int i, int j, int k) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
isdn_timeout_rule *head, *this;
|
||||||
|
int l;
|
||||||
|
ulong flags;
|
||||||
|
|
||||||
|
if(!lp->timeout_rules
|
||||||
|
|| i < 0 || i > ISDN_TIMRU_NUM_CHECK
|
||||||
|
|| j < 0 || j > ISDN_TIMRU_NUM_PROTFAM
|
||||||
|
|| k < 0)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
|
||||||
|
if(!(this = head = lp->timeout_rules->timru[i][j])) {
|
||||||
|
restore_flags(flags);
|
||||||
|
return(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(l = 0; l < k; l++) {
|
||||||
|
if(this->next == head) {
|
||||||
|
restore_flags(flags);
|
||||||
|
return(-EINVAL);
|
||||||
|
}
|
||||||
|
this = this->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*rule = this;
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_get_default(int type, struct device *ndev, int *ret) {
|
||||||
|
isdn_net_local *lp = (isdn_net_local *)ndev->priv;
|
||||||
|
ulong flags;
|
||||||
|
|
||||||
|
if(!lp->timeout_rules)
|
||||||
|
return(-EINVAL);
|
||||||
|
|
||||||
|
save_flags(flags);
|
||||||
|
cli();
|
||||||
|
|
||||||
|
*ret = lp->timeout_rules->defaults[type];
|
||||||
|
|
||||||
|
restore_flags(flags);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_ioctl_add_rule(isdn_ioctl_timeout_rule *iorule)
|
||||||
|
{
|
||||||
|
isdn_net_dev *p = isdn_net_findif(iorule->name);
|
||||||
|
isdn_timeout_rule *r;
|
||||||
|
|
||||||
|
if(p) {
|
||||||
|
if(iorule->where < 0) { /* set default */
|
||||||
|
return(isdn_timru_set_default(iorule->type, &p->dev, iorule->defval));
|
||||||
|
} else {
|
||||||
|
if(!(r = (isdn_timeout_rule *) kmalloc(sizeof(isdn_timeout_rule), GFP_KERNEL)))
|
||||||
|
return(-ENOMEM);
|
||||||
|
memcpy((char *)r, (char *)&iorule->rule, sizeof(isdn_timeout_rule));
|
||||||
|
return(isdn_timru_add_rule(iorule->where, &p->dev, r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(-ENODEV);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_ioctl_del_rule(isdn_ioctl_timeout_rule *iorule)
|
||||||
|
{
|
||||||
|
isdn_net_dev *p = isdn_net_findif(iorule->name);
|
||||||
|
isdn_timeout_rule *r;
|
||||||
|
|
||||||
|
if(p) {
|
||||||
|
if(!(r = (isdn_timeout_rule *) kmalloc(sizeof(isdn_timeout_rule), GFP_KERNEL)))
|
||||||
|
return(-ENOMEM);
|
||||||
|
memcpy((char *)r, (char *)&iorule->rule, sizeof(isdn_timeout_rule));
|
||||||
|
return(isdn_timru_del_rule(&p->dev, r));
|
||||||
|
}
|
||||||
|
return(-ENODEV);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
isdn_timru_ioctl_get_rule(isdn_ioctl_timeout_rule *iorule)
|
||||||
|
{
|
||||||
|
int ret, def;
|
||||||
|
isdn_net_dev *p = isdn_net_findif(iorule->name);
|
||||||
|
isdn_timeout_rule *r;
|
||||||
|
|
||||||
|
if(p) {
|
||||||
|
if(iorule->where < 0) { /* get default */
|
||||||
|
if((ret = isdn_timru_get_default(iorule->type, &p->dev, &def)) < 0)
|
||||||
|
return(ret);
|
||||||
|
|
||||||
|
iorule->protfam = p->local->huptimer;
|
||||||
|
iorule->index = p->local->huptimeout;
|
||||||
|
iorule->defval = def;
|
||||||
|
} else {
|
||||||
|
if(isdn_timru_get_rule(&p->dev, &r, iorule->type, iorule->protfam, iorule->index))
|
||||||
|
return(-ENOMEM);
|
||||||
|
|
||||||
|
memcpy((char *)&iorule->rule, (char *)r, sizeof(isdn_timeout_rule));
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(-ENODEV);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,6 +27,9 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.37 1998/02/22 19:45:24 fritz
|
||||||
|
* Some changes regarding V.110
|
||||||
|
*
|
||||||
* Revision 1.36 1998/02/20 17:35:55 fritz
|
* Revision 1.36 1998/02/20 17:35:55 fritz
|
||||||
* Added V.110 stuff.
|
* Added V.110 stuff.
|
||||||
*
|
*
|
||||||
|
@ -206,6 +209,11 @@
|
||||||
#define IIOCNETDIL _IO('I',20)
|
#define IIOCNETDIL _IO('I',20)
|
||||||
#define IIOCGETCPS _IO('I',21)
|
#define IIOCGETCPS _IO('I',21)
|
||||||
#define IIOCGETDVR _IO('I',22)
|
#define IIOCGETDVR _IO('I',22)
|
||||||
|
#define IIOCNETARU _IO('I',23)
|
||||||
|
#define IIOCNETDRU _IO('I',24)
|
||||||
|
#define IIOCNETGRU _IO('I',25)
|
||||||
|
|
||||||
|
#define IIOCNETBUD _IO('I',26)
|
||||||
|
|
||||||
#define IIOCNETALN _IO('I',32)
|
#define IIOCNETALN _IO('I',32)
|
||||||
#define IIOCNETDLN _IO('I',33)
|
#define IIOCNETDLN _IO('I',33)
|
||||||
|
@ -281,6 +289,9 @@ typedef struct {
|
||||||
int pppbind; /* ippp device for bindings */
|
int pppbind; /* ippp device for bindings */
|
||||||
int chargeint; /* Use fixed charge interval length */
|
int chargeint; /* Use fixed charge interval length */
|
||||||
int triggercps; /* BogoCPS needed for triggering slave */
|
int triggercps; /* BogoCPS needed for triggering slave */
|
||||||
|
int dialtimeout; /* Dial-Timeout */
|
||||||
|
int dialwait; /* Time to wait after failed dial */
|
||||||
|
int stopped; /* Flag: Stopped */
|
||||||
} isdn_net_ioctl_cfg;
|
} isdn_net_ioctl_cfg;
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
@ -397,6 +408,9 @@ typedef struct {
|
||||||
#define ISDN_NET_TMP 0x10 /* tmp interface until getting an IP */
|
#define ISDN_NET_TMP 0x10 /* tmp interface until getting an IP */
|
||||||
#define ISDN_NET_DYNAMIC 0x20 /* this link is dynamically allocated */
|
#define ISDN_NET_DYNAMIC 0x20 /* this link is dynamically allocated */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ISDN_NET_STOPPED 0x40 /* this interface is stopped */
|
||||||
|
|
||||||
#define ISDN_NET_MAGIC 0x49344C02 /* for paranoia-checking */
|
#define ISDN_NET_MAGIC 0x49344C02 /* for paranoia-checking */
|
||||||
|
|
||||||
/* Phone-list-element */
|
/* Phone-list-element */
|
||||||
|
@ -405,6 +419,28 @@ typedef struct {
|
||||||
char num[ISDN_MSNLEN];
|
char num[ISDN_MSNLEN];
|
||||||
} isdn_net_phone;
|
} isdn_net_phone;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
#include <linux/isdn_timru.h>
|
||||||
|
|
||||||
|
struct isdn_timeout_rules {
|
||||||
|
isdn_timeout_rule *timru[ISDN_TIMRU_NUM_CHECK][ISDN_TIMRU_NUM_PROTFAM];
|
||||||
|
int defaults[ISDN_TIMRU_NUM_CHECK];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
#include <linux/isdn_budget.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int amount, /* usable amount */
|
||||||
|
used, /* used so far */
|
||||||
|
period, /* length of period */
|
||||||
|
notified; /* flag: notified user about low budget */
|
||||||
|
time_t period_started, /* when did the current period start? */
|
||||||
|
last_check; /* last time checked */
|
||||||
|
} isdn_budget;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Principles when extending structures for generic encapsulation protocol
|
Principles when extending structures for generic encapsulation protocol
|
||||||
("concap") support:
|
("concap") support:
|
||||||
|
@ -487,6 +523,17 @@ typedef struct isdn_net_local_s {
|
||||||
struct device *,
|
struct device *,
|
||||||
unsigned char *);
|
unsigned char *);
|
||||||
int pppbind; /* ippp device for bindings */
|
int pppbind; /* ippp device for bindings */
|
||||||
|
int dialtimeout; /* How long shall we try on dialing? (jiffies) */
|
||||||
|
int dialwait; /* How long shall we wait after failed attempt? (jiffies) */
|
||||||
|
ulong dialstarted; /* jiffies of first dialing-attempt */
|
||||||
|
ulong dialwait_timer; /* jiffies of earliest next dialing-attempt */
|
||||||
|
int huptimeout; /* How long will the connection be up? (seconds) */
|
||||||
|
#ifdef CONFIG_ISDN_TIMEOUT_RULES
|
||||||
|
struct isdn_timeout_rules *timeout_rules;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ISDN_BUDGET
|
||||||
|
isdn_budget budget [ISDN_BUDGET_NUM_BUDGET];
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_ISDN_X25
|
#ifdef CONFIG_ISDN_X25
|
||||||
struct concap_device_ops *dops; /* callbacks used by encapsulator */
|
struct concap_device_ops *dops; /* callbacks used by encapsulator */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* isdn_budget.h
|
||||||
|
*
|
||||||
|
* Linux ISDN subsystem, budget-accounting for network interfaces.
|
||||||
|
*
|
||||||
|
* Copyright 1997 by Christian Lademann <cal@zls.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
30.06.97:cal:angelegt
|
||||||
|
04.11.97:cal:budget.period: int --> time_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __isdn_budget_h__
|
||||||
|
#define __isdn_budget_h__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define ISDN_BUDGET_DIAL 0
|
||||||
|
#define ISDN_BUDGET_CHARGE 1
|
||||||
|
#define ISDN_BUDGET_ONLINE 2
|
||||||
|
#define ISDN_BUDGET_NUM_BUDGET 3
|
||||||
|
|
||||||
|
#define ISDN_BUDGET_INIT 0
|
||||||
|
#define ISDN_BUDGET_CHECK_DIAL 1
|
||||||
|
#define ISDN_BUDGET_CHECK_CHARGE 2
|
||||||
|
#define ISDN_BUDGET_CHECK_ONLINE 3
|
||||||
|
#define ISDN_BUDGET_START_ONLINE 10
|
||||||
|
|
||||||
|
#define ISDN_BUDGET_SET_BUDGET 0
|
||||||
|
#define ISDN_BUDGET_GET_BUDGET 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name [9]; /* Interface */
|
||||||
|
int command, /* subcommand */
|
||||||
|
budget, /* budget-nr. */
|
||||||
|
amount, /* set/get budget-amount */
|
||||||
|
used; /* set/get used amount */
|
||||||
|
time_t period, /* set/get length of period */
|
||||||
|
period_started; /* set/get startpoint of period */
|
||||||
|
} isdn_ioctl_budget;
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
extern int isdn_net_budget(int, struct device *);
|
||||||
|
extern int isdn_budget_ioctl(isdn_ioctl_budget *);
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
#endif /* __isdn_budget_h__ */
|
|
@ -0,0 +1,119 @@
|
||||||
|
/* isdn_timru.h
|
||||||
|
*
|
||||||
|
* Linux ISDN subsystem, timeout-rules for network interfaces.
|
||||||
|
*
|
||||||
|
* Copyright 1997 by Christian Lademann <cal@zls.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
02.06.97:cal:ISDN_TIMRU_PACKET_NONE def., ISDN_TIMRU_PACKET_* inkr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __isdn_timru_h__
|
||||||
|
#define __isdn_timru_h__
|
||||||
|
|
||||||
|
#define ISDN_TIMRU_PACKET_NONE 0
|
||||||
|
#define ISDN_TIMRU_PACKET_SKB 1
|
||||||
|
#define ISDN_TIMRU_PACKET_PPP 2
|
||||||
|
#define ISDN_TIMRU_PACKET_PPP_NO_HEADER 3
|
||||||
|
|
||||||
|
#define ISDN_TIMRU_BRINGUP 0
|
||||||
|
#define ISDN_TIMRU_KEEPUP_IN 1
|
||||||
|
#define ISDN_TIMRU_KEEPUP_OUT 2
|
||||||
|
#define ISDN_TIMRU_BRINGDOWN 3
|
||||||
|
#define ISDN_TIMRU_NUM_CHECK 4
|
||||||
|
|
||||||
|
#define ISDN_TIMRU_PROTFAM_WILDCARD 0
|
||||||
|
#define ISDN_TIMRU_PROTFAM_IP 1
|
||||||
|
#define ISDN_TIMRU_PROTFAM_PPP 2
|
||||||
|
#define ISDN_TIMRU_PROTFAM_IPX 3
|
||||||
|
#define ISDN_TIMRU_NUM_PROTFAM 4
|
||||||
|
|
||||||
|
#define ISDN_TIMRU_IP_WILDCARD 0
|
||||||
|
#define ISDN_TIMRU_IP_ICMP 1
|
||||||
|
#define ISDN_TIMRU_IP_TCP 2
|
||||||
|
#define ISDN_TIMRU_IP_UDP 3
|
||||||
|
|
||||||
|
#define ISDN_TIMRU_PPP_WILDCARD 0
|
||||||
|
#define ISDN_TIMRU_PPP_IPCP 1
|
||||||
|
#define ISDN_TIMRU_PPP_IPXCP 2
|
||||||
|
#define ISDN_TIMRU_PPP_CCP 3
|
||||||
|
#define ISDN_TIMRU_PPP_LCP 4
|
||||||
|
#define ISDN_TIMRU_PPP_PAP 5
|
||||||
|
#define ISDN_TIMRU_PPP_LQR 6
|
||||||
|
#define ISDN_TIMRU_PPP_CHAP 7
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct in_addr saddr, /* Source Address */
|
||||||
|
smask, /* Source Subnetmask */
|
||||||
|
daddr, /* Dest. Address */
|
||||||
|
dmask; /* Dest. Subnetmask */
|
||||||
|
ushort protocol; /* TCP, UDP, ... */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
__u16 s_from, /* Source Port */
|
||||||
|
s_to,
|
||||||
|
d_from,
|
||||||
|
d_to;
|
||||||
|
} port;
|
||||||
|
struct {
|
||||||
|
__u8 from, /* ICMP-Type */
|
||||||
|
to;
|
||||||
|
} type;
|
||||||
|
} pt;
|
||||||
|
} isdn_timeout_rule_ip;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ushort protocol; /* IPCP, LCP, ... */
|
||||||
|
} isdn_timeout_rule_ppp;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct isdn_timeout_rule_s {
|
||||||
|
struct isdn_timeout_rule_s *next, /* Pointer to next rule */
|
||||||
|
*prev; /* Pointer to previous rule */
|
||||||
|
ushort type, /* BRINGUP, KEEPUP_*, ... */
|
||||||
|
neg;
|
||||||
|
int timeout; /* Timeout value */
|
||||||
|
ushort protfam; /* IP, IPX, PPP, ... */
|
||||||
|
union {
|
||||||
|
isdn_timeout_rule_ip ip; /* IP-Rule */
|
||||||
|
isdn_timeout_rule_ppp ppp; /* PPP-Rule */
|
||||||
|
} rule; /* Prot.-specific rule */
|
||||||
|
} isdn_timeout_rule;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name [9]; /* Interface */
|
||||||
|
int where, /* 0/1: add to start/end of list, -1: handle default */
|
||||||
|
type,
|
||||||
|
protfam,
|
||||||
|
index,
|
||||||
|
defval;
|
||||||
|
isdn_timeout_rule rule; /* Rule */
|
||||||
|
} isdn_ioctl_timeout_rule;
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
extern int isdn_net_recalc_timeout(int, int, struct device *, void *, ulong);
|
||||||
|
extern int isdn_timru_alloc_timeout_rules(struct device *);
|
||||||
|
extern int isdn_timru_ioctl_add_rule(isdn_ioctl_timeout_rule *);
|
||||||
|
extern int isdn_timru_ioctl_del_rule(isdn_ioctl_timeout_rule *);
|
||||||
|
extern int isdn_timru_ioctl_get_rule(isdn_ioctl_timeout_rule *);
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
#endif /* __isdn_timru_h__ */
|
Loading…
Reference in New Issue