Commit 1f5ed52f authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.14e

parent d80e0e9b
init/main.o : init/main.c /usr/lib/gcc-lib/i486-linux/2.5.4/include/stdarg.h /usr/include/asm/system.h \
/usr/include/linux/segment.h /usr/include/asm/io.h /usr/include/linux/types.h \
/usr/include/linux/fcntl.h /usr/include/linux/config.h /usr/include/linux/autoconf.h \
/usr/include/linux/sched.h /usr/include/linux/tasks.h /usr/include/linux/head.h \
/usr/include/linux/fs.h /usr/include/linux/linkage.h /usr/include/linux/limits.h \
/usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
/usr/include/linux/net.h /usr/include/linux/socket.h /usr/include/linux/sockios.h \
/usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
/usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h /usr/include/linux/msdos_fs_i.h \
/usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h \
/usr/include/linux/xia_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
/usr/include/linux/ext2_fs_sb.h /usr/include/linux/hpfs_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
/usr/include/linux/iso_fs_sb.h /usr/include/linux/nfs_fs_sb.h /usr/include/linux/xia_fs_sb.h \
/usr/include/linux/mm.h /usr/include/linux/page.h /usr/include/linux/kernel.h \
/usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
/usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
/usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/linux/unistd.h \
/usr/include/linux/string.h /usr/include/linux/timer.h /usr/include/linux/ctype.h \
/usr/include/linux/delay.h /usr/include/linux/utsname.h /usr/include/linux/ioport.h
tools/build.o : tools/build.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.4/include/stddef.h \
/usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.4/include/float.h \
/usr/include/alloca.h /usr/include/sys/types.h /usr/include/linux/types.h /usr/include/sys/stat.h \
/usr/include/linux/stat.h /usr/include/sys/sysmacros.h /usr/include/unistd.h \
/usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/fcntl.h /usr/include/linux/fcntl.h \
/usr/include/linux/config.h /usr/include/linux/autoconf.h /usr/include/linux/a.out.h \
/usr/include/linux/page.h
tools/version.o : tools/version.c /usr/include/linux/config.h /usr/include/linux/autoconf.h \
/usr/include/linux/utsname.h tools/./version.h
VERSION = 0.99 VERSION = 0.99
PATCHLEVEL = 14 PATCHLEVEL = 14
ALPHA = d ALPHA = e
all: Version zImage all: Version zImage
......
...@@ -205,6 +205,16 @@ static int mmap_zero(struct inode * inode, struct file * file, ...@@ -205,6 +205,16 @@ static int mmap_zero(struct inode * inode, struct file * file,
return 0; return 0;
} }
static int read_full(struct inode * node,struct file * file,char * buf,int count)
{
return count;
}
static int write_full(struct inode * inode,struct file * file,char * buf, int count)
{
return -ENOSPC;
}
/* /*
* Special lseek() function for /dev/null and /dev/zero. Most notably, you can fopen() * Special lseek() function for /dev/null and /dev/zero. Most notably, you can fopen()
* both devices with "a" now. This was previously impossible. SRB. * both devices with "a" now. This was previously impossible. SRB.
...@@ -321,6 +331,18 @@ static struct file_operations zero_fops = { ...@@ -321,6 +331,18 @@ static struct file_operations zero_fops = {
NULL /* no special release code */ NULL /* no special release code */
}; };
static struct file_operations full_fops = {
memory_lseek,
read_full,
write_full,
NULL, /* full_readdir */
NULL, /* full_select */
NULL, /* full_ioctl */
NULL, /* full_mmap */
NULL, /* no special open code */
NULL /* no special release code */
};
static int memory_open(struct inode * inode, struct file * filp) static int memory_open(struct inode * inode, struct file * filp)
{ {
switch (MINOR(inode->i_rdev)) { switch (MINOR(inode->i_rdev)) {
...@@ -342,6 +364,9 @@ static int memory_open(struct inode * inode, struct file * filp) ...@@ -342,6 +364,9 @@ static int memory_open(struct inode * inode, struct file * filp)
case 5: case 5:
filp->f_op = &zero_fops; filp->f_op = &zero_fops;
break; break;
case 7:
filp->f_op = &full_fops;
break;
default: default:
return -ENODEV; return -ENODEV;
} }
......
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
* Matt Dillon : Printable slip (borrowed from NET2E) * Matt Dillon : Printable slip (borrowed from NET2E)
* Pauline Middelink : Slip driver fixes. * Pauline Middelink : Slip driver fixes.
* Alan Cox : Honours the old SL_COMPRESSED flag * Alan Cox : Honours the old SL_COMPRESSED flag
* Alan Cox : KISS AX.25 and AXUI IP support
*/ */
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -38,6 +40,9 @@ ...@@ -38,6 +40,9 @@
#include <linux/in.h> #include <linux/in.h>
#include "inet.h" #include "inet.h"
#include "dev.h" #include "dev.h"
#ifdef CONFIG_AX25
#include "ax25.h"
#endif
#include "eth.h" #include "eth.h"
#include "ip.h" #include "ip.h"
#include "route.h" #include "route.h"
...@@ -507,6 +512,18 @@ sl_xmit(struct sk_buff *skb, struct device *dev) ...@@ -507,6 +512,18 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
/* We were not, so we are now... :-) */ /* We were not, so we are now... :-) */
if (skb != NULL) { if (skb != NULL) {
#ifdef CONFIG_AX25
if(sl->mode & SL_MODE_AX25)
{
if(!skb->arp && dev->rebuild_header(skb+1,dev))
{
skb->dev=dev;
arp_queue(skb);
return 0;
}
skb->arp=1;
}
#endif
sl_lock(sl); sl_lock(sl);
sl_encaps(sl, (unsigned char *) (skb + 1), skb->len); sl_encaps(sl, (unsigned char *) (skb + 1), skb->len);
if (skb->free) kfree_skb(skb, FREE_WRITE); if (skb->free) kfree_skb(skb, FREE_WRITE);
...@@ -515,10 +532,15 @@ sl_xmit(struct sk_buff *skb, struct device *dev) ...@@ -515,10 +532,15 @@ sl_xmit(struct sk_buff *skb, struct device *dev)
} }
/* Return the frame type ID. This is always IP. */ /* Return the frame type ID. This is normally IP but maybe be AX.25. */
static unsigned short static unsigned short
sl_type_trans (struct sk_buff *skb, struct device *dev) sl_type_trans (struct sk_buff *skb, struct device *dev)
{ {
#ifdef CONFIG_AX25
struct slip *sl=&sl_ctrl[dev->base_addr];
if(sl->mode&SL_MODE_AX25)
return(NET16(ETH_P_AX25));
#endif
return(NET16(ETH_P_IP)); return(NET16(ETH_P_IP));
} }
...@@ -528,6 +550,61 @@ static int ...@@ -528,6 +550,61 @@ static int
sl_header(unsigned char *buff, struct device *dev, unsigned short type, sl_header(unsigned char *buff, struct device *dev, unsigned short type,
unsigned long daddr, unsigned long saddr, unsigned len) unsigned long daddr, unsigned long saddr, unsigned len)
{ {
#ifdef CONFIG_AX25
struct slip *sl=&sl_ctrl[dev->base_addr];
unsigned long flags;
if((sl->mode&SL_MODE_AX25) && type!=NET16(ETH_P_AX25))
{
/* header is an AX.25 UI frame from us to them */
if(chk_addr(daddr) == IS_BROADCAST)
{
*buff++=0;
memcpy(buff,dev->broadcast,dev->addr_len); /* QST-0 */
}
else
{
if(type!=ETH_P_IP)
printk("AX25 Encap: Non IP frame to encapsulate directed\n");
save_flags(flags);
cli();
*buff++=0; /* KISS DATA */
memcpy(buff,&daddr,4); /* In case arp fails */
if(arp_find(buff,daddr,dev, saddr))
{
memcpy(buff+7,&saddr,4);
buff+=14;
*buff++=LAPB_UI; /* UI */
/* Append a suitable AX.25 PID */
*buff++=PID_IP; /* AX25 IP */
restore_flags(flags);
return ( -dev->hard_header_len);
}
}
buff[6]&=~LAPB_C;
buff[6]&=~LAPB_E;
buff+=7;
memcpy(buff,dev->dev_addr,dev->addr_len);
buff[6]&=~LAPB_C;
buff[6]|=LAPB_E;
buff+=7;
*buff++=LAPB_UI; /* UI */
/* Append a suitable AX.25 PID */
switch(type)
{
case ETH_P_IP:
*buff++=PID_IP; /* AX25 IP */
break;
case ETH_P_ARP:
*buff++=PID_ARP;
break;
default:
*buff++=0;
}
return (17);
}
#endif
return(0); return(0);
} }
...@@ -536,6 +613,12 @@ sl_header(unsigned char *buff, struct device *dev, unsigned short type, ...@@ -536,6 +613,12 @@ sl_header(unsigned char *buff, struct device *dev, unsigned short type,
static void static void
sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev) sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
{ {
#ifdef CONFIG_AX25
struct slip *sl=&sl_ctrl[dev->base_addr];
if(sl->mode&SL_MODE_AX25)
arp_add(addr,((char *)(skb+1))+8,dev);
#endif
} }
...@@ -543,6 +626,24 @@ sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev) ...@@ -543,6 +626,24 @@ sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
static int static int
sl_rebuild_header(void *buff, struct device *dev) sl_rebuild_header(void *buff, struct device *dev)
{ {
#ifdef CONFIG_AX25
struct slip *sl=&sl_ctrl[dev->base_addr];
if(sl->mode&SL_MODE_AX25)
{
unsigned char *bp=(unsigned char *)buff;
long dest=*(long *)(bp+1);
long src=*(long *)(bp+8);
if(arp_find(bp+1,dest,dev,src))
return 1;
memcpy(bp+8,dev->dev_addr,7);
bp[7]&=~LAPB_C;
bp[7]&=~LAPB_E;
bp[14]&=~LAPB_C;
bp[14]|=LAPB_E;
return(0);
}
#endif
return(0); return(0);
} }
...@@ -939,6 +1040,20 @@ slip_close(struct tty_struct *tty) ...@@ -939,6 +1040,20 @@ slip_close(struct tty_struct *tty)
sl->flags |= SLF_ERROR; sl->flags |= SLF_ERROR;
} }
#ifdef CONFIG_AX25
int sl_set_mac_address(struct device *dev, void *addr)
{
int err=verify_area(VERIFY_READ,addr,7);
if(err)
return err;
memcpy_fromfs(dev->dev_addr,addr,7); /* addr is an AX.25 shifted ASCII mac address */
return 0;
}
#endif
/* Perform I/O control on an active SLIP channel. */ /* Perform I/O control on an active SLIP channel. */
static int static int
slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
...@@ -967,7 +1082,25 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) ...@@ -967,7 +1082,25 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
case SIOCSIFENCAP: case SIOCSIFENCAP:
err=verify_area(VERIFY_READ,arg,sizeof(long)); err=verify_area(VERIFY_READ,arg,sizeof(long));
sl->mode=get_fs_long((long *)arg); sl->mode=get_fs_long((long *)arg);
#ifdef CONFIG_AX25
if(sl->mode & SL_MODE_AX25)
{
sl->dev->addr_len=7; /* sizeof an AX.25 addr */
sl->dev->hard_header_len=17; /* We don't do digipeaters */
sl->dev->type=3; /* AF_AX25 not an AF_INET device */
}
else
{
sl->dev->addr_len=0; /* No mac addr in slip mode */
sl->dev->hard_header_len=0;
sl->dev->type=0;
}
#endif
return(0); return(0);
case SIOCSIFHWADDR:
#ifdef CONFIG_AX25
return sl_set_mac_address(sl->dev,arg);
#endif
default: default:
return(-EINVAL); return(-EINVAL);
} }
...@@ -981,6 +1114,10 @@ slip_init(struct device *dev) ...@@ -981,6 +1114,10 @@ slip_init(struct device *dev)
{ {
struct slip *sl; struct slip *sl;
int i; int i;
#ifdef CONFIG_AX25
static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
#endif
sl = &sl_ctrl[dev->base_addr]; sl = &sl_ctrl[dev->base_addr];
...@@ -988,6 +1125,9 @@ slip_init(struct device *dev) ...@@ -988,6 +1125,9 @@ slip_init(struct device *dev)
printk("SLIP: version %s (%d channels)\n", printk("SLIP: version %s (%d channels)\n",
SLIP_VERSION, SL_NRUNIT); SLIP_VERSION, SL_NRUNIT);
printk("CSLIP: code copyright 1989 Regents of the University of California\n"); printk("CSLIP: code copyright 1989 Regents of the University of California\n");
#ifdef CONFIG_AX25
printk("AX25: KISS encapsulation enabled\n");
#endif
/* Fill in our LDISC request block. */ /* Fill in our LDISC request block. */
sl_ldisc.flags = 0; sl_ldisc.flags = 0;
sl_ldisc.open = slip_open; sl_ldisc.open = slip_open;
...@@ -997,8 +1137,8 @@ slip_init(struct device *dev) ...@@ -997,8 +1137,8 @@ slip_init(struct device *dev)
sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *, sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
unsigned int, unsigned long)) slip_ioctl; unsigned int, unsigned long)) slip_ioctl;
sl_ldisc.handler = slip_recv; sl_ldisc.handler = slip_recv;
if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) == 0) printk("OK\n"); if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
else printk("ERROR: %d\n", i); printk("ERROR: %d\n", i);
} }
/* Set up the "SLIP Control Block". */ /* Set up the "SLIP Control Block". */
...@@ -1020,9 +1160,18 @@ slip_init(struct device *dev) ...@@ -1020,9 +1160,18 @@ slip_init(struct device *dev)
dev->hard_header = sl_header; dev->hard_header = sl_header;
dev->add_arp = sl_add_arp; dev->add_arp = sl_add_arp;
dev->type_trans = sl_type_trans; dev->type_trans = sl_type_trans;
#ifdef HAVE_SET_MAC_ADDR
#ifdef CONFIG_AX25
dev->set_mac_address = sl_set_mac_address;
#endif
#endif
dev->hard_header_len = 0; dev->hard_header_len = 0;
dev->addr_len = 0; dev->addr_len = 0;
dev->type = 0; dev->type = 0;
#ifdef CONFIG_AX25
memcpy(dev->broadcast,ax25_bcast,7); /* Only activated in AX.25 mode */
memcpy(dev->dev_addr,ax25_test,7); /* "" "" "" "" */
#endif
dev->queue_xmit = dev_queue_xmit; dev->queue_xmit = dev_queue_xmit;
dev->rebuild_header = sl_rebuild_header; dev->rebuild_header = sl_rebuild_header;
for (i = 0; i < DEV_NUMBUFFS; i++) for (i = 0; i < DEV_NUMBUFFS; i++)
......
...@@ -67,6 +67,7 @@ struct slip { ...@@ -67,6 +67,7 @@ struct slip {
#define SL_MODE_CSLIP 1 #define SL_MODE_CSLIP 1
#define SL_MODE_SLIP6 2 /* Matt Dillon's printable slip */ #define SL_MODE_SLIP6 2 /* Matt Dillon's printable slip */
#define SL_MODE_CSLIP6 (SL_MODE_SLIP|SL_MODE_CSLIP) #define SL_MODE_CSLIP6 (SL_MODE_SLIP|SL_MODE_CSLIP)
#define SL_MODE_AX25 4
int xdata,xbits; /* 6 bit slip controls */ int xdata,xbits; /* 6 bit slip controls */
}; };
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
/* #define GUS_LINEAR_VOLUME */ /* #define GUS_LINEAR_VOLUME */
#include "sound_config.h" #include "sound_config.h"
#include "ultrasound.h" #include <linux/ultrasound.h>
#include "gus_hw.h" #include "gus_hw.h"
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS) #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
......
...@@ -41,10 +41,10 @@ ...@@ -41,10 +41,10 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <sys/kd.h> #include <linux/kd.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include "soundcard.h" #include <linux/soundcard.h>
typedef char snd_rw_buf; typedef char snd_rw_buf;
......
...@@ -32,7 +32,9 @@ ...@@ -32,7 +32,9 @@
#define ETH_P_IP 0x0800 /* Internet Protocol packet */ #define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */ #define ETH_P_ARP 0x0806 /* Address Resolution packet */
#define ETH_P_RARP 0x0835 /* Reverse Addr Res packet */ #define ETH_P_RARP 0x0835 /* Reverse Addr Res packet */
#define ETH_P_IPX 0x8137 /* IPX over DIX */
#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ #define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
/* Define the Ethernet Broadcast Address (48 bits set to "1"). */ /* Define the Ethernet Broadcast Address (48 bits set to "1"). */
#define ETH_A_BCAST "\377\377\377\377\377\377" #define ETH_A_BCAST "\377\377\377\377\377\377"
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
* 21 - scsi generic * 21 - scsi generic
* 22 - UNUSED * 22 - UNUSED
* 23 - mitsumi cdrom * 23 - mitsumi cdrom
* 24 - sony535 cdrom
*/ */
#define UNNAMED_MAJOR 0 #define UNNAMED_MAJOR 0
...@@ -66,6 +67,7 @@ ...@@ -66,6 +67,7 @@
#define SCSI_GENERIC_MAJOR 21 #define SCSI_GENERIC_MAJOR 21
/* unused: 22 */ /* unused: 22 */
#define MITSUMI_CDROM_MAJOR 23 #define MITSUMI_CDROM_MAJOR 23
#define SONY535_CDROM_MAJOR 24
/* /*
* Tests for SCSI devices. * Tests for SCSI devices.
......
...@@ -30,7 +30,7 @@ sys_create_module(char *module_name, unsigned long size) ...@@ -30,7 +30,7 @@ sys_create_module(char *module_name, unsigned long size)
if (!suser()) if (!suser())
return -EPERM; return -EPERM;
if (name == NULL || size == 0) if (module_name == NULL || size == 0)
return -EINVAL; return -EINVAL;
if ((error = get_mod_name(module_name, name)) != 0) if ((error = get_mod_name(module_name, name)) != 0)
return error; return error;
......
...@@ -29,11 +29,23 @@ ...@@ -29,11 +29,23 @@
#ifdef CONFIG_INET #ifdef CONFIG_INET
# include "inet/inet.h" # include "inet/inet.h"
#endif #endif
#ifdef CONFIG_IPX
#include "inet/ipxcall.h"
#endif
#ifdef CONFIG_AX25
#include "inet/ax25call.h"
#endif
struct ddi_proto protocols[] = { struct ddi_proto protocols[] = {
#ifdef CONFIG_UNIX #ifdef CONFIG_UNIX
{ "UNIX", unix_proto_init }, { "UNIX", unix_proto_init },
#endif #endif
#ifdef CONFIG_IPX
{ "IPX", ipx_proto_init },
#endif
#ifdef CONFIG_AX25
{ "AX.25", ax25_proto_init },
#endif
#ifdef CONFIG_INET #ifdef CONFIG_INET
{ "INET", inet_proto_init }, { "INET", inet_proto_init },
#endif #endif
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
OBJS = sock.o utils.o route.o proc.o timer.o protocol.o loopback.o \ OBJS = sock.o utils.o route.o proc.o timer.o protocol.o loopback.o \
eth.o packet.o arp.o dev.o ip.o raw.o icmp.o tcp.o udp.o \ eth.o packet.o arp.o dev.o ip.o raw.o icmp.o tcp.o udp.o \
datagram.o skbuff.o datagram.o skbuff.o
# ipx.o ax25.o ax25_in.o ax25_out.o ax25_subr.o ax25_timer.o
ifdef CONFIG_INET ifdef CONFIG_INET
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
* Alan Cox : 'Bad Packet' only reported on debugging * Alan Cox : 'Bad Packet' only reported on debugging
* Alan Cox : Proxy arp. * Alan Cox : Proxy arp.
* Alan Cox : skb->link3 maintained by letting the other xmit queue kill the packet. * Alan Cox : skb->link3 maintained by letting the other xmit queue kill the packet.
* Alan Cox : Knows about type 3 devices (AX.25) using an AX.25 protocol ID not the ethernet
* one.
* *
* To Fix: * To Fix:
* : arp response allocates an skbuff to send. However there is a perfectly * : arp response allocates an skbuff to send. However there is a perfectly
...@@ -482,7 +484,7 @@ arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -482,7 +484,7 @@ arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
} }
/* For now we will only deal with IP addresses. */ /* For now we will only deal with IP addresses. */
if (arp->ar_pro != NET16(ETH_P_IP) || arp->ar_pln != 4) if (((arp->ar_pro != NET16(0x00CC) && dev->type==3) || (arp->ar_pro != NET16(ETH_P_IP) && dev->type!=3) ) || arp->ar_pln != 4)
{ {
if (arp->ar_op != NET16(ARPOP_REQUEST)) if (arp->ar_op != NET16(ARPOP_REQUEST))
DPRINTF((DBG_ARP,"ARP: Non-IP request on device \"%s\" !\n", dev->name)); DPRINTF((DBG_ARP,"ARP: Non-IP request on device \"%s\" !\n", dev->name));
...@@ -601,7 +603,10 @@ arp_send(unsigned long paddr, struct device *dev, unsigned long saddr) ...@@ -601,7 +603,10 @@ arp_send(unsigned long paddr, struct device *dev, unsigned long saddr)
} }
arp = (struct arphdr *) ((unsigned char *) (skb+1) + tmp); arp = (struct arphdr *) ((unsigned char *) (skb+1) + tmp);
arp->ar_hrd = htons(dev->type); arp->ar_hrd = htons(dev->type);
arp->ar_pro = htons(ETH_P_IP); if(dev->type!=3) /* AX.25 */
arp->ar_pro = htons(ETH_P_IP);
else
arp->ar_pro = htons(0xCC);
arp->ar_hln = dev->addr_len; arp->ar_hln = dev->addr_len;
arp->ar_pln = 4; arp->ar_pln = 4;
arp->ar_op = htons(ARPOP_REQUEST); arp->ar_op = htons(ARPOP_REQUEST);
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
* Fixes: * Fixes:
* Alan Cox : NULL return from skb_peek_copy() understood * Alan Cox : NULL return from skb_peek_copy() understood
* Alan Cox : Rewrote skb_read_datagram to avoid the skb_peek_copy stuff. * Alan Cox : Rewrote skb_read_datagram to avoid the skb_peek_copy stuff.
* Alan Cox : Added support for SOCK_SEQPACKET. IPX can no longer use the SO_TYPE hack but
* AX.25 now works right, and SPX is feasible.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -60,6 +62,22 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock, ...@@ -60,6 +62,22 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
return NULL; return NULL;
} }
if(sk->err)
{
release_sock(sk);
*err=-sk->err;
sk->err=0;
return NULL;
}
/* Sequenced packets can come disconnected. If so we report the problem */
if(sk->type==SOCK_SEQPACKET && sk->state!=TCP_ESTABLISHED)
{
release_sock(sk);
*err=-ENOTCONN;
return NULL;
}
/* User doesn't want to wait */ /* User doesn't want to wait */
if (noblock) if (noblock)
{ {
...@@ -145,6 +163,7 @@ void skb_copy_datagram(struct sk_buff *skb, int offset, char *to, int size) ...@@ -145,6 +163,7 @@ void skb_copy_datagram(struct sk_buff *skb, int offset, char *to, int size)
/* /*
* Datagram select: Again totally generic. Moved from udp.c * Datagram select: Again totally generic. Moved from udp.c
* Now does seqpacket.
*/ */
int datagram_select(struct sock *sk, int sel_type, select_table *wait) int datagram_select(struct sock *sk, int sel_type, select_table *wait)
...@@ -153,6 +172,11 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait) ...@@ -153,6 +172,11 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait)
switch(sel_type) switch(sel_type)
{ {
case SEL_IN: case SEL_IN:
if (sk->type==SOCK_SEQPACKET && sk->state==TCP_CLOSE)
{
/* Connection closed: Wake up */
return(1);
}
if (sk->rqueue != NULL || sk->err != 0) if (sk->rqueue != NULL || sk->err != 0)
{ /* This appears to be consistent { /* This appears to be consistent
with other stacks */ with other stacks */
...@@ -168,7 +192,7 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait) ...@@ -168,7 +192,7 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait)
return(0); return(0);
case SEL_EX: case SEL_EX:
if (sk->err) if (sk->err)
return(1); /* Socket has gone into error state (eg icmp error) */ return(1); /* Socket has gone into error state (eg icmp error) */
return(0); return(0);
} }
......
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
* Alan Cox: Supports Donald Beckers new hardware * Alan Cox: Supports Donald Beckers new hardware
* multicast layer, but not yet multicast lists. * multicast layer, but not yet multicast lists.
* Alan Cox: ip_addr_match problems with class A/B nets. * Alan Cox: ip_addr_match problems with class A/B nets.
* C.E.Hawkins IP 0.0.0.0 and also same net route fix. [FIXME: Ought to cause ICMP_REDIRECT]
* Alan Cox: Removed bogus subnet check now the subnet code
* a) actually works for all A/B nets
* b) doesn't forward off the same interface.
* Alan Cox: Multiple extra protocols
* *
* 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
...@@ -52,6 +57,45 @@ ...@@ -52,6 +57,45 @@
#include "skbuff.h" #include "skbuff.h"
#include "sock.h" #include "sock.h"
#include "arp.h" #include "arp.h"
#ifdef CONFIG_AX25
#include "ax25.h"
#endif
#ifdef CONFIG_IPX
static struct packet_type ipx_8023_type = {
NET16(ETH_P_802_3),
0,
ipx_rcv,
NULL,
NULL
};
static struct packet_type ipx_packet_type = {
NET16(ETH_P_IPX),
0,
ipx_rcv,
NULL,
&ipx_8023_type
};
#endif
#ifdef CONFIG_AX25
static struct packet_type ax25_packet_type = {
NET16(ETH_P_AX25),
0,
ax25_rcv,
NULL,
#ifdef CONFIG_IPX
&ipx_packet_type
#else
NULL
#endif
};
#endif
static struct packet_type arp_packet_type = { static struct packet_type arp_packet_type = {
...@@ -59,7 +103,15 @@ static struct packet_type arp_packet_type = { ...@@ -59,7 +103,15 @@ static struct packet_type arp_packet_type = {
0, /* copy */ 0, /* copy */
arp_rcv, arp_rcv,
NULL, NULL,
#ifdef CONFIG_IPX
#ifndef CONFIG_AX25
&ipx_packet_type
#else
&ax25_packet_type
#endif
#else
NULL /* next */ NULL /* next */
#endif
}; };
...@@ -161,14 +213,10 @@ chk_addr(unsigned long addr) ...@@ -161,14 +213,10 @@ chk_addr(unsigned long addr)
/* OK, now check the interface addresses. */ /* OK, now check the interface addresses. */
for (dev = dev_base; dev != NULL; dev = dev->next) { for (dev = dev_base; dev != NULL; dev = dev->next) {
if (dev->pa_addr == 0) if (!(dev->flags&IFF_UP))
{ continue;
if(dev->flags&IFF_PROMISC) /* This allows all addresses through */ if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
return(IS_MYADDR); return(IS_MYADDR);
else
continue;
}
/* Is it the exact IP address? */ /* Is it the exact IP address? */
if (addr == dev->pa_addr) { if (addr == dev->pa_addr) {
DPRINTF((DBG_DEV, "MYADDR\n")); DPRINTF((DBG_DEV, "MYADDR\n"));
...@@ -187,15 +235,30 @@ chk_addr(unsigned long addr) ...@@ -187,15 +235,30 @@ chk_addr(unsigned long addr)
return(IS_BROADCAST); return(IS_BROADCAST);
} }
} }
/* Nope. Check for Network broadcast. */
if(IN_CLASSA(dst)) {
if( addr == (dev->pa_addr | 0xffffff00)) {
DPRINTF((DBG_DEV, "CLASS A BROADCAST-1\n"));
return(IS_BROADCAST);
}
}
else if(IN_CLASSB(dst)) {
if( addr == (dev->pa_addr | 0xffff0000)) {
DPRINTF((DBG_DEV, "CLASS B BROADCAST-1\n"));
return(IS_BROADCAST);
}
}
else { /* IN_CLASSC */
if( addr == (dev->pa_addr | 0xff000000)) {
DPRINTF((DBG_DEV, "CLASS C BROADCAST-1\n"));
return(IS_BROADCAST);
}
}
} }
DPRINTF((DBG_DEV, "NONE\n")); DPRINTF((DBG_DEV, "NONE\n"));
if ((addr & 0xFF) == 0xFF)
{
/* Wrong subnetted IS_BROADCAST */
return(IS_INVBCAST);
}
return(0); /* no match at all */ return(0); /* no match at all */
} }
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
/* for future expansion when we will have different priorities. */ /* for future expansion when we will have different priorities. */
#define DEV_NUMBUFFS 3 #define DEV_NUMBUFFS 3
#define MAX_ADDR_LEN 6 #define MAX_ADDR_LEN 7
#define MAX_HEADER 14 #define MAX_HEADER 18
#define IS_MYADDR 1 /* address is (one of) our own */ #define IS_MYADDR 1 /* address is (one of) our own */
#define IS_LOOPBACK 2 /* address is for LOOPBACK */ #define IS_LOOPBACK 2 /* address is for LOOPBACK */
...@@ -135,6 +135,8 @@ struct device { ...@@ -135,6 +135,8 @@ struct device {
#define HAVE_MULTICAST #define HAVE_MULTICAST
void (*set_multicast_list)(struct device *dev, void (*set_multicast_list)(struct device *dev,
int num_addrs, void *addrs); int num_addrs, void *addrs);
#define HAVE_SET_MAC_ADDR
int (*set_mac_address)(struct device *dev, void *addr);
}; };
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* *
* Fixes: * Fixes:
* Alan Cox : Generic queue usage. * Alan Cox : Generic queue usage.
* Gerhard Koerting: ICMP addressing corrected
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -106,7 +107,7 @@ icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -106,7 +107,7 @@ icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
iph = (struct iphdr *) ((unsigned char *) iph + dev->hard_header_len); iph = (struct iphdr *) ((unsigned char *) iph + dev->hard_header_len);
/* Build Layer 2-3 headers for message back to source. */ /* Build Layer 2-3 headers for message back to source. */
offset = ip_build_header(skb, iph->daddr, iph->saddr, offset = ip_build_header(skb, dev->pa_addr, iph->saddr,
&dev, IPPROTO_ICMP, NULL, len); &dev, IPPROTO_ICMP, NULL, len);
if (offset < 0) { if (offset < 0) {
skb->sk = NULL; skb->sk = NULL;
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
* Gerhard Koerting: Forward fragmented frames correctly. * Gerhard Koerting: Forward fragmented frames correctly.
* Gerhard Koerting: Fixes to my fix of the above 8-). * Gerhard Koerting: Fixes to my fix of the above 8-).
* Gerhard Koerting: IP interface addressing fix. * Gerhard Koerting: IP interface addressing fix.
* Linus Torvalds : More robustness checks
* Alan Cox : Even more checks: Still not as robust as it ought to be
* *
* To Fix: * To Fix:
* IP option processing is mostly not needed. ip_forward needs to know about routing rules * IP option processing is mostly not needed. ip_forward needs to know about routing rules
...@@ -1108,6 +1110,7 @@ ip_forward(struct sk_buff *skb, struct device *dev, int is_frag) ...@@ -1108,6 +1110,7 @@ ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
return; return;
} }
/* /*
* Gosh. Not only is the packet valid; we even know how to * Gosh. Not only is the packet valid; we even know how to
* forward it onto its final destination. Can we say this * forward it onto its final destination. Can we say this
...@@ -1129,6 +1132,7 @@ ip_forward(struct sk_buff *skb, struct device *dev, int is_frag) ...@@ -1129,6 +1132,7 @@ ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
} else raddr = iph->daddr; } else raddr = iph->daddr;
dev2 = rt->rt_dev; dev2 = rt->rt_dev;
if (dev == dev2) if (dev == dev2)
return; return;
/* /*
...@@ -1191,7 +1195,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1191,7 +1195,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
DPRINTF((DBG_IP, "<<\n")); DPRINTF((DBG_IP, "<<\n"));
/* Is the datagram acceptable? */ /* Is the datagram acceptable? */
if (iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0) { if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0) {
DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n")); DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n"));
DPRINTF((DBG_IP, " SRC = %s ", in_ntoa(iph->saddr))); DPRINTF((DBG_IP, " SRC = %s ", in_ntoa(iph->saddr)));
DPRINTF((DBG_IP, " DST = %s (ignored)\n", in_ntoa(iph->daddr))); DPRINTF((DBG_IP, " DST = %s (ignored)\n", in_ntoa(iph->daddr)));
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* Alan Cox : UDP sockets show the rxqueue/txqueue * Alan Cox : UDP sockets show the rxqueue/txqueue
* using hint flag for the netinfo. * using hint flag for the netinfo.
* Pauline Middelink : Pidentd support * Pauline Middelink : Pidentd support
* Alan Cox : Make /proc safer.
* *
* To Do: * To Do:
* Put the creating userid in the proc/net/... files. This will * Put the creating userid in the proc/net/... files. This will
...@@ -65,7 +66,13 @@ get__netinfo(struct proto *pro, char *buffer, int format) ...@@ -65,7 +66,13 @@ get__netinfo(struct proto *pro, char *buffer, int format)
s_array = pro->sock_array; s_array = pro->sock_array;
pos+=sprintf(pos, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n"); pos+=sprintf(pos, "sl local_address rem_address st tx_queue rx_queue tr tm->when uid\n");
/*
* This was very pretty but didn't work when a socket is destroyed at the wrong moment
* (eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing
* with timers we just concede defeat and cli().
*/
for(i = 0; i < SOCK_ARRAY_SIZE; i++) { for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
cli();
sp = s_array[i]; sp = s_array[i];
while(sp != NULL) { while(sp != NULL) {
dest = sp->daddr; dest = sp->daddr;
...@@ -76,7 +83,6 @@ get__netinfo(struct proto *pro, char *buffer, int format) ...@@ -76,7 +83,6 @@ get__netinfo(struct proto *pro, char *buffer, int format)
/* Since we are Little Endian we need to swap the bytes :-( */ /* Since we are Little Endian we need to swap the bytes :-( */
destp = ntohs(destp); destp = ntohs(destp);
srcp = ntohs(srcp); srcp = ntohs(srcp);
timer_active = del_timer(&sp->timer); timer_active = del_timer(&sp->timer);
if (!timer_active) if (!timer_active)
sp->timer.expires = 0; sp->timer.expires = 0;
...@@ -88,7 +94,6 @@ get__netinfo(struct proto *pro, char *buffer, int format) ...@@ -88,7 +94,6 @@ get__netinfo(struct proto *pro, char *buffer, int format)
SOCK_INODE(sp->socket)->i_uid); SOCK_INODE(sp->socket)->i_uid);
if (timer_active) if (timer_active)
add_timer(&sp->timer); add_timer(&sp->timer);
/* Is place in buffer too rare? then abort. */ /* Is place in buffer too rare? then abort. */
if (pos > buffer+PAGE_SIZE-80) { if (pos > buffer+PAGE_SIZE-80) {
printk("oops, too many %s sockets for netinfo.\n", printk("oops, too many %s sockets for netinfo.\n",
...@@ -103,6 +108,8 @@ get__netinfo(struct proto *pro, char *buffer, int format) ...@@ -103,6 +108,8 @@ get__netinfo(struct proto *pro, char *buffer, int format)
*/ */
sp = sp->next; sp = sp->next;
} }
sti(); /* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
before this will clear before we jump back and cli, so its not as bad as it looks */
} }
return(strlen(buffer)); return(strlen(buffer));
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* library. No more peek crashes, no more backlogs * library. No more peek crashes, no more backlogs
* Alan Cox : Checks sk->broadcast. * Alan Cox : Checks sk->broadcast.
* Alan Cox : Uses skb_free_datagram/skb_copy_datagram * Alan Cox : Uses skb_free_datagram/skb_copy_datagram
* Alan Cox : Raw passes ip options too
* *
* 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
......
...@@ -70,19 +70,26 @@ rt_del(unsigned long dst) ...@@ -70,19 +70,26 @@ rt_del(unsigned long dst)
unsigned long flags; unsigned long flags;
DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst))); DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst)));
if ((r = rt_base) == NULL) return; if ((r = rt_base) == NULL)
return;
save_flags(flags); save_flags(flags);
cli(); cli();
p = NULL; p = NULL;
while(r != NULL) { while(r != NULL)
if (r->rt_dst == dst) { {
if (p == NULL) rt_base = r->rt_next; if (r->rt_dst == dst)
else p->rt_next = r->rt_next; {
if (p == NULL)
rt_base = r->rt_next;
else
p->rt_next = r->rt_next;
x = r->rt_next; x = r->rt_next;
kfree_s(r, sizeof(struct rtable)); kfree_s(r, sizeof(struct rtable));
r = x; r = x;
} else { }
else
{
p = r; p = r;
r = r->rt_next; r = r->rt_next;
} }
...@@ -105,14 +112,20 @@ rt_flush(struct device *dev) ...@@ -105,14 +112,20 @@ rt_flush(struct device *dev)
save_flags(flags); save_flags(flags);
p = NULL; p = NULL;
while(r != NULL) { while(r != NULL)
if (r->rt_dev == dev) { {
if (p == NULL) rt_base = r->rt_next; if (r->rt_dev == dev)
else p->rt_next = r->rt_next; {
if (p == NULL)
rt_base = r->rt_next;
else
p->rt_next = r->rt_next;
x = r->rt_next; x = r->rt_next;
kfree_s(r, sizeof(struct rtable)); kfree_s(r, sizeof(struct rtable));
r = x; r = x;
} else { }
else
{
p = r; p = r;
r = r->rt_next; r = r->rt_next;
} }
...@@ -126,7 +139,7 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev) ...@@ -126,7 +139,7 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
{ {
struct rtable *r, *r1; struct rtable *r, *r1;
struct rtable *rt; struct rtable *rt;
int mask; int mask=0;
unsigned long cpuflags; unsigned long cpuflags;
/* Allocate an entry. */ /* Allocate an entry. */
...@@ -139,7 +152,18 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev) ...@@ -139,7 +152,18 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
/* Fill in the fields. */ /* Fill in the fields. */
memset(rt, 0, sizeof(struct rtable)); memset(rt, 0, sizeof(struct rtable));
rt->rt_flags = (flags | RTF_UP); rt->rt_flags = (flags | RTF_UP);
if (gw != 0) rt->rt_flags |= RTF_GATEWAY;
/*
* Gateway to our own interface is really direct
*/
if (gw==dev->pa_addr || gw==dst)
{
gw=0;
rt->rt_flags&=~RTF_GATEWAY;
}
if (gw != 0)
rt->rt_flags |= RTF_GATEWAY;
rt->rt_dev = dev; rt->rt_dev = dev;
rt->rt_gateway = gw; rt->rt_gateway = gw;
...@@ -148,23 +172,31 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev) ...@@ -148,23 +172,31 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
* the TARGET if we are creating an entry for a NETWORK. Use * the TARGET if we are creating an entry for a NETWORK. Use
* an Internet class C network mask. Yuck :-( * an Internet class C network mask. Yuck :-(
*/ */
if (flags & RTF_DYNAMIC) { if (flags & RTF_DYNAMIC)
{
if (flags & RTF_HOST) if (flags & RTF_HOST)
rt->rt_dst = dst; rt->rt_dst = dst;
else{ else
{
/* Cut down to the route at interface mask level */
rt->rt_dst = (dst & dev->pa_mask); rt->rt_dst = (dst & dev->pa_mask);
mask=dev->pa_mask;
/* We don't want new routes to our own net*/ /* We don't want new routes to our own net*/
if(rt->rt_dst == (dev->pa_addr & dev->pa_mask)){ if(rt->rt_dst == (dev->pa_addr & dev->pa_mask))
{
kfree_s(rt, sizeof(struct rtable)); kfree_s(rt, sizeof(struct rtable));
/*printk("Dynamic route to my own net rejected\n");*/ /*printk("Dynamic route to my own net rejected\n");*/
return; return;
} }
} }
} else rt->rt_dst = dst; }
else
rt->rt_dst = dst;
rt_print(rt); rt_print(rt);
if (rt_base == NULL) { if (rt_base == NULL)
{
rt->rt_next = NULL; rt->rt_next = NULL;
rt_base = rt; rt_base = rt;
return; return;
...@@ -175,26 +207,38 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev) ...@@ -175,26 +207,38 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
* found the first address which has the same generality * found the first address which has the same generality
* as the one in rt. Then we can put rt in after it. * as the one in rt. Then we can put rt in after it.
*/ */
for (mask = 0xff000000L; mask != 0xffffffffL; mask = (mask >> 8) | mask) {
if (mask & dst) { if(mask==0) /* Dont figure out masks for DYNAMIC routes. The mask is (our should be!)
mask = mask << 8; the device mask (obtained above) */
break; {
} for (mask = 0xff000000L; mask != 0xffffffffL; mask = (mask >> 8) | mask)
{
if (mask & dst)
{
mask = mask << 8;
break;
}
}
DPRINTF((DBG_RT, "RT: mask = %X\n", mask));
} }
DPRINTF((DBG_RT, "RT: mask = %X\n", mask));
save_flags(cpuflags); save_flags(cpuflags);
cli(); cli();
r1 = rt_base; r1 = rt_base;
/* See if we are getting a duplicate. */ /* See if we are getting a duplicate. */
for (r = rt_base; r != NULL; r = r->rt_next) { for (r = rt_base; r != NULL; r = r->rt_next)
if (r->rt_dst == dst) { {
if (r == rt_base) { if (r->rt_dst == dst)
{
if (r == rt_base)
{
rt->rt_next = r->rt_next; rt->rt_next = r->rt_next;
rt_base = rt; rt_base = rt;
} else { }
else
{
rt->rt_next = r->rt_next; rt->rt_next = r->rt_next;
r1->rt_next = rt; r1->rt_next = rt;
} }
...@@ -206,11 +250,16 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev) ...@@ -206,11 +250,16 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
} }
r1 = rt_base; r1 = rt_base;
for (r = rt_base; r != NULL; r = r->rt_next) { for (r = rt_base; r != NULL; r = r->rt_next)
if (! (r->rt_dst & mask)) { {
/* When we find a route more general than ourselves, and we are not a gateway or it is a gateway then use it
This puts gateways after direct links in the table and sorts (most) of the bit aligned subnetting out */
if (! (r->rt_dst & mask) && (gw==0 || r->rt_flags&RTF_GATEWAY))
{
DPRINTF((DBG_RT, "RT: adding before r=%X\n", r)); DPRINTF((DBG_RT, "RT: adding before r=%X\n", r));
rt_print(r); rt_print(r);
if (r == rt_base) { if (r == rt_base)
{
rt->rt_next = rt_base; rt->rt_next = rt_base;
rt_base = rt; rt_base = rt;
restore_flags(cpuflags); restore_flags(cpuflags);
...@@ -315,11 +364,12 @@ struct rtable * ...@@ -315,11 +364,12 @@ struct rtable *
rt_route(unsigned long daddr, struct options *opt) rt_route(unsigned long daddr, struct options *opt)
{ {
struct rtable *rt; struct rtable *rt;
int type;
/* /*
* This is a hack, I think. -FvK * This is a hack, I think. -FvK
*/ */
if (chk_addr(daddr) == IS_MYADDR) daddr = my_addr(); if ((type=chk_addr(daddr)) == IS_MYADDR) daddr = my_addr();
/* /*
* Loop over the IP routing table to find a route suitable * Loop over the IP routing table to find a route suitable
...@@ -342,7 +392,7 @@ rt_route(unsigned long daddr, struct options *opt) ...@@ -342,7 +392,7 @@ rt_route(unsigned long daddr, struct options *opt)
rt->rt_use++; rt->rt_use++;
return(rt); return(rt);
} }
if ((rt->rt_dev->flags & IFF_BROADCAST) && if (type==IS_BROADCAST && (rt->rt_dev->flags & IFF_BROADCAST) &&
ip_addr_match(rt->rt_dev->pa_brdaddr, daddr)) { ip_addr_match(rt->rt_dev->pa_brdaddr, daddr)) {
DPRINTF((DBG_RT, "%s (BCAST %s)\n", DPRINTF((DBG_RT, "%s (BCAST %s)\n",
rt->rt_dev->name, in_ntoa(rt->rt_dev->pa_brdaddr))); rt->rt_dev->name, in_ntoa(rt->rt_dev->pa_brdaddr)));
......
...@@ -11,11 +11,13 @@ ...@@ -11,11 +11,13 @@
* Fixes: * Fixes:
* Alan Cox : Tracks memory and number of buffers for kernel memory report * Alan Cox : Tracks memory and number of buffers for kernel memory report
* and memory leak hunting. * and memory leak hunting.
* Alan Cox : More generic kfree handler
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -384,15 +386,30 @@ void kfree_skb(struct sk_buff *skb, int rw) ...@@ -384,15 +386,30 @@ void kfree_skb(struct sk_buff *skb, int rw)
if(skb->list) if(skb->list)
printk("Warning: kfree_skb passed an skb still on a list.\n"); printk("Warning: kfree_skb passed an skb still on a list.\n");
skb->magic = 0; skb->magic = 0;
if (skb->sk) { if (skb->sk)
if (rw) { {
skb->sk->prot->rfree(skb->sk, skb->mem_addr, skb->mem_len); if(skb->sk->prot!=NULL)
} else { {
skb->sk->prot->wfree(skb->sk, skb->mem_addr, skb->mem_len); if (rw)
skb->sk->prot->rfree(skb->sk, skb->mem_addr, skb->mem_len);
else
skb->sk->prot->wfree(skb->sk, skb->mem_addr, skb->mem_len);
} }
} else { else
{
/* Non INET - default wmalloc/rmalloc handler */
if (rw)
skb->sk->rmem_alloc-=skb->mem_len;
else
skb->sk->wmem_alloc-=skb->mem_len;
if(!skb->sk->dead)
wake_up(skb->sk->sleep);
kfree_skbmem(skb->mem_addr,skb->mem_len);
}
}
else
kfree_skbmem(skb->mem_addr, skb->mem_len); kfree_skbmem(skb->mem_addr, skb->mem_len);
}
} }
/* /*
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
* Pauline Middelink : Pidentd support * Pauline Middelink : Pidentd support
* Alan Cox : Fixed connect() taking signals I think. * Alan Cox : Fixed connect() taking signals I think.
* Alan Cox : SO_LINGER supported * Alan Cox : SO_LINGER supported
* Alan Cox : Error reporting fixes
* Anonymous : inet_create tidied up (sk->reuse setting)
* *
* To Fix: * To Fix:
* *
...@@ -708,7 +710,7 @@ inet_create(struct socket *sock, int protocol) ...@@ -708,7 +710,7 @@ inet_create(struct socket *sock, int protocol)
if (sk == NULL) if (sk == NULL)
return(-ENOMEM); return(-ENOMEM);
sk->num = 0; sk->num = 0;
sk->reuse = 0;
switch(sock->type) { switch(sock->type) {
case SOCK_STREAM: case SOCK_STREAM:
case SOCK_SEQPACKET: case SOCK_SEQPACKET:
...@@ -794,7 +796,7 @@ inet_create(struct socket *sock, int protocol) ...@@ -794,7 +796,7 @@ inet_create(struct socket *sock, int protocol)
sk->intr = 0; sk->intr = 0;
sk->linger = 0; sk->linger = 0;
sk->destroy = 0; sk->destroy = 0;
sk->reuse = 0;
sk->priority = 1; sk->priority = 1;
sk->shutdown = 0; sk->shutdown = 0;
sk->urg = 0; sk->urg = 0;
...@@ -1077,7 +1079,9 @@ inet_connect(struct socket *sock, struct sockaddr * uaddr, ...@@ -1077,7 +1079,9 @@ inet_connect(struct socket *sock, struct sockaddr * uaddr,
{ {
sti(); sti();
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
return -sk->err; /* set by tcp_err() */ err = -sk->err;
sk->err=0;
return err; /* set by tcp_err() */
} }
} }
sti(); sti();
...@@ -1085,7 +1089,9 @@ inet_connect(struct socket *sock, struct sockaddr * uaddr, ...@@ -1085,7 +1089,9 @@ inet_connect(struct socket *sock, struct sockaddr * uaddr,
if (sk->state != TCP_ESTABLISHED && sk->err) { if (sk->state != TCP_ESTABLISHED && sk->err) {
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
return(-sk->err); err=sk->err;
sk->err=0;
return(err);
} }
return(0); return(0);
} }
...@@ -1773,7 +1779,7 @@ void inet_proto_init(struct ddi_proto *pro) ...@@ -1773,7 +1779,7 @@ void inet_proto_init(struct ddi_proto *pro)
struct inet_protocol *p; struct inet_protocol *p;
int i; int i;
printk("Swansea University Computer Society Net2Debugged [1.24]\n"); printk("Swansea University Computer Society Net2Debugged [1.27]\n");
/* Set up our UNIX VFS major device. */ /* Set up our UNIX VFS major device. */
if (register_chrdev(AF_INET_MAJOR, "af_inet", &inet_fops) < 0) { if (register_chrdev(AF_INET_MAJOR, "af_inet", &inet_fops) < 0) {
printk("%s: cannot register major device %d!\n", printk("%s: cannot register major device %d!\n",
......
...@@ -36,6 +36,12 @@ ...@@ -36,6 +36,12 @@
#include "skbuff.h" /* struct sk_buff */ #include "skbuff.h" /* struct sk_buff */
#include "protocol.h" /* struct inet_protocol */ #include "protocol.h" /* struct inet_protocol */
#ifdef CONFIG_AX25
#include "ax25.h"
#endif
#ifdef CONFIG_IPX
#include "ipx.h"
#endif
#define SOCK_ARRAY_SIZE 64 #define SOCK_ARRAY_SIZE 64
...@@ -74,7 +80,7 @@ struct sock { ...@@ -74,7 +80,7 @@ struct sock {
ack_timed, ack_timed,
no_check, no_check,
exp_growth, exp_growth,
zapped, /* In ipx means not linked */ zapped, /* In ax25 & ipx means not linked */
broadcast; broadcast;
unsigned long lingertime; unsigned long lingertime;
int proc; int proc;
...@@ -114,7 +120,23 @@ struct sock { ...@@ -114,7 +120,23 @@ struct sock {
unsigned char debug; unsigned char debug;
unsigned short rcvbuf; unsigned short rcvbuf;
unsigned short sndbuf; unsigned short sndbuf;
unsigned short type; /* IPX type field */ unsigned short type;
#ifdef CONFIG_IPX
ipx_address ipx_source_addr,ipx_dest_addr;
unsigned short ipx_type;
#endif
#ifdef CONFIG_AX25
/* Really we want to add a per protocol private area */
ax25_address ax25_source_addr,ax25_dest_addr;
struct sk_buff *volatile ax25_retxq[8];
char ax25_state,ax25_vs,ax25_vr,ax25_lastrxnr,ax25_lasttxnr;
char ax25_condition;
char ax25_retxcnt;
char ax25_xx;
char ax25_retxqi;
char ax25_rrtimer;
char ax25_timer;
#endif
struct tcphdr dummy_th; struct tcphdr dummy_th;
/* This part is used for the timeout functions (timer.c). */ /* This part is used for the timeout functions (timer.c). */
......
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