Commit a3c7a8fa authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.20

parent 961f4bfa
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 19 SUBLEVEL = 20
ARCH = i386 ARCH = i386
...@@ -113,7 +113,7 @@ include arch/$(ARCH)/Makefile ...@@ -113,7 +113,7 @@ include arch/$(ARCH)/Makefile
$(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
Version: dummy Version: dummy
rm -f include/linux/version.h @rm -f include/linux/compile.h
boot: vmlinux boot: vmlinux
@$(MAKE) -C arch/$(ARCH)/boot @$(MAKE) -C arch/$(ARCH)/boot
...@@ -140,6 +140,7 @@ linuxsubdirs: dummy ...@@ -140,6 +140,7 @@ linuxsubdirs: dummy
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done
$(TOPDIR)/include/linux/version.h: include/linux/version.h $(TOPDIR)/include/linux/version.h: include/linux/version.h
$(TOPDIR)/include/linux/compile.h: include/linux/compile.h
newversion: newversion:
@if [ ! -f .version ]; then \ @if [ ! -f .version ]; then \
...@@ -148,8 +149,7 @@ newversion: ...@@ -148,8 +149,7 @@ newversion:
expr `cat .version` + 1 > .version; \ expr `cat .version` + 1 > .version; \
fi fi
include/linux/version.h: $(CONFIGURATION) Makefile newversion include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
@echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > .ver
@if [ -f .name ]; then \ @if [ -f .name ]; then \
echo \#define UTS_VERSION \"\#`cat .version`-`cat .name` `date`\"; \ echo \#define UTS_VERSION \"\#`cat .version`-`cat .name` `date`\"; \
else \ else \
...@@ -166,10 +166,14 @@ include/linux/version.h: $(CONFIGURATION) Makefile newversion ...@@ -166,10 +166,14 @@ include/linux/version.h: $(CONFIGURATION) Makefile newversion
echo \#define LINUX_COMPILE_DOMAIN ; \ echo \#define LINUX_COMPILE_DOMAIN ; \
fi >> .ver fi >> .ver
@echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> .ver @echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> .ver
@mv -f .ver $@
include/linux/version.h: ./Makefile
@echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > .ver
@echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver @echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver
if [ ! -f $@ ]; then mv .ver $@; fi @mv -f .ver $@
init/version.o: init/version.c include/linux/version.h init/version.o: init/version.c include/linux/compile.h
$(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c $(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c
init/main.o: init/main.c init/main.o: init/main.c
...@@ -225,7 +229,7 @@ modules_install: ...@@ -225,7 +229,7 @@ modules_install:
) )
clean: archclean clean: archclean
rm -f kernel/ksyms.lst rm -f kernel/ksyms.lst include/linux/compile.h
rm -f core `find . -name '*.[oas]' -print` rm -f core `find . -name '*.[oas]' -print`
rm -f core `find . -type f -name 'core' -print` rm -f core `find . -type f -name 'core' -print`
rm -f vmlinux System.map rm -f vmlinux System.map
...@@ -253,11 +257,9 @@ backup: mrproper ...@@ -253,11 +257,9 @@ backup: mrproper
sync sync
#depend dep: .hdepend #depend dep: .hdepend
depend dep: archdep .hdepend depend dep: archdep .hdepend include/linux/version.h
touch include/linux/version.h
awk -f scripts/depend.awk init/*.c > .tmpdepend awk -f scripts/depend.awk init/*.c > .tmpdepend
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done
rm -f include/linux/version.h
mv .tmpdepend .depend mv .tmpdepend .depend
ifdef CONFIG_MODVERSIONS ifdef CONFIG_MODVERSIONS
@echo updating $(TOPDIR)/include/linux/modversions.h @echo updating $(TOPDIR)/include/linux/modversions.h
......
...@@ -695,7 +695,6 @@ static void msg(int level, const char *fmt, ...) ...@@ -695,7 +695,6 @@ static void msg(int level, const char *fmt, ...)
{ {
char buf[256]; char buf[256];
va_list args; va_list args;
extern int vsprintf(char *, const char *, va_list);
if (!(sbpcd_debug&(1<<level))) return; if (!(sbpcd_debug&(1<<level))) return;
......
...@@ -127,13 +127,13 @@ L_OBJS += de600.o ...@@ -127,13 +127,13 @@ L_OBJS += de600.o
else else
M_OBJS += de600.o M_OBJS += de600.o
endif endif
ifdef CONFIG_DE620 ifdef CONFIG_DE620
L_OBJS += de620.o L_OBJS += de620.o
else else
M_OBJS += de620.o M_OBJS += de620.o
endif endif
ifdef CONFIG_AT1500 ifdef CONFIG_AT1500
L_OBJS += lance.o L_OBJS += lance.o
endif endif
......
...@@ -385,7 +385,7 @@ sl_bump(struct slip *sl) ...@@ -385,7 +385,7 @@ sl_bump(struct slip *sl)
skb->dev = sl->dev; skb->dev = sl->dev;
memcpy(skb_put(skb,count), sl->rbuff, count); memcpy(skb_put(skb,count), sl->rbuff, count);
skb->mac.raw=skb->data; skb->mac.raw=skb->data;
if(sl->mode&(SL_MODE_AX25|SL_MODE_AX25VC)) if(sl->mode & SL_MODE_AX25)
skb->protocol=htons(ETH_P_AX25); skb->protocol=htons(ETH_P_AX25);
else else
skb->protocol=htons(ETH_P_IP); skb->protocol=htons(ETH_P_IP);
...@@ -537,7 +537,7 @@ sl_header(struct sk_buff *skb, struct device *dev, unsigned short type, ...@@ -537,7 +537,7 @@ sl_header(struct sk_buff *skb, struct device *dev, unsigned short type,
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct slip *sl = (struct slip*)(dev->priv); struct slip *sl = (struct slip*)(dev->priv);
if (((sl->mode & SL_MODE_AX25) || (sl->mode & SL_MODE_AX25VC)) && type != htons(ETH_P_AX25)) { if (sl->mode & SL_MODE_AX25 && type != htons(ETH_P_AX25)) {
return ax25_encapsulate(skb, dev, type, daddr, saddr, len); return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
} }
#endif #endif
...@@ -555,7 +555,7 @@ sl_rebuild_header(void *buff, struct device *dev, unsigned long raddr, ...@@ -555,7 +555,7 @@ sl_rebuild_header(void *buff, struct device *dev, unsigned long raddr,
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct slip *sl = (struct slip*)(dev->priv); struct slip *sl = (struct slip*)(dev->priv);
if ((sl->mode & SL_MODE_AX25) || (sl->mode & SL_MODE_AX25VC)) { if (sl->mode & SL_MODE_AX25) {
return ax25_rebuild_header(buff, dev, raddr, skb); return ax25_rebuild_header(buff, dev, raddr, skb);
} }
#endif #endif
...@@ -752,7 +752,7 @@ slip_open(struct tty_struct *tty) ...@@ -752,7 +752,7 @@ slip_open(struct tty_struct *tty)
sl->mode = SL_MODE_DEFAULT; sl->mode = SL_MODE_DEFAULT;
sl->dev->type = ARPHRD_SLIP + sl->mode; sl->dev->type = ARPHRD_SLIP + sl->mode;
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
if (sl->dev->type == 260 || sl->dev->type == 272) { /* KISS */ if (sl->dev->type == 260) { /* KISS */
sl->dev->type = ARPHRD_AX25; sl->dev->type = ARPHRD_AX25;
} }
#endif #endif
...@@ -1008,14 +1008,6 @@ sl_set_dev_mac_address(struct device *dev, void *addr) ...@@ -1008,14 +1008,6 @@ sl_set_dev_mac_address(struct device *dev, void *addr)
memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
return 0; return 0;
} }
int sl_get_ax25_mode(struct device *dev)
{
struct slip *sl = (struct slip*)(dev->priv);
return sl->mode & SL_MODE_AX25VC;
}
#endif /* CONFIG_AX25 */ #endif /* CONFIG_AX25 */
...@@ -1072,13 +1064,13 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) ...@@ -1072,13 +1064,13 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
} }
#endif #endif
#ifndef CONFIG_AX25 #ifndef CONFIG_AX25
if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) { if (tmp & SL_MODE_AX25) {
return -EINVAL; return -EINVAL;
} }
#else #else
if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) { if (tmp & SL_MODE_AX25) {
sl->dev->addr_len=AX25_ADDR_LEN; /* sizeof an AX.25 addr */ sl->dev->addr_len=AX25_ADDR_LEN; /* sizeof an AX.25 addr */
sl->dev->hard_header_len=73; /* We don't do digipeaters */ sl->dev->hard_header_len=AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
} else { } else {
sl->dev->addr_len=0; /* No mac addr in slip mode */ sl->dev->addr_len=0; /* No mac addr in slip mode */
sl->dev->hard_header_len=0; sl->dev->hard_header_len=0;
...@@ -1087,7 +1079,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) ...@@ -1087,7 +1079,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
sl->mode = tmp; sl->mode = tmp;
sl->dev->type = ARPHRD_SLIP+sl->mode; sl->dev->type = ARPHRD_SLIP+sl->mode;
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
if (sl->dev->type == 260 || sl->dev->type == 272) { if (sl->dev->type == 260) {
sl->dev->type = ARPHRD_AX25; sl->dev->type = ARPHRD_AX25;
} }
#endif #endif
...@@ -1221,7 +1213,7 @@ slip_init(struct device *dev) ...@@ -1221,7 +1213,7 @@ slip_init(struct device *dev)
dev->addr_len = 0; dev->addr_len = 0;
dev->type = ARPHRD_SLIP + SL_MODE_DEFAULT; dev->type = ARPHRD_SLIP + SL_MODE_DEFAULT;
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
if (sl->dev->type == 260 || sl->dev->type == 272) { if (sl->dev->type == 260) {
sl->dev->type = ARPHRD_AX25; sl->dev->type = ARPHRD_AX25;
} }
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); /* Only activated in AX.25 mode */ memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); /* Only activated in AX.25 mode */
......
...@@ -95,7 +95,6 @@ struct slip { ...@@ -95,7 +95,6 @@ struct slip {
#define SL_MODE_CSLIP6 (SL_MODE_SLIP6|SL_MODE_CSLIP) #define SL_MODE_CSLIP6 (SL_MODE_SLIP6|SL_MODE_CSLIP)
#define SL_MODE_AX25 4 #define SL_MODE_AX25 4
#define SL_MODE_ADAPTIVE 8 #define SL_MODE_ADAPTIVE 8
#define SL_MODE_AX25VC 16
}; };
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/ip.h> #include <net/ip.h>
......
...@@ -34,7 +34,7 @@ include ../../versions.mk ...@@ -34,7 +34,7 @@ include ../../versions.mk
endif endif
ifdef CONFIG_SCSI ifdef CONFIG_SCSI
L_OBJS := hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o L_OBJS += hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o
else else
ifdef CONFIG_MODVERSIONS ifdef CONFIG_MODVERSIONS
# Create this before we build anything else. # Create this before we build anything else.
......
...@@ -228,7 +228,7 @@ int fsync_dev(dev_t dev) ...@@ -228,7 +228,7 @@ int fsync_dev(dev_t dev)
asmlinkage int sys_sync(void) asmlinkage int sys_sync(void)
{ {
sync_dev(0); fsync_dev(0);
return 0; return 0;
} }
...@@ -440,6 +440,7 @@ struct buffer_head * get_hash_table(dev_t dev, int block, int size) ...@@ -440,6 +440,7 @@ struct buffer_head * get_hash_table(dev_t dev, int block, int size)
for (;;) { for (;;) {
if (!(bh=find_buffer(dev,block,size))) if (!(bh=find_buffer(dev,block,size)))
return NULL; return NULL;
bh->b_reuse=0;
bh->b_count++; bh->b_count++;
wait_on_buffer(bh); wait_on_buffer(bh);
if (bh->b_dev == dev && bh->b_blocknr == block && bh->b_size == size) if (bh->b_dev == dev && bh->b_blocknr == block && bh->b_size == size)
...@@ -1075,6 +1076,7 @@ static unsigned long try_to_load_aligned(unsigned long address, ...@@ -1075,6 +1076,7 @@ static unsigned long try_to_load_aligned(unsigned long address,
arr[block++] = bh; arr[block++] = bh;
bh->b_count = 1; bh->b_count = 1;
bh->b_dirt = 0; bh->b_dirt = 0;
bh->b_reuse = 0;
bh->b_flushtime = 0; bh->b_flushtime = 0;
bh->b_uptodate = 0; bh->b_uptodate = 0;
bh->b_req = 0; bh->b_req = 0;
......
...@@ -23,6 +23,33 @@ ...@@ -23,6 +23,33 @@
*/ */
#define mem_write NULL #define mem_write NULL
static int check_range(struct task_struct * tsk, unsigned long addr, int count)
{
struct vm_area_struct *vma;
int retval;
vma = find_vma(tsk, addr);
if (!vma)
return -EACCES;
if (vma->vm_start > addr)
return -EACCES;
if (!(vma->vm_flags & VM_READ))
return -EACCES;
while ((retval = vma->vm_end - addr) < count) {
struct vm_area_struct *next = vma->vm_next;
if (!next)
break;
if (vma->vm_end != next->vm_start)
break;
if (!(next->vm_flags & VM_READ))
break;
vma = next;
}
if (retval > count)
retval = count;
return retval;
}
static int mem_read(struct inode * inode, struct file * file,char * buf, int count) static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
{ {
pgd_t *page_dir; pgd_t *page_dir;
...@@ -47,6 +74,9 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou ...@@ -47,6 +74,9 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
if (!tsk) if (!tsk)
return -EACCES; return -EACCES;
addr = file->f_pos; addr = file->f_pos;
count = check_range(tsk, addr, count);
if (count < 0)
return count;
tmp = buf; tmp = buf;
while (count > 0) { while (count > 0) {
if (current->signal & ~current->blocked) if (current->signal & ~current->blocked)
......
...@@ -24,6 +24,14 @@ struct full_sockaddr_ax25 ...@@ -24,6 +24,14 @@ struct full_sockaddr_ax25
ax25_address fsa_digipeater[AX25_MAX_DIGIS]; ax25_address fsa_digipeater[AX25_MAX_DIGIS];
}; };
struct ax25_routes_struct
{
ax25_address port_addr;
ax25_address dest_addr;
unsigned char digi_count;
ax25_address digi_addr[AX25_MAX_DIGIS - 2];
};
#define AX25_WINDOW 1 #define AX25_WINDOW 1
#define AX25_T1 2 #define AX25_T1 2
#define AX25_N2 3 #define AX25_N2 3
...@@ -31,12 +39,35 @@ struct full_sockaddr_ax25 ...@@ -31,12 +39,35 @@ struct full_sockaddr_ax25
#define AX25_T2 5 #define AX25_T2 5
#define AX25_BACKOFF 6 #define AX25_BACKOFF 6
#define AX25_EXTSEQ 7 #define AX25_EXTSEQ 7
#define AX25_HDRINCL 8
#define SIOCAX25GETUID (SIOCPROTOPRIVATE) #define SIOCAX25GETUID (SIOCPROTOPRIVATE)
#define SIOCAX25ADDUID (SIOCPROTOPRIVATE+1) #define SIOCAX25ADDUID (SIOCPROTOPRIVATE+1)
#define SIOCAX25DELUID (SIOCPROTOPRIVATE+2) #define SIOCAX25DELUID (SIOCPROTOPRIVATE+2)
#define SIOCAX25NOUID (SIOCPROTOPRIVATE+3) #define SIOCAX25NOUID (SIOCPROTOPRIVATE+3)
#define SIOCAX25DIGCTL (SIOCPROTOPRIVATE+4) #define SIOCAX25DIGCTL (SIOCPROTOPRIVATE+4)
#define SIOCAX25GETPARMS (SIOCPROTOPRIVATE+5)
#define SIOCAX25SETPARMS (SIOCPROTOPRIVATE+6)
#define AX25_NOUID_DEFAULT 0 #define AX25_NOUID_DEFAULT 0
#define AX25_NOUID_BLOCK 1 #define AX25_NOUID_BLOCK 1
#define AX25_VALUES_IPDEFMODE 0 /* 'D'=DG 'V'=VC */
#define AX25_VALUES_AXDEFMODE 1 /* 8=Normal 128=Extended Seq Nos */
#define AX25_VALUES_NETROM 2 /* Allow NET/ROM - 0=No 1=Yes */
#define AX25_VALUES_TEXT 3 /* Allow PID=Text - 0=No 1=Yes */
#define AX25_VALUES_BACKOFF 4 /* 'E'=Exponential 'L'=Linear */
#define AX25_VALUES_CONMODE 5 /* Allow connected modes - 0=No 1=Yes */
#define AX25_VALUES_WINDOW 6 /* Default window size for standard AX.25 */
#define AX25_VALUES_EWINDOW 7 /* Default window size for extended AX.25 */
#define AX25_VALUES_T1 8 /* Default T1 timeout value */
#define AX25_VALUES_T2 9 /* Default T2 timeout value */
#define AX25_VALUES_T3 10 /* Default T3 timeout value */
#define AX25_VALUES_N2 11 /* Default N2 value */
#define AX25_MAX_VALUES 20
struct ax25_parms_struct
{
ax25_address port_addr;
unsigned short values[AX25_MAX_VALUES];
};
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#define NETROM_T1 1 #define NETROM_T1 1
#define NETROM_T2 2 #define NETROM_T2 2
#define NETROM_N2 3 #define NETROM_N2 3
#define NETROM_HDRINCL 4
#define SIOCNRGETPARMS (SIOCPROTOPRIVATE+0) #define SIOCNRGETPARMS (SIOCPROTOPRIVATE+0)
#define SIOCNRSETPARMS (SIOCPROTOPRIVATE+1) #define SIOCNRSETPARMS (SIOCPROTOPRIVATE+1)
......
...@@ -101,14 +101,22 @@ ...@@ -101,14 +101,22 @@
#define AX25_STATE_4 4 #define AX25_STATE_4 4
#define PR_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */ #define PR_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */
#define DEFAULT_T1 (10 * PR_SLOWHZ) /* Outstanding frames - 10 seconds */
#define DEFAULT_T2 (3 * PR_SLOWHZ) /* Response delay - 3 seconds */
#define DEFAULT_T3 (300 * PR_SLOWHZ) /* Idle supervision - 300 seconds */
#define DEFAULT_N2 10 /* Number of retries */
#define DEFAULT_WINDOW 2 /* Default window size */
#define MODULUS 8 /* Standard AX.25 modulus */ #define MODULUS 8 /* Standard AX.25 modulus */
#define EMODULUS 128 /* Extended AX.25 modulus */ #define EMODULUS 128 /* Extended AX.25 modulus */
#define AX25_DEF_IPDEFMODE 'D'
#define AX25_DEF_AXDEFMODE 8
#define AX25_DEF_NETROM 1
#define AX25_DEF_TEXT 1
#define AX25_DEF_BACKOFF 'E'
#define AX25_DEF_CONMODE 1
#define AX25_DEF_WINDOW 2
#define AX25_DEF_EWINDOW 32
#define AX25_DEF_T1 10
#define AX25_DEF_T2 3
#define AX25_DEF_T3 300
#define AX25_DEF_N2 10
typedef struct ax25_uid_assoc { typedef struct ax25_uid_assoc {
struct ax25_uid_assoc *next; struct ax25_uid_assoc *next;
uid_t uid; uid_t uid;
...@@ -126,7 +134,7 @@ typedef struct ax25_cb { ...@@ -126,7 +134,7 @@ typedef struct ax25_cb {
struct ax25_cb *next; struct ax25_cb *next;
ax25_address source_addr, dest_addr; ax25_address source_addr, dest_addr;
struct device *device; struct device *device;
unsigned char state, modulus; unsigned char state, modulus, hdrincl;
unsigned short vs, vr, va; unsigned short vs, vr, va;
unsigned char condition, backoff; unsigned char condition, backoff;
unsigned char n2, n2count; unsigned char n2, n2count;
...@@ -152,7 +160,6 @@ extern struct device *ax25rtr_get_dev(ax25_address *); ...@@ -152,7 +160,6 @@ extern struct device *ax25rtr_get_dev(ax25_address *);
extern int ax25_encapsulate(struct sk_buff *, struct device *, unsigned short, extern int ax25_encapsulate(struct sk_buff *, struct device *, unsigned short,
void *, void *, unsigned int); void *, void *, unsigned int);
extern int ax25_rebuild_header(unsigned char *, struct device *, unsigned long, struct sk_buff *); extern int ax25_rebuild_header(unsigned char *, struct device *, unsigned long, struct sk_buff *);
extern int ax25_get_info(char *, char **, off_t, int, int);
extern ax25_uid_assoc *ax25_uid_list; extern ax25_uid_assoc *ax25_uid_list;
extern int ax25_uid_policy; extern int ax25_uid_policy;
extern ax25_address *ax25_findbyuid(uid_t); extern ax25_address *ax25_findbyuid(uid_t);
...@@ -171,17 +178,23 @@ extern void ax25_nr_error_recovery(ax25_cb *); ...@@ -171,17 +178,23 @@ extern void ax25_nr_error_recovery(ax25_cb *);
extern void ax25_establish_data_link(ax25_cb *); extern void ax25_establish_data_link(ax25_cb *);
extern void ax25_transmit_enquiry(ax25_cb *); extern void ax25_transmit_enquiry(ax25_cb *);
extern void ax25_enquiry_response(ax25_cb *); extern void ax25_enquiry_response(ax25_cb *);
extern void ax25_timeout_response(ax25_cb *);
extern void ax25_check_iframes_acked(ax25_cb *, unsigned short); extern void ax25_check_iframes_acked(ax25_cb *, unsigned short);
extern void ax25_check_need_response(ax25_cb *, int, int); extern void ax25_check_need_response(ax25_cb *, int, int);
/* ax25_route.c */ /* ax25_route.c */
extern void ax25_rt_rx_frame(ax25_address *, struct device *); extern void ax25_rt_rx_frame(ax25_address *, struct device *, ax25_digi *);
extern int ax25_rt_get_info(char *, char **, off_t, int, int); extern int ax25_rt_get_info(char *, char **, off_t, int, int);
extern int ax25_cs_get_info(char *, char **, off_t, int, int); extern int ax25_cs_get_info(char *, char **, off_t, int, int);
extern int ax25_rt_autobind(ax25_cb *, ax25_address *); extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern void ax25_rt_device_down(struct device *); extern void ax25_rt_device_down(struct device *);
extern int ax25_rt_ioctl(unsigned int, void *);
extern void ax25_ip_mode_set(ax25_address *, struct device *, char); extern void ax25_ip_mode_set(ax25_address *, struct device *, char);
extern char ax25_ip_mode_get(ax25_address *, struct device *); extern char ax25_ip_mode_get(ax25_address *, struct device *);
extern unsigned short ax25_dev_get_value(struct device *, int);
extern void ax25_dev_device_up(struct device *);
extern void ax25_dev_device_down(struct device *);
extern int ax25_dev_ioctl(unsigned int, void *);
/* ax25_subr.c */ /* ax25_subr.c */
extern void ax25_clear_queues(ax25_cb *); extern void ax25_clear_queues(ax25_cb *);
...@@ -202,7 +215,4 @@ extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25 ...@@ -202,7 +215,4 @@ extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25
/* ax25_timer */ /* ax25_timer */
extern void ax25_set_timer(ax25_cb *); extern void ax25_set_timer(ax25_cb *);
/* slip.c */
extern int sl_get_ax25_mode(struct device *);
#endif #endif
...@@ -46,11 +46,10 @@ ...@@ -46,11 +46,10 @@
typedef struct { typedef struct {
ax25_address user_addr, source_addr, dest_addr; ax25_address user_addr, source_addr, dest_addr;
struct device *device; struct device *device;
unsigned char my_index, my_id; unsigned char my_index, my_id;
unsigned char your_index, your_id; unsigned char your_index, your_id;
unsigned char state, bpqext; unsigned char state, condition, bpqext, hdrincl;
unsigned short vs, vr, va, vl; unsigned short vs, vr, va, vl;
unsigned char condition;
unsigned char n2, n2count; unsigned char n2, n2count;
unsigned short t1, t2, rtt; unsigned short t1, t2, rtt;
unsigned short t1timer, t2timer, t4timer; unsigned short t1timer, t2timer, t4timer;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/compile.h>
struct new_utsname system_utsname = { struct new_utsname system_utsname = {
UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION,
......
...@@ -14,10 +14,13 @@ O_TARGET := kernel.o ...@@ -14,10 +14,13 @@ O_TARGET := kernel.o
O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \
module.o exit.o signal.o itimer.o info.o time.o softirq.o \ module.o exit.o signal.o itimer.o info.o time.o softirq.o \
resource.o resource.o
SYMTAB_OBJS = ksyms.o SYMTAB_OBJS = ksyms.o
O_OBJS += $(SYMTAB_OBJS) O_OBJS += $(SYMTAB_OBJS)
ifdef CONFIG_MODVERSIONS
$(O_TARGET): $(SYMTAB_OBJS:.o=.ver) $(O_TARGET): $(SYMTAB_OBJS:.o=.ver)
endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
/**** This file is generated by genksyms DO NOT EDIT! ****/
#if defined(CONFIG_MODVERSIONS) && !defined(__GENKSYMS__)
#ifndef _KSYMS_VER_
#define _KSYMS_VER_
#define rename_module_symbol _set_ver(rename_module_symbol, b81c73c1)
#define register_symtab _set_ver(register_symtab, e910ea66)
#define EISA_bus _set_ver(EISA_bus, 7e37737c)
#define wp_works_ok _set_ver(wp_works_ok, f37f99e9)
#define verify_area _set_ver(verify_area, 4cfda560)
#define do_mmap _set_ver(do_mmap, 677e7ee1)
#define do_munmap _set_ver(do_munmap, 6221f117)
#define zeromap_page_range _set_ver(zeromap_page_range, 7c395a26)
#define unmap_page_range _set_ver(unmap_page_range, 0110085f)
#define insert_vm_struct _set_ver(insert_vm_struct, 1f4e4882)
#define merge_segments _set_ver(merge_segments, 6854be5a)
#define __get_free_pages _set_ver(__get_free_pages, 5243d78b)
#define free_pages _set_ver(free_pages, 96448859)
#define kmalloc _set_ver(kmalloc, d31fb2cb)
#define kfree_s _set_ver(kfree_s, 1e72eb79)
#define vmalloc _set_ver(vmalloc, 667f3e25)
#define vfree _set_ver(vfree, 6df52add)
#define getname _set_ver(getname, 81487159)
#define putname _set_ver(putname, b19e8126)
#define __iget _set_ver(__iget, ee2b6320)
#define iput _set_ver(iput, 59241ced)
#define namei _set_ver(namei, 00478bcd)
#define lnamei _set_ver(lnamei, fcfddbb1)
#define open_namei _set_ver(open_namei, 414b2b0f)
#define close_fp _set_ver(close_fp, 1d4c15d8)
#define check_disk_change _set_ver(check_disk_change, b66ed457)
#define invalidate_buffers _set_ver(invalidate_buffers, c65255f1)
#define fsync_dev _set_ver(fsync_dev, a221190d)
#define permission _set_ver(permission, 0ebf7474)
#define inode_setattr _set_ver(inode_setattr, 0c80a3c1)
#define inode_change_ok _set_ver(inode_change_ok, 5d1cb326)
#define generic_mmap _set_ver(generic_mmap, d4ff59f3)
#define set_blocksize _set_ver(set_blocksize, f45fda38)
#define getblk _set_ver(getblk, d40228ac)
#define bread _set_ver(bread, c73bf0f0)
#define breada _set_ver(breada, eb8e858c)
#define brelse _set_ver(brelse, 4c27ac3d)
#define ll_rw_block _set_ver(ll_rw_block, f3aa4dd3)
#define __wait_on_buffer _set_ver(__wait_on_buffer, e8fcc968)
#define dcache_lookup _set_ver(dcache_lookup, 83336566)
#define dcache_add _set_ver(dcache_add, fe71f11e)
#define register_chrdev _set_ver(register_chrdev, da99513f)
#define unregister_chrdev _set_ver(unregister_chrdev, 61ea5ee8)
#define register_blkdev _set_ver(register_blkdev, 4699a621)
#define unregister_blkdev _set_ver(unregister_blkdev, d39bbca9)
#define tty_register_driver _set_ver(tty_register_driver, fcc8591c)
#define tty_unregister_driver _set_ver(tty_unregister_driver, c78132a8)
#define tty_std_termios _set_ver(tty_std_termios, cf350678)
#define block_read _set_ver(block_read, a7fe4f51)
#define block_write _set_ver(block_write, 902674c9)
#define block_fsync _set_ver(block_fsync, 182888d8)
#define wait_for_request _set_ver(wait_for_request, 9ca2932e)
#define blksize_size _set_ver(blksize_size, dea1eb55)
#define hardsect_size _set_ver(hardsect_size, ed1ee14f)
#define blk_size _set_ver(blk_size, f60b5398)
#define blk_dev _set_ver(blk_dev, dbf5fdd4)
#define is_read_only _set_ver(is_read_only, b0c5f83e)
#define set_device_ro _set_ver(set_device_ro, 8fb69e13)
#define bmap _set_ver(bmap, 73bb8bdd)
#define sync_dev _set_ver(sync_dev, 9bca536d)
#define get_blkfops _set_ver(get_blkfops, 83827791)
#define register_serial _set_ver(register_serial, 3425f38c)
#define unregister_serial _set_ver(unregister_serial, c013d717)
#define tty_hangup _set_ver(tty_hangup, e3487df0)
#define tty_wait_until_sent _set_ver(tty_wait_until_sent, da85d428)
#define tty_check_change _set_ver(tty_check_change, 705eaab0)
#define tty_hung_up_p _set_ver(tty_hung_up_p, f99ac1e4)
#define register_filesystem _set_ver(register_filesystem, 1c7110ef)
#define unregister_filesystem _set_ver(unregister_filesystem, 5e353af7)
#define register_binfmt _set_ver(register_binfmt, 66ece706)
#define unregister_binfmt _set_ver(unregister_binfmt, 41822618)
#define lookup_exec_domain _set_ver(lookup_exec_domain, 32f10d48)
#define register_exec_domain _set_ver(register_exec_domain, eda4711f)
#define unregister_exec_domain _set_ver(unregister_exec_domain, 78ea447c)
#define request_irq _set_ver(request_irq, 9e81629c)
#define free_irq _set_ver(free_irq, f487dc0c)
#define enable_irq _set_ver(enable_irq, 54e09f5f)
#define disable_irq _set_ver(disable_irq, b4449c1f)
#define bh_active _set_ver(bh_active, 98fb5ca1)
#define bh_mask _set_ver(bh_mask, 1abf3d3f)
#define add_timer _set_ver(add_timer, f13cb728)
#define del_timer _set_ver(del_timer, c7aff713)
#define tq_timer _set_ver(tq_timer, 46cf583e)
#define tq_immediate _set_ver(tq_immediate, 46cf583e)
#define tq_scheduler _set_ver(tq_scheduler, 46cf583e)
#define tq_last _set_ver(tq_last, 457cf547)
#define timer_active _set_ver(timer_active, 5a6747ee)
#define timer_table _set_ver(timer_table, 9e03b650)
#define request_dma _set_ver(request_dma, 2a687646)
#define free_dma _set_ver(free_dma, 5d4b914c)
#define disable_hlt _set_ver(disable_hlt, 794487ee)
#define enable_hlt _set_ver(enable_hlt, 9c7077bd)
#define check_region _set_ver(check_region, b91154fb)
#define request_region _set_ver(request_region, 138b0a1e)
#define release_region _set_ver(release_region, f41d6d31)
#define wake_up _set_ver(wake_up, e8d71419)
#define wake_up_interruptible _set_ver(wake_up_interruptible, 64c8cb92)
#define sleep_on _set_ver(sleep_on, 67a00cee)
#define interruptible_sleep_on _set_ver(interruptible_sleep_on, 6a5fc80d)
#define schedule _set_ver(schedule, 01000e51)
#define current _set_ver(current, fc1cb29b)
#define jiffies _set_ver(jiffies, 2f7c7437)
#define xtime _set_ver(xtime, e70c0be0)
#define loops_per_sec _set_ver(loops_per_sec, 40a14192)
#define need_resched _set_ver(need_resched, dfc016ea)
#define kill_proc _set_ver(kill_proc, 911f760a)
#define kill_pg _set_ver(kill_pg, 0a758a45)
#define kill_sl _set_ver(kill_sl, 49625e94)
#define panic _set_ver(panic, 400c0de3)
#define printk _set_ver(printk, ad1148ba)
#define sprintf _set_ver(sprintf, f9003107)
#define vsprintf _set_ver(vsprintf, e605cb6b)
#define simple_strtoul _set_ver(simple_strtoul, bdb8c1e3)
#define system_utsname _set_ver(system_utsname, 066845bc)
#define sys_call_table _set_ver(sys_call_table, 79fa4011)
#define do_signal _set_ver(do_signal, 86f9bc59)
#define send_sig _set_ver(send_sig, 5cddd8d9)
#define setup_arg_pages _set_ver(setup_arg_pages, fe68d94a)
#define copy_strings _set_ver(copy_strings, 232aee96)
#define create_tables _set_ver(create_tables, ba788fa2)
#define do_execve _set_ver(do_execve, 8c99dc0a)
#define flush_old_exec _set_ver(flush_old_exec, c737e178)
#define open_inode _set_ver(open_inode, 27302cb6)
#define read_exec _set_ver(read_exec, a80a2dd0)
#define si_meminfo _set_ver(si_meminfo, bb05fc9a)
#define sock_register _set_ver(sock_register, d68e1649)
#define sock_unregister _set_ver(sock_unregister, 72c332bd)
#define inet_add_protocol _set_ver(inet_add_protocol, 55292121)
#define inet_del_protocol _set_ver(inet_del_protocol, 73908a1b)
#define slhc_init _set_ver(slhc_init, e490a4b8)
#define slhc_free _set_ver(slhc_free, 39ab902b)
#define slhc_remember _set_ver(slhc_remember, db333be6)
#define slhc_compress _set_ver(slhc_compress, e753e2d2)
#define slhc_uncompress _set_ver(slhc_uncompress, 81cc1144)
#define register_netdevice_notifier _set_ver(register_netdevice_notifier, e7aace7c)
#define unregister_netdevice_notifier _set_ver(unregister_netdevice_notifier, be114416)
#define floppy_track_buffer _set_ver(floppy_track_buffer, c6e3f7c2)
#define register_netdev _set_ver(register_netdev, 0d8d1bb4)
#define unregister_netdev _set_ver(unregister_netdev, 25a99579)
#define ether_setup _set_ver(ether_setup, 4eafef91)
#define alloc_skb _set_ver(alloc_skb, b6b523ba)
#define kfree_skb _set_ver(kfree_skb, 0b938572)
#define dev_kfree_skb _set_ver(dev_kfree_skb, aa1fe7f4)
#define netif_rx _set_ver(netif_rx, d8051cb2)
#define dev_rint _set_ver(dev_rint, 040d3f4b)
#define dev_tint _set_ver(dev_tint, 860b350b)
#define irq2dev_map _set_ver(irq2dev_map, 10bdcd8a)
#define dev_add_pack _set_ver(dev_add_pack, 6d7d9be4)
#define dev_remove_pack _set_ver(dev_remove_pack, 784fa59f)
#define dev_get _set_ver(dev_get, 72ed90fd)
#define dev_ioctl _set_ver(dev_ioctl, 08760203)
#define dev_queue_xmit _set_ver(dev_queue_xmit, 4a478225)
#define dev_base _set_ver(dev_base, 0a8809f0)
#define dev_close _set_ver(dev_close, 9bdad56d)
#define arp_find _set_ver(arp_find, a141bd11)
#define n_tty_ioctl _set_ver(n_tty_ioctl, 538e5fa6)
#define tty_register_ldisc _set_ver(tty_register_ldisc, 8fdde939)
#define kill_fasync _set_ver(kill_fasync, 890501b6)
#define in_scan_scsis _set_ver(in_scan_scsis, 21874a88)
#define scsi_register_module _set_ver(scsi_register_module, 8eff1010)
#define scsi_unregister_module _set_ver(scsi_unregister_module, d913b8f0)
#define scsi_free _set_ver(scsi_free, 475dddfa)
#define scsi_malloc _set_ver(scsi_malloc, 1cce3f92)
#define scsi_register _set_ver(scsi_register, d6e77069)
#define scsi_unregister _set_ver(scsi_unregister, 3b0b616b)
#define scsicam_bios_param _set_ver(scsicam_bios_param, 3d965248)
#define scsi_init_malloc _set_ver(scsi_init_malloc, e5167cbc)
#define scsi_init_free _set_ver(scsi_init_free, 8b2721f8)
#define print_command _set_ver(print_command, 6f14cd75)
#define print_msg _set_ver(print_msg, 0465f877)
#define print_status _set_ver(print_status, 32f84646)
#define set_writetime _set_ver(set_writetime, 52131916)
#define sys_tz _set_ver(sys_tz, aa3c9782)
#define __wait_on_super _set_ver(__wait_on_super, 61a5c00a)
#define file_fsync _set_ver(file_fsync, d30a190f)
#define clear_inode _set_ver(clear_inode, da2b0e9f)
#define refile_buffer _set_ver(refile_buffer, 8c69e123)
#define ___strtok _set_ver(___strtok, 8b55d69c)
#define init_fifo _set_ver(init_fifo, 082629c7)
#define super_blocks _set_ver(super_blocks, e1f1ee99)
#define chrdev_inode_operations _set_ver(chrdev_inode_operations, 6ba1faa3)
#define blkdev_inode_operations _set_ver(blkdev_inode_operations, ed443696)
#define read_ahead _set_ver(read_ahead, bbcd3768)
#define get_hash_table _set_ver(get_hash_table, 3b5f3c55)
#define get_empty_inode _set_ver(get_empty_inode, 554bdc75)
#define insert_inode_hash _set_ver(insert_inode_hash, 59b8c371)
#define event _set_ver(event, a6aac9c1)
#define __down _set_ver(__down, 75aa9e96)
#endif /* _KSYMS_VER_ */
#endif /* CONFIG_MODVERSIONS !__GENKSYMS__ */
/**** This file is generated by genksyms DO NOT EDIT! ****/
#if defined(CONFIG_MODVERSIONS) && !defined(__GENKSYMS__)
#ifndef _KSYMS_VER_
#define _KSYMS_VER_
#define rename_module_symbol _set_ver(rename_module_symbol, b81c73c1)
#define register_symtab _set_ver(register_symtab, e910ea66)
#define EISA_bus _set_ver(EISA_bus, 7e37737c)
#define wp_works_ok _set_ver(wp_works_ok, f37f99e9)
#define verify_area _set_ver(verify_area, 4cfda560)
#define do_mmap _set_ver(do_mmap, 677e7ee1)
#define do_munmap _set_ver(do_munmap, 6221f117)
#define zeromap_page_range _set_ver(zeromap_page_range, 7c395a26)
#define unmap_page_range _set_ver(unmap_page_range, 0110085f)
#define insert_vm_struct _set_ver(insert_vm_struct, 1f4e4882)
#define merge_segments _set_ver(merge_segments, 6854be5a)
#define __get_free_pages _set_ver(__get_free_pages, 5243d78b)
#define free_pages _set_ver(free_pages, 96448859)
#define kmalloc _set_ver(kmalloc, d31fb2cb)
#define kfree_s _set_ver(kfree_s, 1e72eb79)
#define vmalloc _set_ver(vmalloc, 667f3e25)
#define vfree _set_ver(vfree, 6df52add)
#define getname _set_ver(getname, 81487159)
#define putname _set_ver(putname, b19e8126)
#define __iget _set_ver(__iget, ee2b6320)
#define iput _set_ver(iput, 59241ced)
#define namei _set_ver(namei, 00478bcd)
#define lnamei _set_ver(lnamei, fcfddbb1)
#define open_namei _set_ver(open_namei, 414b2b0f)
#define close_fp _set_ver(close_fp, 1d4c15d8)
#define check_disk_change _set_ver(check_disk_change, b66ed457)
#define invalidate_buffers _set_ver(invalidate_buffers, c65255f1)
#define fsync_dev _set_ver(fsync_dev, a221190d)
#define permission _set_ver(permission, 0ebf7474)
#define inode_setattr _set_ver(inode_setattr, 0c80a3c1)
#define inode_change_ok _set_ver(inode_change_ok, 5d1cb326)
#define generic_mmap _set_ver(generic_mmap, d4ff59f3)
#define set_blocksize _set_ver(set_blocksize, f45fda38)
#define getblk _set_ver(getblk, d40228ac)
#define bread _set_ver(bread, c73bf0f0)
#define breada _set_ver(breada, eb8e858c)
#define brelse _set_ver(brelse, 4c27ac3d)
#define ll_rw_block _set_ver(ll_rw_block, f3aa4dd3)
#define __wait_on_buffer _set_ver(__wait_on_buffer, e8fcc968)
#define dcache_lookup _set_ver(dcache_lookup, 83336566)
#define dcache_add _set_ver(dcache_add, fe71f11e)
#define register_chrdev _set_ver(register_chrdev, da99513f)
#define unregister_chrdev _set_ver(unregister_chrdev, 61ea5ee8)
#define register_blkdev _set_ver(register_blkdev, 4699a621)
#define unregister_blkdev _set_ver(unregister_blkdev, d39bbca9)
#define tty_register_driver _set_ver(tty_register_driver, fcc8591c)
#define tty_unregister_driver _set_ver(tty_unregister_driver, c78132a8)
#define tty_std_termios _set_ver(tty_std_termios, cf350678)
#define block_read _set_ver(block_read, a7fe4f51)
#define block_write _set_ver(block_write, 902674c9)
#define block_fsync _set_ver(block_fsync, 182888d8)
#define wait_for_request _set_ver(wait_for_request, 9ca2932e)
#define blksize_size _set_ver(blksize_size, dea1eb55)
#define hardsect_size _set_ver(hardsect_size, ed1ee14f)
#define blk_size _set_ver(blk_size, f60b5398)
#define blk_dev _set_ver(blk_dev, dbf5fdd4)
#define is_read_only _set_ver(is_read_only, b0c5f83e)
#define set_device_ro _set_ver(set_device_ro, 8fb69e13)
#define bmap _set_ver(bmap, 73bb8bdd)
#define sync_dev _set_ver(sync_dev, 9bca536d)
#define get_blkfops _set_ver(get_blkfops, 83827791)
#define register_serial _set_ver(register_serial, 3425f38c)
#define unregister_serial _set_ver(unregister_serial, c013d717)
#define tty_hangup _set_ver(tty_hangup, e3487df0)
#define tty_wait_until_sent _set_ver(tty_wait_until_sent, da85d428)
#define tty_check_change _set_ver(tty_check_change, 705eaab0)
#define tty_hung_up_p _set_ver(tty_hung_up_p, f99ac1e4)
#define register_filesystem _set_ver(register_filesystem, 1c7110ef)
#define unregister_filesystem _set_ver(unregister_filesystem, 5e353af7)
#define register_binfmt _set_ver(register_binfmt, 66ece706)
#define unregister_binfmt _set_ver(unregister_binfmt, 41822618)
#define lookup_exec_domain _set_ver(lookup_exec_domain, 32f10d48)
#define register_exec_domain _set_ver(register_exec_domain, eda4711f)
#define unregister_exec_domain _set_ver(unregister_exec_domain, 78ea447c)
#define request_irq _set_ver(request_irq, 9e81629c)
#define free_irq _set_ver(free_irq, f487dc0c)
#define enable_irq _set_ver(enable_irq, 54e09f5f)
#define disable_irq _set_ver(disable_irq, b4449c1f)
#define bh_active _set_ver(bh_active, 98fb5ca1)
#define bh_mask _set_ver(bh_mask, 1abf3d3f)
#define add_timer _set_ver(add_timer, f13cb728)
#define del_timer _set_ver(del_timer, c7aff713)
#define tq_timer _set_ver(tq_timer, 46cf583e)
#define tq_immediate _set_ver(tq_immediate, 46cf583e)
#define tq_scheduler _set_ver(tq_scheduler, 46cf583e)
#define tq_last _set_ver(tq_last, 457cf547)
#define timer_active _set_ver(timer_active, 5a6747ee)
#define timer_table _set_ver(timer_table, 9e03b650)
#define request_dma _set_ver(request_dma, 2a687646)
#define free_dma _set_ver(free_dma, 5d4b914c)
#define disable_hlt _set_ver(disable_hlt, 794487ee)
#define enable_hlt _set_ver(enable_hlt, 9c7077bd)
#define check_region _set_ver(check_region, b91154fb)
#define request_region _set_ver(request_region, 138b0a1e)
#define release_region _set_ver(release_region, f41d6d31)
#define wake_up _set_ver(wake_up, e8d71419)
#define wake_up_interruptible _set_ver(wake_up_interruptible, 64c8cb92)
#define sleep_on _set_ver(sleep_on, 67a00cee)
#define interruptible_sleep_on _set_ver(interruptible_sleep_on, 6a5fc80d)
#define schedule _set_ver(schedule, 01000e51)
#define current _set_ver(current, fc1cb29b)
#define jiffies _set_ver(jiffies, 2f7c7437)
#define xtime _set_ver(xtime, e70c0be0)
#define loops_per_sec _set_ver(loops_per_sec, 40a14192)
#define need_resched _set_ver(need_resched, dfc016ea)
#define kill_proc _set_ver(kill_proc, 911f760a)
#define kill_pg _set_ver(kill_pg, 0a758a45)
#define kill_sl _set_ver(kill_sl, 49625e94)
#define panic _set_ver(panic, 400c0de3)
#define printk _set_ver(printk, ad1148ba)
#define sprintf _set_ver(sprintf, f9003107)
#define vsprintf _set_ver(vsprintf, e605cb6b)
#define simple_strtoul _set_ver(simple_strtoul, bdb8c1e3)
#define system_utsname _set_ver(system_utsname, 066845bc)
#define sys_call_table _set_ver(sys_call_table, 79fa4011)
#define do_signal _set_ver(do_signal, 86f9bc59)
#define send_sig _set_ver(send_sig, 5cddd8d9)
#define setup_arg_pages _set_ver(setup_arg_pages, fe68d94a)
#define copy_strings _set_ver(copy_strings, 232aee96)
#define create_tables _set_ver(create_tables, ba788fa2)
#define do_execve _set_ver(do_execve, 8c99dc0a)
#define flush_old_exec _set_ver(flush_old_exec, c737e178)
#define open_inode _set_ver(open_inode, 27302cb6)
#define read_exec _set_ver(read_exec, a80a2dd0)
#define si_meminfo _set_ver(si_meminfo, bb05fc9a)
#define sock_register _set_ver(sock_register, d68e1649)
#define sock_unregister _set_ver(sock_unregister, 72c332bd)
#define inet_add_protocol _set_ver(inet_add_protocol, 55292121)
#define inet_del_protocol _set_ver(inet_del_protocol, 73908a1b)
#define slhc_init _set_ver(slhc_init, e490a4b8)
#define slhc_free _set_ver(slhc_free, 39ab902b)
#define slhc_remember _set_ver(slhc_remember, db333be6)
#define slhc_compress _set_ver(slhc_compress, e753e2d2)
#define slhc_uncompress _set_ver(slhc_uncompress, 81cc1144)
#define register_netdevice_notifier _set_ver(register_netdevice_notifier, e7aace7c)
#define unregister_netdevice_notifier _set_ver(unregister_netdevice_notifier, be114416)
#define floppy_track_buffer _set_ver(floppy_track_buffer, c6e3f7c2)
#define register_netdev _set_ver(register_netdev, 0d8d1bb4)
#define unregister_netdev _set_ver(unregister_netdev, 25a99579)
#define ether_setup _set_ver(ether_setup, 4eafef91)
#define alloc_skb _set_ver(alloc_skb, b6b523ba)
#define kfree_skb _set_ver(kfree_skb, 0b938572)
#define dev_kfree_skb _set_ver(dev_kfree_skb, aa1fe7f4)
#define netif_rx _set_ver(netif_rx, d8051cb2)
#define dev_rint _set_ver(dev_rint, 040d3f4b)
#define dev_tint _set_ver(dev_tint, 860b350b)
#define irq2dev_map _set_ver(irq2dev_map, 10bdcd8a)
#define dev_add_pack _set_ver(dev_add_pack, 6d7d9be4)
#define dev_remove_pack _set_ver(dev_remove_pack, 784fa59f)
#define dev_get _set_ver(dev_get, 72ed90fd)
#define dev_ioctl _set_ver(dev_ioctl, 08760203)
#define dev_queue_xmit _set_ver(dev_queue_xmit, 4a478225)
#define dev_base _set_ver(dev_base, 0a8809f0)
#define dev_close _set_ver(dev_close, 9bdad56d)
#define arp_find _set_ver(arp_find, a141bd11)
#define n_tty_ioctl _set_ver(n_tty_ioctl, 538e5fa6)
#define tty_register_ldisc _set_ver(tty_register_ldisc, 8fdde939)
#define kill_fasync _set_ver(kill_fasync, 890501b6)
#define in_scan_scsis _set_ver(in_scan_scsis, 21874a88)
#define scsi_register_module _set_ver(scsi_register_module, 8eff1010)
#define scsi_unregister_module _set_ver(scsi_unregister_module, d913b8f0)
#define scsi_free _set_ver(scsi_free, 475dddfa)
#define scsi_malloc _set_ver(scsi_malloc, 1cce3f92)
#define scsi_register _set_ver(scsi_register, d6e77069)
#define scsi_unregister _set_ver(scsi_unregister, 3b0b616b)
#define scsicam_bios_param _set_ver(scsicam_bios_param, 3d965248)
#define scsi_init_malloc _set_ver(scsi_init_malloc, e5167cbc)
#define scsi_init_free _set_ver(scsi_init_free, 8b2721f8)
#define print_command _set_ver(print_command, 6f14cd75)
#define print_msg _set_ver(print_msg, 0465f877)
#define print_status _set_ver(print_status, 32f84646)
#define set_writetime _set_ver(set_writetime, 52131916)
#define sys_tz _set_ver(sys_tz, aa3c9782)
#define __wait_on_super _set_ver(__wait_on_super, 61a5c00a)
#define file_fsync _set_ver(file_fsync, d30a190f)
#define clear_inode _set_ver(clear_inode, da2b0e9f)
#define refile_buffer _set_ver(refile_buffer, 8c69e123)
#define ___strtok _set_ver(___strtok, 8b55d69c)
#define init_fifo _set_ver(init_fifo, 082629c7)
#define super_blocks _set_ver(super_blocks, e1f1ee99)
#define chrdev_inode_operations _set_ver(chrdev_inode_operations, 6ba1faa3)
#define blkdev_inode_operations _set_ver(blkdev_inode_operations, ed443696)
#define read_ahead _set_ver(read_ahead, bbcd3768)
#define get_hash_table _set_ver(get_hash_table, 3b5f3c55)
#define get_empty_inode _set_ver(get_empty_inode, 554bdc75)
#define insert_inode_hash _set_ver(insert_inode_hash, 59b8c371)
#define event _set_ver(event, a6aac9c1)
#define __down _set_ver(__down, 75aa9e96)
#endif /* _KSYMS_VER_ */
#endif /* CONFIG_MODVERSIONS !__GENKSYMS__ */
...@@ -11,6 +11,6 @@ MOD_SUB_DIRS := ipv4 ...@@ -11,6 +11,6 @@ MOD_SUB_DIRS := ipv4
ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom
SUB_DIRS := $(ALL_SUB_DIRS) SUB_DIRS := $(ALL_SUB_DIRS)
L_TARGET := network.a L_TARGET := network.a
L_OBJS := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o)) L_OBJS := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/route.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -50,6 +52,7 @@ ...@@ -50,6 +52,7 @@
#include <net/sock.h> #include <net/sock.h>
#include <linux/atalk.h> #include <linux/atalk.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h>
#ifdef CONFIG_ATALK #ifdef CONFIG_ATALK
...@@ -211,7 +214,7 @@ static void atalk_destroy_socket(atalk_socket *sk) ...@@ -211,7 +214,7 @@ static void atalk_destroy_socket(atalk_socket *sk)
/* Called from proc fs */ /* Called from proc fs */
int atalk_get_info(char *buffer, char **start, off_t offset, int length) int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{ {
atalk_socket *s; atalk_socket *s;
int len=0; int len=0;
...@@ -813,7 +816,7 @@ static int atrtr_ioctl(unsigned int cmd, void *arg) ...@@ -813,7 +816,7 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
/* Called from proc fs - just make it print the ifaces neatly */ /* Called from proc fs - just make it print the ifaces neatly */
int atalk_if_get_info(char *buffer, char **start, off_t offset, int length) int atalk_if_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{ {
struct atalk_iface *iface; struct atalk_iface *iface;
int len=0; int len=0;
...@@ -846,7 +849,7 @@ int atalk_if_get_info(char *buffer, char **start, off_t offset, int length) ...@@ -846,7 +849,7 @@ int atalk_if_get_info(char *buffer, char **start, off_t offset, int length)
/* Called from proc fs - just make it print the routes neatly */ /* Called from proc fs - just make it print the routes neatly */
int atalk_rt_get_info(char *buffer, char **start, off_t offset, int length) int atalk_rt_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{ {
struct atalk_route *rt; struct atalk_route *rt;
int len=0; int len=0;
...@@ -1873,6 +1876,7 @@ void atalk_proto_init(struct net_proto *pro) ...@@ -1873,6 +1876,7 @@ void atalk_proto_init(struct net_proto *pro)
proc_net_register(&(struct proc_dir_entry) { proc_net_register(&(struct proc_dir_entry) {
PROC_NET_AT_ROUTE, 11,"atalk_route", PROC_NET_AT_ROUTE, 11,"atalk_route",
S_IFREG | S_IRUGO, 1, 0, 0, S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
atalk_rt_get_info atalk_rt_get_info
}); });
proc_net_register(&(struct proc_dir_entry) { proc_net_register(&(struct proc_dir_entry) {
......
...@@ -12,7 +12,7 @@ O_TARGET := ax25.o ...@@ -12,7 +12,7 @@ O_TARGET := ax25.o
O_OBJS := af_ax25.o O_OBJS := af_ax25.o
ifdef CONFIG_AX25 ifdef CONFIG_AX25
OBJS += ax25_in.o ax25_out.o ax25_route.o ax25_subr.o ax25_timer.o O_OBJS += ax25_in.o ax25_out.o ax25_route.o ax25_subr.o ax25_timer.o
endif endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
...@@ -63,12 +63,10 @@ ...@@ -63,12 +63,10 @@
* Added AX.25 frame segmentation. * Added AX.25 frame segmentation.
* *
* To do: * To do:
* Support use as digipeater, including an on/off ioctl
* Restructure the ax25_rcv code to be cleaner/faster and * Restructure the ax25_rcv code to be cleaner/faster and
* copy only when needed. * copy only when needed.
* Consider better arbitary protocol support. * Consider better arbitary protocol support.
* Fix non-blocking connect failure. * Fix non-blocking connect failure.
* VC mode doesnt work on the PI card.
* Settable protocol id for SEQPACKET sockets * Settable protocol id for SEQPACKET sockets
*/ */
...@@ -87,6 +85,7 @@ ...@@ -87,6 +85,7 @@
#include <net/ax25.h> #include <net/ax25.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/segment.h> #include <asm/segment.h>
...@@ -97,6 +96,7 @@ ...@@ -97,6 +96,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/arp.h> #include <net/arp.h>
...@@ -213,8 +213,6 @@ static void ax25_kill_by_device(struct device *dev) ...@@ -213,8 +213,6 @@ static void ax25_kill_by_device(struct device *dev)
} }
} }
} }
ax25_rt_device_down(dev);
} }
/* /*
...@@ -222,11 +220,21 @@ static void ax25_kill_by_device(struct device *dev) ...@@ -222,11 +220,21 @@ static void ax25_kill_by_device(struct device *dev)
*/ */
static int ax25_device_event(unsigned long event, void *ptr) static int ax25_device_event(unsigned long event, void *ptr)
{ {
if (event != NETDEV_DOWN) struct device *dev = (struct device *)ptr;
return NOTIFY_DONE;
switch (event) {
ax25_kill_by_device(ptr); case NETDEV_UP:
ax25_dev_device_up(dev);
break;
case NETDEV_DOWN:
ax25_kill_by_device(dev);
ax25_rt_device_down(dev);
ax25_dev_device_down(dev);
break;
default:
break;
}
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -514,16 +522,17 @@ static ax25_cb *ax25_create_cb(void) ...@@ -514,16 +522,17 @@ static ax25_cb *ax25_create_cb(void)
init_timer(&ax25->timer); init_timer(&ax25->timer);
ax25->rtt = DEFAULT_T1; ax25->rtt = (AX25_DEF_T1 * PR_SLOWHZ) / 2;
ax25->t1 = DEFAULT_T1; ax25->t1 = AX25_DEF_T1 * PR_SLOWHZ;
ax25->t2 = DEFAULT_T2; ax25->t2 = AX25_DEF_T2 * PR_SLOWHZ;
ax25->n2 = DEFAULT_N2; ax25->t3 = AX25_DEF_T3 * PR_SLOWHZ;
ax25->t3 = DEFAULT_T3; ax25->n2 = AX25_DEF_N2;
ax25->modulus = MODULUS; ax25->modulus = AX25_DEF_AXDEFMODE;
ax25->fragno = 0; ax25->fragno = 0;
ax25->fraglen = 0; ax25->fraglen = 0;
ax25->backoff = 1; ax25->hdrincl = 0;
ax25->backoff = AX25_DEF_BACKOFF == 'E';
ax25->condition = 0x00; ax25->condition = 0x00;
ax25->t1timer = 0; ax25->t1timer = 0;
ax25->t2timer = 0; ax25->t2timer = 0;
...@@ -534,7 +543,11 @@ static ax25_cb *ax25_create_cb(void) ...@@ -534,7 +543,11 @@ static ax25_cb *ax25_create_cb(void)
ax25->vr = 0; ax25->vr = 0;
ax25->vs = 0; ax25->vs = 0;
ax25->window = DEFAULT_WINDOW; if (AX25_DEF_AXDEFMODE == EMODULUS) {
ax25->window = AX25_DEF_EWINDOW;
} else {
ax25->window = AX25_DEF_WINDOW;
}
ax25->device = NULL; ax25->device = NULL;
ax25->digipeat = NULL; ax25->digipeat = NULL;
ax25->sk = NULL; ax25->sk = NULL;
...@@ -547,6 +560,31 @@ static ax25_cb *ax25_create_cb(void) ...@@ -547,6 +560,31 @@ static ax25_cb *ax25_create_cb(void)
return ax25; return ax25;
} }
/*
* Fill in a created AX.25 created control block with the default
* values for a particular device.
*/
static void ax25_fillin_cb(ax25_cb *ax25, struct device *dev)
{
ax25->device = dev;
ax25->rtt = ax25_dev_get_value(dev, AX25_VALUES_T1);
ax25->t1 = ax25_dev_get_value(dev, AX25_VALUES_T1);
ax25->t2 = ax25_dev_get_value(dev, AX25_VALUES_T2);
ax25->t3 = ax25_dev_get_value(dev, AX25_VALUES_T3);
ax25->n2 = ax25_dev_get_value(dev, AX25_VALUES_N2);
ax25->modulus = ax25_dev_get_value(dev, AX25_VALUES_AXDEFMODE);
if (ax25->modulus == MODULUS) {
ax25->window = ax25_dev_get_value(dev, AX25_VALUES_WINDOW);
} else {
ax25->window = ax25_dev_get_value(dev, AX25_VALUES_EWINDOW);
}
ax25->backoff = ax25_dev_get_value(dev, AX25_VALUES_BACKOFF) == 'E';
}
int ax25_send_frame(struct sk_buff *skb, ax25_address *src, ax25_address *dest, int ax25_send_frame(struct sk_buff *skb, ax25_address *src, ax25_address *dest,
ax25_digi *digi, struct device *dev) ax25_digi *digi, struct device *dev)
{ {
...@@ -571,7 +609,7 @@ int ax25_send_frame(struct sk_buff *skb, ax25_address *src, ax25_address *dest, ...@@ -571,7 +609,7 @@ int ax25_send_frame(struct sk_buff *skb, ax25_address *src, ax25_address *dest,
if ((ax25 = ax25_create_cb()) == NULL) if ((ax25 = ax25_create_cb()) == NULL)
return 0; return 0;
ax25->device = dev; ax25_fillin_cb(ax25, dev);
memcpy(&ax25->source_addr, src, sizeof(ax25_address)); memcpy(&ax25->source_addr, src, sizeof(ax25_address));
memcpy(&ax25->dest_addr, dest, sizeof(ax25_address)); memcpy(&ax25->dest_addr, dest, sizeof(ax25_address));
...@@ -709,6 +747,10 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, ...@@ -709,6 +747,10 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
sk->ax25->modulus = opt ? EMODULUS : MODULUS; sk->ax25->modulus = opt ? EMODULUS : MODULUS;
return 0; return 0;
case AX25_HDRINCL:
sk->ax25->hdrincl = opt ? 1 : 0;
return 0;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
...@@ -735,7 +777,7 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname, ...@@ -735,7 +777,7 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname,
break; break;
case AX25_T1: case AX25_T1:
val = sk->ax25->t1 / PR_SLOWHZ; val = (sk->ax25->t1 * 2) / PR_SLOWHZ;
break; break;
case AX25_T2: case AX25_T2:
...@@ -756,7 +798,11 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname, ...@@ -756,7 +798,11 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname,
case AX25_EXTSEQ: case AX25_EXTSEQ:
val = (sk->ax25->modulus == EMODULUS); val = (sk->ax25->modulus == EMODULUS);
return 0; break;
case AX25_HDRINCL:
val = sk->ax25->hdrincl;
break;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
...@@ -884,6 +930,8 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev) ...@@ -884,6 +930,8 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev)
return NULL; return NULL;
} }
ax25_fillin_cb(ax25, dev);
sk->type = osk->type; sk->type = osk->type;
sk->socket = osk->socket; sk->socket = osk->socket;
...@@ -933,6 +981,7 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev) ...@@ -933,6 +981,7 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev)
ax25->modulus = osk->ax25->modulus; ax25->modulus = osk->ax25->modulus;
ax25->backoff = osk->ax25->backoff; ax25->backoff = osk->ax25->backoff;
ax25->hdrincl = osk->ax25->hdrincl;
ax25->rtt = osk->ax25->rtt; ax25->rtt = osk->ax25->rtt;
ax25->t1 = osk->ax25->t1; ax25->t1 = osk->ax25->t1;
ax25->t2 = osk->ax25->t2; ax25->t2 = osk->ax25->t2;
...@@ -940,7 +989,6 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev) ...@@ -940,7 +989,6 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev)
ax25->n2 = osk->ax25->n2; ax25->n2 = osk->ax25->n2;
ax25->window = osk->ax25->window; ax25->window = osk->ax25->window;
ax25->device = dev;
memcpy(&ax25->source_addr, &osk->ax25->source_addr, sizeof(ax25_address)); memcpy(&ax25->source_addr, &osk->ax25->source_addr, sizeof(ax25_address));
...@@ -1073,7 +1121,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len) ...@@ -1073,7 +1121,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
} }
sk->ax25->device = dev; ax25_fillin_cb(sk->ax25, dev);
ax25_insert_socket(sk->ax25); ax25_insert_socket(sk->ax25);
sk->zapped = 0; sk->zapped = 0;
...@@ -1298,6 +1346,7 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a ...@@ -1298,6 +1346,7 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
/* /*
* Process the AX.25/LAPB frame. * Process the AX.25/LAPB frame.
*/ */
skb->h.raw = skb->data;
/* /*
* Parse the address header. * Parse the address header.
...@@ -1310,7 +1359,7 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a ...@@ -1310,7 +1359,7 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
/* /*
* Send the frame to the AX.25 auto-router * Send the frame to the AX.25 auto-router
*/ */
ax25_rt_rx_frame(&src, dev); ax25_rt_rx_frame(&src, dev, &dp);
/* /*
* Ours perhaps ? * Ours perhaps ?
...@@ -1413,6 +1462,16 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a ...@@ -1413,6 +1462,16 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
return 0; return 0;
} }
/*
* Is connected mode supported on this device ?
* If not, should we DM the incoming frame (except DMs) or
* silently ignore them. For now we stay quiet.
*/
if (!ax25_dev_get_value(dev, AX25_VALUES_CONMODE)) {
kfree_skb(skb, FREE_READ);
return 0;
}
/* LAPB */ /* LAPB */
if ((ax25 = ax25_find_cb(&dest, &src, dev)) != NULL) { if ((ax25 = ax25_find_cb(&dest, &src, dev)) != NULL) {
...@@ -1469,6 +1528,8 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a ...@@ -1469,6 +1528,8 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
return 0; return 0;
} }
ax25_fillin_cb(ax25, dev);
#else #else
if (mine) if (mine)
ax25_return_dm(dev, &src, &dest, &dp); ax25_return_dm(dev, &src, &dest, &dp);
...@@ -1502,8 +1563,10 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a ...@@ -1502,8 +1563,10 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
if ((*skb->data & ~PF) == SABME) { if ((*skb->data & ~PF) == SABME) {
ax25->modulus = EMODULUS; ax25->modulus = EMODULUS;
ax25->window = ax25_dev_get_value(dev, AX25_VALUES_EWINDOW);
} else { } else {
ax25->modulus = MODULUS; ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(dev, AX25_VALUES_WINDOW);
} }
ax25->device = dev; ax25->device = dev;
...@@ -1733,10 +1796,9 @@ static int ax25_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, ...@@ -1733,10 +1796,9 @@ static int ax25_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
struct sock *sk = (struct sock *)sock->data; struct sock *sk = (struct sock *)sock->data;
struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)sip; struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)sip;
char *addrptr = (char *)sip; char *addrptr = (char *)sip;
int copied = 0; int copied, length;
struct sk_buff *skb; struct sk_buff *skb;
int er; int er;
int bias = 0;
if (sk->err) { if (sk->err) {
er = -sk->err; er = -sk->err;
...@@ -1747,19 +1809,28 @@ static int ax25_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, ...@@ -1747,19 +1809,28 @@ static int ax25_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
if (addr_len != NULL) if (addr_len != NULL)
*addr_len = sizeof(*sax); *addr_len = sizeof(*sax);
/* This works for seqpacket too. The receiver has ordered the queue for us! We do one quick check first though */ /*
if (sk->type == SOCK_SEQPACKET) { * This works for seqpacket too. The receiver has ordered the
if (sk->state != TCP_ESTABLISHED) * queue for us! We do one quick check first though
return -ENOTCONN; */
bias = 1; if (sk->type == SOCK_SEQPACKET && sk->state != TCP_ESTABLISHED)
} return -ENOTCONN;
/* Now we can treat all alike */ /* Now we can treat all alike */
if ((skb = skb_recv_datagram(sk, flags, noblock, &er)) == NULL) if ((skb = skb_recv_datagram(sk, flags, noblock, &er)) == NULL)
return er; return er;
copied = (size < skb->len - bias) ? size : skb->len - bias; if (sk->ax25->hdrincl) {
skb_copy_datagram(skb, bias, ubuf, copied); length = skb->len + (skb->data - skb->h.raw);
} else {
if (sk->type == SOCK_SEQPACKET)
skb_pull(skb, 1); /* Remove PID */
length = skb->len;
skb->h.raw = skb->data;
}
copied = (size < length) ? size : length;
skb_copy_datagram(skb, 0, ubuf, copied);
if (sax) { if (sax) {
struct sockaddr_ax25 addr; struct sockaddr_ax25 addr;
...@@ -1887,6 +1958,16 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1887,6 +1958,16 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
ax25_digi_on = amount ? 1 : 0; ax25_digi_on = amount ? 1 : 0;
return 0; return 0;
case SIOCAX25GETPARMS:
case SIOCAX25SETPARMS:
return ax25_dev_ioctl(cmd, (void *)arg);
case SIOCADDRT:
case SIOCDELRT:
if (!suser())
return -EPERM;
return ax25_rt_ioctl(cmd, (void *)arg);
case SIOCGIFADDR: case SIOCGIFADDR:
case SIOCSIFADDR: case SIOCSIFADDR:
case SIOCGIFDSTADDR: case SIOCGIFDSTADDR:
...@@ -1907,7 +1988,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1907,7 +1988,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return(0); return(0);
} }
int ax25_get_info(char *buffer, char **start, off_t offset, int length, int dummy) static int ax25_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{ {
ax25_cb *ax25; ax25_cb *ax25;
struct device *dev; struct device *dev;
...@@ -2050,7 +2131,7 @@ void ax25_proto_init(struct net_proto *pro) ...@@ -2050,7 +2131,7 @@ void ax25_proto_init(struct net_proto *pro)
ax25_cs_get_info ax25_cs_get_info
}); });
printk("GW4PTS/G4KLX AX.25 for Linux. Version 0.30 ALPHA for Linux NET3.030 (Linux 1.3.0)\n"); printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.30 ALPHA for Linux NET3.030 (Linux 1.3.20)\n");
} }
/* /*
...@@ -2158,8 +2239,7 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des ...@@ -2158,8 +2239,7 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des
if (bp[16] == AX25_P_IP) { if (bp[16] == AX25_P_IP) {
mode = ax25_ip_mode_get((ax25_address *)(bp + 1), dev); mode = ax25_ip_mode_get((ax25_address *)(bp + 1), dev);
if (mode == 'V' || mode == 'v' || (mode == ' ' && ax25_dev_get_value(dev, AX25_VALUES_IPDEFMODE) == 'V')) {
if (mode == 'V' || mode == 'v' || (mode == ' ' && sl_get_ax25_mode(dev))) {
skb_device_unlock(skb); skb_device_unlock(skb);
skb_pull(skb, AX25_HEADER_LEN - 1); /* Keep PID */ skb_pull(skb, AX25_HEADER_LEN - 1); /* Keep PID */
ax25_send_frame(skb, (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev); ax25_send_frame(skb, (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev);
......
...@@ -64,6 +64,7 @@ static int ax25_rx_iframe(ax25_cb *, struct sk_buff *); ...@@ -64,6 +64,7 @@ static int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb) static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
{ {
struct sk_buff *skbn, *skbo; struct sk_buff *skbn, *skbo;
int hdrlen;
if (ax25->fragno != 0) { if (ax25->fragno != 0) {
if (!(*skb->data & SEG_FIRST)) { if (!(*skb->data & SEG_FIRST)) {
...@@ -86,6 +87,14 @@ static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb) ...@@ -86,6 +87,14 @@ static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
} }
skb_reserve(skbn, AX25_MAX_HEADER_LEN); skb_reserve(skbn, AX25_MAX_HEADER_LEN);
skbn->h.raw = skbn->data;
skbo = skb_dequeue(&ax25->frag_queue);
hdrlen = skbo->data - skbo->h.raw;
skb_push(skbo, hdrlen);
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
skb_pull(skbn, hdrlen);
kfree_skb(skbo, FREE_READ);
while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) { while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len); memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
...@@ -122,13 +131,13 @@ static int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb) ...@@ -122,13 +131,13 @@ static int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
{ {
int queued = 0; int queued = 0;
skb->h.raw = skb->data;
switch (*skb->data) { switch (*skb->data) {
#ifdef CONFIG_NETROM #ifdef CONFIG_NETROM
case AX25_P_NETROM: case AX25_P_NETROM:
skb_pull(skb, 1); /* Remove PID */ if (ax25_dev_get_value(ax25->device, AX25_VALUES_NETROM)) {
queued = nr_route_frame(skb, ax25); skb_pull(skb, 1); /* Remove PID */
queued = nr_route_frame(skb, ax25);
}
break; break;
#endif #endif
#ifdef CONFIG_INET #ifdef CONFIG_INET
...@@ -141,7 +150,7 @@ static int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb) ...@@ -141,7 +150,7 @@ static int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
break; break;
#endif #endif
case AX25_P_TEXT: case AX25_P_TEXT:
if (ax25->sk != NULL) { if (ax25->sk != NULL && ax25_dev_get_value(ax25->device, AX25_VALUES_TEXT)) {
if (sock_queue_rcv_skb(ax25->sk, skb) == 0) { if (sock_queue_rcv_skb(ax25->sk, skb) == 0) {
queued = 1; queued = 1;
} else { } else {
...@@ -172,11 +181,13 @@ static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype ...@@ -172,11 +181,13 @@ static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
switch (frametype) { switch (frametype) {
case SABM: case SABM:
ax25->modulus = MODULUS; ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE); ax25_send_control(ax25, UA, pf, C_RESPONSE);
break; break;
case SABME: case SABME:
ax25->modulus = EMODULUS; ax25->modulus = EMODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE); ax25_send_control(ax25, UA, pf, C_RESPONSE);
break; break;
...@@ -217,6 +228,7 @@ static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype ...@@ -217,6 +228,7 @@ static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
} }
} else { } else {
ax25->modulus = MODULUS; ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
} }
} }
break; break;
...@@ -298,6 +310,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype ...@@ -298,6 +310,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
switch (frametype) { switch (frametype) {
case SABM: case SABM:
ax25->modulus = MODULUS; ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE); ax25_send_control(ax25, UA, pf, C_RESPONSE);
ax25->condition = 0x00; ax25->condition = 0x00;
ax25->t1timer = 0; ax25->t1timer = 0;
...@@ -309,6 +322,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype ...@@ -309,6 +322,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
case SABME: case SABME:
ax25->modulus = EMODULUS; ax25->modulus = EMODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE); ax25_send_control(ax25, UA, pf, C_RESPONSE);
ax25->condition = 0x00; ax25->condition = 0x00;
ax25->t1timer = 0; ax25->t1timer = 0;
...@@ -455,6 +469,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype ...@@ -455,6 +469,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
switch (frametype) { switch (frametype) {
case SABM: case SABM:
ax25->modulus = MODULUS; ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE); ax25_send_control(ax25, UA, pf, C_RESPONSE);
ax25->condition = 0x00; ax25->condition = 0x00;
ax25->t1timer = 0; ax25->t1timer = 0;
...@@ -468,6 +483,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype ...@@ -468,6 +483,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
case SABME: case SABME:
ax25->modulus = EMODULUS; ax25->modulus = EMODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
ax25_send_control(ax25, UA, pf, C_RESPONSE); ax25_send_control(ax25, UA, pf, C_RESPONSE);
ax25->condition = 0x00; ax25->condition = 0x00;
ax25->t1timer = 0; ax25->t1timer = 0;
......
...@@ -286,6 +286,16 @@ void ax25_enquiry_response(ax25_cb *ax25) ...@@ -286,6 +286,16 @@ void ax25_enquiry_response(ax25_cb *ax25)
ax25->condition &= ~ACK_PENDING_CONDITION; ax25->condition &= ~ACK_PENDING_CONDITION;
} }
void ax25_timeout_response(ax25_cb *ax25)
{
if (ax25->condition & OWN_RX_BUSY_CONDITION)
ax25_send_control(ax25, RNR, POLLOFF, C_RESPONSE);
else
ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
ax25->condition &= ~ACK_PENDING_CONDITION;
}
void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr) void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
{ {
if (ax25->vs == nr) { if (ax25->vs == nr) {
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
* removes the heard structure. * removes the heard structure.
* AX.25 029 Steven(GW7RRM) Added /proc information for uid/callsign mapping. * AX.25 029 Steven(GW7RRM) Added /proc information for uid/callsign mapping.
* Jonathan(G4KLX) Handling of IP mode in the routing list and /proc entry. * Jonathan(G4KLX) Handling of IP mode in the routing list and /proc entry.
* AX.25 030 Jonathan(G4KLX) Added digi-peaters to routing table, and
* ioctls to manipulate them. Added port
* configuration.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -55,12 +58,19 @@ static struct ax25_route { ...@@ -55,12 +58,19 @@ static struct ax25_route {
struct ax25_route *next; struct ax25_route *next;
ax25_address callsign; ax25_address callsign;
struct device *dev; struct device *dev;
ax25_digi *digipeat;
struct timeval stamp; struct timeval stamp;
int n; int n;
char ip_mode; char ip_mode;
} *ax25_route = NULL; } *ax25_route = NULL;
void ax25_rt_rx_frame(ax25_address *src, struct device *dev) static struct ax25_dev {
struct ax25_dev *next;
struct device *dev;
unsigned short values[AX25_MAX_VALUES];
} *ax25_device = NULL;
void ax25_rt_rx_frame(ax25_address *src, struct device *dev, ax25_digi *digi)
{ {
unsigned long flags; unsigned long flags;
extern struct timeval xtime; extern struct timeval xtime;
...@@ -72,11 +82,12 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev) ...@@ -72,11 +82,12 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev)
oldest = NULL; oldest = NULL;
for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) { for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
if (count == 0 || ax25_rt->stamp.tv_sec < oldest->stamp.tv_sec) if (count == 0 || (ax25_rt->stamp.tv_sec != 0 && ax25_rt->stamp.tv_sec < oldest->stamp.tv_sec))
oldest = ax25_rt; oldest = ax25_rt;
if (ax25cmp(&ax25_rt->callsign, src) == 0 && ax25_rt->dev == dev) { if (ax25cmp(&ax25_rt->callsign, src) == 0 && ax25_rt->dev == dev) {
ax25_rt->stamp = xtime; if (ax25_rt->stamp.tv_sec != 0)
ax25_rt->stamp = xtime;
ax25_rt->n++; ax25_rt->n++;
return; return;
} }
...@@ -87,6 +98,10 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev) ...@@ -87,6 +98,10 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev)
if (count > AX25_ROUTE_MAX) { if (count > AX25_ROUTE_MAX) {
oldest->callsign = *src; oldest->callsign = *src;
oldest->dev = dev; oldest->dev = dev;
if (oldest->digipeat != NULL) {
kfree_s(oldest->digipeat, sizeof(ax25_digi));
oldest->digipeat = NULL;
}
oldest->stamp = xtime; oldest->stamp = xtime;
oldest->n = 1; oldest->n = 1;
oldest->ip_mode = ' '; oldest->ip_mode = ' ';
...@@ -98,10 +113,19 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev) ...@@ -98,10 +113,19 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev)
ax25_rt->callsign = *src; ax25_rt->callsign = *src;
ax25_rt->dev = dev; ax25_rt->dev = dev;
ax25_rt->digipeat = NULL;
ax25_rt->stamp = xtime; ax25_rt->stamp = xtime;
ax25_rt->n = 1; ax25_rt->n = 1;
ax25_rt->ip_mode = ' '; ax25_rt->ip_mode = ' ';
if (digi != NULL) {
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
kfree_s(ax25_rt, sizeof(struct ax25_route));
return;
}
memcpy(ax25_rt->digipeat, digi, sizeof(ax25_digi));
}
save_flags(flags); save_flags(flags);
cli(); cli();
...@@ -122,11 +146,15 @@ void ax25_rt_device_down(struct device *dev) ...@@ -122,11 +146,15 @@ void ax25_rt_device_down(struct device *dev)
if (s->dev == dev) { if (s->dev == dev) {
if (ax25_route == s) { if (ax25_route == s) {
ax25_route = s->next; ax25_route = s->next;
if (s->digipeat != NULL)
kfree_s((void *)s->digipeat, sizeof(ax25_digi));
kfree_s((void *)s, (sizeof *s)); kfree_s((void *)s, (sizeof *s));
} else { } else {
for (t = ax25_route; t != NULL; t = t->next) { for (t = ax25_route; t != NULL; t = t->next) {
if (t->next == s) { if (t->next == s) {
t->next = s->next; t->next = s->next;
if (s->digipeat != NULL)
kfree_s((void *)s->digipeat, sizeof(ax25_digi));
kfree_s((void *)s, sizeof(*s)); kfree_s((void *)s, sizeof(*s));
break; break;
} }
...@@ -136,16 +164,116 @@ void ax25_rt_device_down(struct device *dev) ...@@ -136,16 +164,116 @@ void ax25_rt_device_down(struct device *dev)
} }
} }
int ax25_rt_ioctl(unsigned int cmd, void *arg)
{
unsigned long flags;
struct ax25_route *s, *t, *ax25_rt;
struct ax25_routes_struct route;
struct device *dev;
int i, err;
switch (cmd) {
case SIOCADDRT:
if ((err = verify_area(VERIFY_READ, arg, sizeof(route))) != 0)
return err;
memcpy_fromfs(&route, arg, sizeof(route));
if ((dev = ax25rtr_get_dev(&route.port_addr)) == NULL)
return -EINVAL;
if (route.digi_count > 6)
return -EINVAL;
for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
if (ax25cmp(&ax25_rt->callsign, &route.dest_addr) == 0 && ax25_rt->dev == dev) {
if (ax25_rt->digipeat != NULL) {
kfree_s(ax25_rt->digipeat, sizeof(ax25_digi));
ax25_rt->digipeat = NULL;
}
if (route.digi_count != 0) {
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
return -ENOMEM;
ax25_rt->digipeat->lastrepeat = 0;
ax25_rt->digipeat->ndigi = route.digi_count;
for (i = 0; i < route.digi_count; i++) {
ax25_rt->digipeat->repeated[i] = 0;
ax25_rt->digipeat->calls[i] = route.digi_addr[i];
}
}
ax25_rt->stamp.tv_sec = 0;
return 0;
}
}
if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
return -ENOMEM;
ax25_rt->callsign = route.dest_addr;
ax25_rt->dev = dev;
ax25_rt->digipeat = NULL;
ax25_rt->stamp.tv_sec = 0;
ax25_rt->n = 0;
ax25_rt->ip_mode = ' ';
if (route.digi_count != 0) {
if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
kfree_s(ax25_rt, sizeof(struct ax25_route));
return -ENOMEM;
}
ax25_rt->digipeat->lastrepeat = 0;
ax25_rt->digipeat->ndigi = route.digi_count;
for (i = 0; i < route.digi_count; i++) {
ax25_rt->digipeat->repeated[i] = 0;
ax25_rt->digipeat->calls[i] = route.digi_addr[i];
}
}
save_flags(flags);
cli();
ax25_rt->next = ax25_route;
ax25_route = ax25_rt;
restore_flags(flags);
break;
case SIOCDELRT:
if ((err = verify_area(VERIFY_READ, arg, sizeof(route))) != 0)
return err;
memcpy_fromfs(&route, arg, sizeof(route));
if ((dev = ax25rtr_get_dev(&route.port_addr)) == NULL)
return -EINVAL;
ax25_rt = ax25_route;
while (ax25_rt != NULL) {
s = ax25_rt;
ax25_rt = ax25_rt->next;
if (s->dev == dev && ax25cmp(&route.dest_addr, &s->callsign) == 0) {
if (ax25_route == s) {
ax25_route = s->next;
if (s->digipeat != NULL)
kfree_s((void *)s->digipeat, sizeof(ax25_digi));
kfree_s((void *)s, (sizeof *s));
} else {
for (t = ax25_route; t != NULL; t = t->next) {
if (t->next == s) {
t->next = s->next;
if (s->digipeat != NULL)
kfree_s((void *)s->digipeat, sizeof(ax25_digi));
kfree_s((void *)s, sizeof(*s));
break;
}
}
}
}
}
break;
}
return 0;
}
int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length, int dummy) int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{ {
struct ax25_route *ax25_rt; struct ax25_route *ax25_rt;
int len = 0; int len = 0;
off_t pos = 0; off_t pos = 0;
off_t begin = 0; off_t begin = 0;
int i;
cli(); cli();
len += sprintf(buffer, "callsign dev count time mode\n"); len += sprintf(buffer, "callsign dev count time mode digipeaters\n");
for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) { for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
len += sprintf(buffer + len, "%-9s %-4s %5d %9d", len += sprintf(buffer + len, "%-9s %-4s %5d %9d",
...@@ -157,16 +285,22 @@ int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length, int d ...@@ -157,16 +285,22 @@ int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length, int d
switch (ax25_rt->ip_mode) { switch (ax25_rt->ip_mode) {
case 'V': case 'V':
case 'v': case 'v':
len += sprintf(buffer + len, " vc\n"); len += sprintf(buffer + len, " vc");
break; break;
case 'D': case 'D':
case 'd': case 'd':
len += sprintf(buffer + len, " dg\n"); len += sprintf(buffer + len, " dg");
break; break;
default: default:
len += sprintf(buffer + len, "\n"); len += sprintf(buffer + len, " ");
break; break;
} }
if (ax25_rt->digipeat != NULL)
for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
len += sprintf(buffer + len, " %s", ax2asc(&ax25_rt->digipeat->calls[i]));
len += sprintf(buffer + len, "\n");
pos = begin + len; pos = begin + len;
...@@ -245,6 +379,11 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) ...@@ -245,6 +379,11 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
call = (ax25_address *)ax25->device->dev_addr; call = (ax25_address *)ax25->device->dev_addr;
} }
memcpy(&ax25->source_addr, call, sizeof(ax25_address)); memcpy(&ax25->source_addr, call, sizeof(ax25_address));
if (ax25_rt->digipeat != NULL) {
if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
return -ENOMEM;
memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
}
if (ax25->sk != NULL) if (ax25->sk != NULL)
ax25->sk->zapped = 0; ax25->sk->zapped = 0;
...@@ -285,4 +424,167 @@ char ax25_ip_mode_get(ax25_address *callsign, struct device *dev) ...@@ -285,4 +424,167 @@ char ax25_ip_mode_get(ax25_address *callsign, struct device *dev)
return ' '; return ' ';
} }
static struct ax25_dev *ax25_dev_get_dev(struct device *dev)
{
struct ax25_dev *s;
for (s = ax25_device; s != NULL; s = s->next)
if (s->dev == dev)
return s;
return NULL;
}
/*
* Wow, a bit of data hiding. Is this C++ or what ?
*/
unsigned short ax25_dev_get_value(struct device *dev, int valueno)
{
struct ax25_dev *ax25_dev;
if ((ax25_dev = ax25_dev_get_dev(dev)) == NULL) {
printk("ax25_dev_get_flag called with invalid device\n");
return 1;
}
return ax25_dev->values[valueno];
}
/*
* This is called when an interface is brought up. These are
* reasonable defaults.
*/
void ax25_dev_device_up(struct device *dev)
{
unsigned long flags;
struct ax25_dev *ax25_dev;
if ((ax25_dev = (struct ax25_dev *)kmalloc(sizeof(struct ax25_dev), GFP_ATOMIC)) == NULL)
return; /* No space */
ax25_dev->dev = dev;
ax25_dev->values[AX25_VALUES_IPDEFMODE] = AX25_DEF_IPDEFMODE;
ax25_dev->values[AX25_VALUES_AXDEFMODE] = AX25_DEF_AXDEFMODE;
ax25_dev->values[AX25_VALUES_NETROM] = AX25_DEF_NETROM;
ax25_dev->values[AX25_VALUES_TEXT] = AX25_DEF_TEXT;
ax25_dev->values[AX25_VALUES_BACKOFF] = AX25_DEF_BACKOFF;
ax25_dev->values[AX25_VALUES_CONMODE] = AX25_DEF_CONMODE;
ax25_dev->values[AX25_VALUES_WINDOW] = AX25_DEF_WINDOW;
ax25_dev->values[AX25_VALUES_EWINDOW] = AX25_DEF_EWINDOW;
ax25_dev->values[AX25_VALUES_T1] = (AX25_DEF_T1 * PR_SLOWHZ) / 2;
ax25_dev->values[AX25_VALUES_T2] = AX25_DEF_T2 * PR_SLOWHZ;
ax25_dev->values[AX25_VALUES_T3] = AX25_DEF_T3 * PR_SLOWHZ;
ax25_dev->values[AX25_VALUES_N2] = AX25_DEF_N2;
save_flags(flags);
cli();
ax25_dev->next = ax25_device;
ax25_device = ax25_dev;
restore_flags(flags);
}
void ax25_dev_device_down(struct device *dev)
{
struct ax25_dev *s, *t, *ax25_dev = ax25_device;
while (ax25_dev != NULL) {
s = ax25_dev;
ax25_dev = ax25_dev->next;
if (s->dev == dev) {
if (ax25_device == s) {
ax25_device = s->next;
kfree_s((void *)s, (sizeof *s));
} else {
for (t = ax25_device; t != NULL; t = t->next) {
if (t->next == s) {
t->next = s->next;
kfree_s((void *)s, sizeof(*s));
break;
}
}
}
}
}
}
int ax25_dev_ioctl(unsigned int cmd, void *arg)
{
struct ax25_parms_struct ax25_parms;
struct device *dev;
struct ax25_dev *ax25_dev;
int err;
switch (cmd) {
case SIOCAX25SETPARMS:
if (!suser())
return -EPERM;
if ((err = verify_area(VERIFY_READ, arg, sizeof(ax25_parms))) != 0)
return err;
memcpy_fromfs(&ax25_parms, arg, sizeof(ax25_parms));
if ((dev = ax25rtr_get_dev(&ax25_parms.port_addr)) == NULL)
return -EINVAL;
if ((ax25_dev = ax25_dev_get_dev(dev)) == NULL)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_IPDEFMODE] != 'D' &&
ax25_parms.values[AX25_VALUES_IPDEFMODE] != 'V')
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_AXDEFMODE] != MODULUS &&
ax25_parms.values[AX25_VALUES_AXDEFMODE] != EMODULUS)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_NETROM] != 0 &&
ax25_parms.values[AX25_VALUES_NETROM] != 1)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_TEXT] != 0 &&
ax25_parms.values[AX25_VALUES_TEXT] != 1)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_BACKOFF] != 'E' &&
ax25_parms.values[AX25_VALUES_BACKOFF] != 'L')
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_CONMODE] != 0 &&
ax25_parms.values[AX25_VALUES_CONMODE] != 1)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_WINDOW] < 1 ||
ax25_parms.values[AX25_VALUES_WINDOW] > 7)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_EWINDOW] < 1 ||
ax25_parms.values[AX25_VALUES_EWINDOW] > 63)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_T1] < 1)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_T2] < 1)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_T3] < 1)
return -EINVAL;
if (ax25_parms.values[AX25_VALUES_N2] < 1 ||
ax25_parms.values[AX25_VALUES_N2] > 31)
return -EINVAL;
memcpy(ax25_dev->values, ax25_parms.values, AX25_MAX_VALUES * sizeof(short));
ax25_dev->values[AX25_VALUES_T1] *= (PR_SLOWHZ / 2);
ax25_dev->values[AX25_VALUES_T2] *= PR_SLOWHZ;
ax25_dev->values[AX25_VALUES_T3] *= PR_SLOWHZ;
break;
case SIOCAX25GETPARMS:
if ((err = verify_area(VERIFY_WRITE, arg, sizeof(struct ax25_parms_struct))) != 0)
return err;
memcpy_fromfs(&ax25_parms, arg, sizeof(ax25_parms));
if ((dev = ax25rtr_get_dev(&ax25_parms.port_addr)) == NULL)
return -EINVAL;
if ((ax25_dev = ax25_dev_get_dev(dev)) == NULL)
return -EINVAL;
memcpy(ax25_parms.values, ax25_dev->values, AX25_MAX_VALUES * sizeof(short));
ax25_parms.values[AX25_VALUES_T1] /= (PR_SLOWHZ * 2);
ax25_parms.values[AX25_VALUES_T2] /= PR_SLOWHZ;
ax25_parms.values[AX25_VALUES_T3] /= PR_SLOWHZ;
memcpy_tofs(arg, &ax25_parms, sizeof(ax25_parms));
break;
}
return 0;
}
#endif #endif
...@@ -130,7 +130,7 @@ static void ax25_timer(unsigned long param) ...@@ -130,7 +130,7 @@ static void ax25_timer(unsigned long param)
if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) { if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
if (ax25->condition & ACK_PENDING_CONDITION) { if (ax25->condition & ACK_PENDING_CONDITION) {
ax25->condition &= ~ACK_PENDING_CONDITION; ax25->condition &= ~ACK_PENDING_CONDITION;
ax25_enquiry_response(ax25); ax25_timeout_response(ax25);
} }
} }
} }
...@@ -167,7 +167,9 @@ static void ax25_timer(unsigned long param) ...@@ -167,7 +167,9 @@ static void ax25_timer(unsigned long param)
} }
} else { } else {
ax25->modulus = MODULUS; ax25->modulus = MODULUS;
ax25->window = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
ax25->n2count = 0; ax25->n2count = 0;
ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
} }
} else { } else {
ax25->n2count++; ax25->n2count++;
......
...@@ -9,8 +9,10 @@ ...@@ -9,8 +9,10 @@
O_TARGET := core.o O_TARGET := core.o
O_OBJS :=
ifdef CONFIG_NET ifdef CONFIG_NET
O_OBJS := sock.o dev.o dev_mcast.o skbuff.o datagram.o iovec.o O_OBJS += sock.o dev.o dev_mcast.o iovec.o skbuff.o datagram.o
endif endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
...@@ -1240,13 +1240,13 @@ static int arp_req_set(struct arpreq *req) ...@@ -1240,13 +1240,13 @@ static int arp_req_set(struct arpreq *req)
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
case ARPHRD_AX25: case ARPHRD_AX25:
htype = ARPHRD_AX25; htype = ARPHRD_AX25;
hlen = 7; hlen = AX25_ADDR_LEN;
break; break;
#endif #endif
#ifdef CONFIG_NETROM #ifdef CONFIG_NETROM
case ARPHRD_NETROM: case ARPHRD_NETROM:
htype = ARPHRD_NETROM; htype = ARPHRD_NETROM;
hlen = 7; hlen = AX25_ADDR_LEN;
break; break;
#endif #endif
case ARPHRD_IEEE802: case ARPHRD_IEEE802:
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/in.h> #include <linux/in.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/protocol.h> #include <net/protocol.h>
#include <net/route.h> #include <net/route.h>
......
...@@ -127,6 +127,7 @@ ...@@ -127,6 +127,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h>
#include <net/snmp.h> #include <net/snmp.h>
#include <net/ip.h> #include <net/ip.h>
...@@ -1695,7 +1696,6 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1695,7 +1696,6 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
static void ip_loopback(struct device *old_dev, struct sk_buff *skb) static void ip_loopback(struct device *old_dev, struct sk_buff *skb)
{ {
extern struct device loopback_dev;
struct device *dev=&loopback_dev; struct device *dev=&loopback_dev;
int len=skb->len-old_dev->hard_header_len; int len=skb->len-old_dev->hard_header_len;
struct sk_buff *newskb=dev_alloc_skb(len+dev->hard_header_len+15); struct sk_buff *newskb=dev_alloc_skb(len+dev->hard_header_len+15);
......
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
#include <linux/ip_fw.h> #include <linux/ip_fw.h>
#include <net/checksum.h> #include <net/checksum.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h>
/* /*
* Implement IP packet firewall * Implement IP packet firewall
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
* Fixes: * Fixes:
* Alan Cox : Merged and made usable non modular (its so tiny its silly as * Alan Cox : Merged and made usable non modular (its so tiny its silly as
* a module taking up 2 pages). * a module taking up 2 pages).
* Alan Cox : Fixed bug with 1.3.18 and IPIP not working (now needs to set skb->h.iph)
* to keep ip_forward happy.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -56,6 +58,7 @@ int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -56,6 +58,7 @@ int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
#ifdef TUNNEL_DEBUG #ifdef TUNNEL_DEBUG
printk("ipip_rcv: got a packet!\n"); printk("ipip_rcv: got a packet!\n");
#endif #endif
skb->h.iph=skb->data; /* Correct IP header pointer on to new header */
if(ip_forward(skb, dev, 0, daddr, 0)) if(ip_forward(skb, dev, 0, daddr, 0))
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include <net/ax25.h> #include <net/ax25.h>
#endif #endif
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h>
#if defined(CONFIG_INET_RARP) || defined(MODULE) #if defined(CONFIG_INET_RARP) || defined(MODULE)
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include <linux/ipx.h> #include <linux/ipx.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/route.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/segment.h> #include <asm/segment.h>
...@@ -71,6 +72,7 @@ ...@@ -71,6 +72,7 @@
#include <net/p8022.h> #include <net/p8022.h>
#include <net/psnap.h> #include <net/psnap.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h>
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
/* Configuration Variables */ /* Configuration Variables */
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <net/netrom.h> #include <net/netrom.h>
#include <linux/proc_fs.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/arp.h> #include <net/arp.h>
...@@ -115,8 +115,6 @@ static void nr_kill_by_device(struct device *dev) ...@@ -115,8 +115,6 @@ static void nr_kill_by_device(struct device *dev)
s->dead = 1; s->dead = 1;
} }
} }
nr_rt_device_down(dev);
} }
/* /*
...@@ -124,10 +122,13 @@ static void nr_kill_by_device(struct device *dev) ...@@ -124,10 +122,13 @@ static void nr_kill_by_device(struct device *dev)
*/ */
static int nr_device_event(unsigned long event, void *ptr) static int nr_device_event(unsigned long event, void *ptr)
{ {
struct device *dev = (struct device *)ptr;
if (event != NETDEV_DOWN) if (event != NETDEV_DOWN)
return NOTIFY_DONE; return NOTIFY_DONE;
nr_kill_by_device(ptr); nr_kill_by_device(dev);
nr_rt_device_down(dev);
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -329,6 +330,10 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, ...@@ -329,6 +330,10 @@ static int nr_setsockopt(struct socket *sock, int level, int optname,
sk->nr->n2 = opt; sk->nr->n2 = opt;
return 0; return 0;
case NETROM_HDRINCL:
sk->nr->hdrincl = opt ? 1 : 0;
return 0;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
...@@ -351,7 +356,7 @@ static int nr_getsockopt(struct socket *sock, int level, int optname, ...@@ -351,7 +356,7 @@ static int nr_getsockopt(struct socket *sock, int level, int optname,
switch (optname) { switch (optname) {
case NETROM_T1: case NETROM_T1:
val = sk->nr->t1 / PR_SLOWHZ; val = (sk->nr->t1 * 2) / PR_SLOWHZ;
break; break;
case NETROM_T2: case NETROM_T2:
...@@ -362,6 +367,10 @@ static int nr_getsockopt(struct socket *sock, int level, int optname, ...@@ -362,6 +367,10 @@ static int nr_getsockopt(struct socket *sock, int level, int optname,
val = sk->nr->n2; val = sk->nr->n2;
break; break;
case NETROM_HDRINCL:
val = sk->nr->hdrincl;
break;
default: default:
return -ENOPROTOOPT; return -ENOPROTOOPT;
} }
...@@ -497,6 +506,7 @@ static int nr_create(struct socket *sock, int protocol) ...@@ -497,6 +506,7 @@ static int nr_create(struct socket *sock, int protocol)
nr->bpqext = 1; nr->bpqext = 1;
nr->fraglen = 0; nr->fraglen = 0;
nr->hdrincl = 0;
nr->state = NR_STATE_0; nr->state = NR_STATE_0;
nr->device = NULL; nr->device = NULL;
...@@ -580,6 +590,7 @@ static struct sock *nr_make_new(struct sock *osk) ...@@ -580,6 +590,7 @@ static struct sock *nr_make_new(struct sock *osk)
nr->device = osk->nr->device; nr->device = osk->nr->device;
nr->bpqext = osk->nr->bpqext; nr->bpqext = osk->nr->bpqext;
nr->hdrincl = osk->nr->hdrincl;
nr->fraglen = 0; nr->fraglen = 0;
nr->t1timer = 0; nr->t1timer = 0;
...@@ -931,10 +942,9 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev) ...@@ -931,10 +942,9 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
*/ */
if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL) || if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL) ||
((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL)) { ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL)) {
skb_pull(skb, NR_NETWORK_LEN); skb->h.raw = skb->data;
skb->h.raw = skb->data + NR_TRANSPORT_LEN;
if ((frametype & 0x0F) == NR_CONNACK && skb->len == 7) if ((frametype & 0x0F) == NR_CONNACK && skb->len == 22)
sk->nr->bpqext = 1; sk->nr->bpqext = 1;
else else
sk->nr->bpqext = 0; sk->nr->bpqext = 0;
...@@ -1129,7 +1139,7 @@ static int nr_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, ...@@ -1129,7 +1139,7 @@ static int nr_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
{ {
struct sock *sk = (struct sock *)sock->data; struct sock *sk = (struct sock *)sock->data;
struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)sip; struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)sip;
int copied = 0; int copied;
struct sk_buff *skb; struct sk_buff *skb;
int er; int er;
...@@ -1142,7 +1152,10 @@ static int nr_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, ...@@ -1142,7 +1152,10 @@ static int nr_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
if (addr_len != NULL) if (addr_len != NULL)
*addr_len = sizeof(*sax); *addr_len = sizeof(*sax);
/* This works for seqpacket too. The receiver has ordered the queue for us! We do one quick check first though */ /*
* This works for seqpacket too. The receiver has ordered the queue for
* us! We do one quick check first though
*/
if (sk->type == SOCK_SEQPACKET && sk->state != TCP_ESTABLISHED) if (sk->type == SOCK_SEQPACKET && sk->state != TCP_ESTABLISHED)
return -ENOTCONN; return -ENOTCONN;
...@@ -1150,8 +1163,12 @@ static int nr_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, ...@@ -1150,8 +1163,12 @@ static int nr_recvfrom(struct socket *sock, void *ubuf, int size, int noblock,
if ((skb = skb_recv_datagram(sk, flags, noblock, &er)) == NULL) if ((skb = skb_recv_datagram(sk, flags, noblock, &er)) == NULL)
return er; return er;
copied = (size < skb->len - NR_TRANSPORT_LEN) ? size : skb->len - NR_TRANSPORT_LEN; if (!sk->nr->hdrincl) {
skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
skb->h.raw = skb->data;
}
copied = (size < skb->len) ? size : skb->len;
skb_copy_datagram(skb, 0, ubuf, copied); skb_copy_datagram(skb, 0, ubuf, copied);
if (sax != NULL) { if (sax != NULL) {
...@@ -1286,8 +1303,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -1286,8 +1303,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return(0); return(0);
} }
static int nr_get_info(char *buffer, char **start, off_t offset, static int nr_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
int length, int dummy)
{ {
struct sock *s; struct sock *s;
struct device *dev; struct device *dev;
......
...@@ -211,7 +211,7 @@ int nr_init(struct device *dev) ...@@ -211,7 +211,7 @@ int nr_init(struct device *dev)
dev->stop = nr_close; dev->stop = nr_close;
dev->hard_header = nr_header; dev->hard_header = nr_header;
dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + 2 + NR_NETWORK_LEN + NR_TRANSPORT_LEN; dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + 3 + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
dev->addr_len = AX25_ADDR_LEN; dev->addr_len = AX25_ADDR_LEN;
dev->type = ARPHRD_NETROM; dev->type = ARPHRD_NETROM;
dev->rebuild_header = nr_rebuild_header; dev->rebuild_header = nr_rebuild_header;
......
...@@ -68,11 +68,16 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) ...@@ -68,11 +68,16 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
skbn->free = 1; skbn->free = 1;
skbn->arp = 1; skbn->arp = 1;
skbn->sk = sk; skbn->sk = sk;
sk->rmem_alloc += skb->truesize; sk->rmem_alloc += skbn->truesize;
skbn->h.raw = skbn->data;
skbo = skb_dequeue(&sk->nr->frag_queue);
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
kfree_skb(skbo, FREE_READ);
while ((skbo = skb_dequeue(&sk->nr->frag_queue)) != NULL) { while ((skbo = skb_dequeue(&sk->nr->frag_queue)) != NULL) {
skb_pull(skbo, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len); memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
kfree_skb(skbo, FREE_READ); kfree_skb(skbo, FREE_READ);
} }
...@@ -93,9 +98,9 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype ...@@ -93,9 +98,9 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype
case NR_CONNACK: case NR_CONNACK:
nr_calculate_rtt(sk); nr_calculate_rtt(sk);
sk->window = skb->data[5]; sk->window = skb->data[20];
sk->nr->your_index = skb->data[2]; sk->nr->your_index = skb->data[17];
sk->nr->your_id = skb->data[3]; sk->nr->your_id = skb->data[18];
sk->nr->t1timer = 0; sk->nr->t1timer = 0;
sk->nr->t2timer = 0; sk->nr->t2timer = 0;
sk->nr->t4timer = 0; sk->nr->t4timer = 0;
...@@ -170,8 +175,8 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype ...@@ -170,8 +175,8 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
unsigned short nr, ns; unsigned short nr, ns;
int queued = 0; int queued = 0;
nr = skb->data[3]; nr = skb->data[18];
ns = skb->data[2]; ns = skb->data[17];
switch (frametype) { switch (frametype) {
...@@ -276,7 +281,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype ...@@ -276,7 +281,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
do { do {
save_vr = sk->nr->vr; save_vr = sk->nr->vr;
while ((skbn = skb_dequeue(&sk->nr->reseq_queue)) != NULL) { while ((skbn = skb_dequeue(&sk->nr->reseq_queue)) != NULL) {
ns = skbn->data[2]; ns = skbn->data[17];
if (ns == sk->nr->vr) { if (ns == sk->nr->vr) {
if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) { if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
sk->nr->vr = (sk->nr->vr + 1) % NR_MODULUS; sk->nr->vr = (sk->nr->vr + 1) % NR_MODULUS;
...@@ -328,7 +333,7 @@ int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb) ...@@ -328,7 +333,7 @@ int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
del_timer(&sk->timer); del_timer(&sk->timer);
frametype = skb->data[4]; frametype = skb->data[19];
switch (sk->nr->state) switch (sk->nr->state)
{ {
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
* *
* Fixes: * Fixes:
* Linus Torvalds : Assorted bug cures. * Linus Torvalds : Assorted bug cures.
* Niibe Yutaka : async I/O support
* Carsten Paeth : PF_UNIX check, address fixes.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -237,14 +239,26 @@ static void def_callback1(struct sock *sk) ...@@ -237,14 +239,26 @@ static void def_callback1(struct sock *sk)
static void def_callback2(struct sock *sk, int len) static void def_callback2(struct sock *sk, int len)
{ {
if(!sk->dead) if(!sk->dead)
{
wake_up_interruptible(sk->sleep); wake_up_interruptible(sk->sleep);
sock_wake_async(sk->socket, 1);
}
}
static void def_callback3(struct sock *sk)
{
if(!sk->dead)
{
wake_up_interruptible(sk->sleep);
sock_wake_async(sk->socket, 2);
}
} }
static int unix_create(struct socket *sock, int protocol) static int unix_create(struct socket *sock, int protocol)
{ {
unix_socket *sk; unix_socket *sk;
/* printk("Unix create\n");*/ /* printk("Unix create\n");*/
if(protocol) if(protocol && protocol != PF_UNIX)
return -EPROTONOSUPPORT; return -EPROTONOSUPPORT;
sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL); sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
if(sk==NULL) if(sk==NULL)
...@@ -289,7 +303,7 @@ static int unix_create(struct socket *sock, int protocol) ...@@ -289,7 +303,7 @@ static int unix_create(struct socket *sock, int protocol)
sk->shutdown=0; sk->shutdown=0;
sk->state_change=def_callback1; sk->state_change=def_callback1;
sk->data_ready=def_callback2; sk->data_ready=def_callback2;
sk->write_space=def_callback1; sk->write_space=def_callback3;
sk->error_report=def_callback1; sk->error_report=def_callback1;
sk->mtu=4096; sk->mtu=4096;
sk->socket=sock; sk->socket=sock;
...@@ -410,7 +424,6 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le ...@@ -410,7 +424,6 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
struct sk_buff *skb; struct sk_buff *skb;
int err; int err;
unix_mkname(sun, addr_len);
if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other) if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
{ {
if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED) if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
...@@ -428,9 +441,11 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le ...@@ -428,9 +441,11 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
return -EISCONN; return -EISCONN;
} }
if(sun->sun_family!=AF_UNIX) if(addr_len < sizeof(sun->sun_family)+1 || sun->sun_family!=AF_UNIX)
return -EINVAL; return -EINVAL;
unix_mkname(sun, addr_len);
if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other) if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
{ {
sk->protinfo.af_unix.other->protinfo.af_unix.locks--; sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
...@@ -440,6 +455,11 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le ...@@ -440,6 +455,11 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
if(sock->type==SOCK_DGRAM) if(sock->type==SOCK_DGRAM)
{ {
other=unix_find_other(sun->sun_path, &err);
if(other==NULL)
return err;
other->protinfo.af_unix.locks++;
sk->protinfo.af_unix.other=other;
sock->state=SS_CONNECTED; sock->state=SS_CONNECTED;
sk->state=TCP_ESTABLISHED; sk->state=TCP_ESTABLISHED;
return 0; /* Done */ return 0; /* Done */
...@@ -601,6 +621,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags) ...@@ -601,6 +621,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
tsk->protinfo.af_unix.locks++; /* Back lock */ tsk->protinfo.af_unix.locks++; /* Back lock */
sti(); sti();
tsk->state_change(tsk); /* Wake up any sleeping connect */ tsk->state_change(tsk); /* Wake up any sleeping connect */
sock_wake_async(tsk->socket, 0);
return 0; return 0;
} }
...@@ -619,10 +640,10 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ ...@@ -619,10 +640,10 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
if(sk->protinfo.af_unix.name==NULL) if(sk->protinfo.af_unix.name==NULL)
{ {
*sun->sun_path=0; *sun->sun_path=0;
*uaddr_len=3; *uaddr_len=sizeof(sun->sun_family)+1;
return 0; /* Not bound */ return 0; /* Not bound */
} }
*uaddr_len=sizeof(short)+strlen(sk->protinfo.af_unix.name)+1; *uaddr_len=sizeof(sun->sun_family)+strlen(sk->protinfo.af_unix.name)+1;
strcpy(sun->sun_path,sk->protinfo.af_unix.name); /* 108 byte limited */ strcpy(sun->sun_path,sk->protinfo.af_unix.name); /* 108 byte limited */
return 0; return 0;
} }
...@@ -688,6 +709,13 @@ static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no ...@@ -688,6 +709,13 @@ static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
if(sun==NULL) if(sun==NULL)
{ {
other=sk->protinfo.af_unix.other; other=sk->protinfo.af_unix.other;
if(sock->type==SOCK_DGRAM && other->dead)
{
other->protinfo.af_unix.locks--;
sk->protinfo.af_unix.other=NULL;
sock->state=SS_UNCONNECTED;
return -ECONNRESET;
}
} }
else else
{ {
...@@ -761,7 +789,9 @@ static int unix_recvmsg(struct socket *sock, struct msghdr *msg, int size, int n ...@@ -761,7 +789,9 @@ static int unix_recvmsg(struct socket *sock, struct msghdr *msg, int size, int n
{ {
return -EAGAIN; return -EAGAIN;
} }
sk->socket->flags |= SO_WAITDATA;
interruptible_sleep_on(sk->sleep); interruptible_sleep_on(sk->sleep);
sk->socket->flags &= ~SO_WAITDATA;
if( current->signal & ~current->blocked) if( current->signal & ~current->blocked)
{ {
sti(); sti();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment