diff -u --recursive --new-file v1.1.16/linux/Makefile linux/Makefile --- v1.1.16/linux/Makefile Tue May 31 12:48:14 1994 +++ linux/Makefile Tue May 31 12:38:53 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 16 +SUBLEVEL = 17 all: Version zImage diff -u --recursive --new-file v1.1.16/linux/config.in linux/config.in --- v1.1.16/linux/config.in Fri May 27 10:49:05 1994 +++ linux/config.in Tue May 31 12:43:17 1994 @@ -73,6 +73,7 @@ comment 'Skipping ethercard configuration options...' else +bool 'Dummy net driver support' CONFIG_DUMMY y bool 'SLIP (serial line) support' CONFIG_SLIP n if [ "$CONFIG_SLIP" = "y" ]; then bool ' CSLIP compressed headers' SL_COMPRESSED y @@ -98,7 +99,7 @@ #bool 'NI52EE support' CONFIG_NI52 n #bool 'NI65EE support' CONFIG_NI65 n #bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n -#bool 'Cabletron E21xx support (not recommended)' CONFIG_E21 n +#bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n fi diff -u --recursive --new-file v1.1.16/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v1.1.16/linux/drivers/net/Makefile Tue May 31 12:48:17 1994 +++ linux/drivers/net/Makefile Tue May 31 12:32:57 1994 @@ -82,6 +82,12 @@ NETDRV_OBJS := $(NETDRV_OBJS) net.a(3c589.o) endif +ifdef CONFIG_DUMMY +NETDRV_OBJS := $(NETDRV_OBJS) net.a(dummy.o) +dummy.o: dummy.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< +endif + ifdef CONFIG_DE600 NETDRV_OBJS := $(NETDRV_OBJS) net.a(de600.o) endif Only in v1.1.16/linux/drivers/net: d_link.c diff -u --recursive --new-file v1.1.16/linux/drivers/net/dummy.c linux/drivers/net/dummy.c --- v1.1.16/linux/drivers/net/dummy.c Thu Jan 1 02:00:00 1970 +++ linux/drivers/net/dummy.c Tue May 31 12:33:04 1994 @@ -0,0 +1,110 @@ +/* dummy.c: a dummy net driver + + The purpose of this driver is to provide a device to point a + route through, but not to actually transmit packets. + + Why? If you have a machine whose only connection is an occasional + PPP/SLIP/PLIP link, you can only connect to your own hostname + when the link is up. Otherwise you have to use localhost. + This isn't very consistent. + + One solution is to set up a dummy link using PPP/SLIP/PLIP, + but this seems (to me) too much overhead for too little gain. + This driver provides a small alternative. Thus you can do + + [when not running slip] + ifconfig dummy slip.addr.ess.here up + [to go to slip] + ifconfig dummy down + dip whatever + + This was written by looking at Donald Becker's skeleton driver + and the loopback driver. I then threw away anything that didn't + apply! Thanks to Alan Cox for the key clue on what to do with + misguided packets. + + Nick Holloway, 27th May 1994 + [I tweaked this explanation a little but thats all] + Alan Cox, 30th May 1994 +*/ + +/* To have statistics (just packets sent) define this */ +#undef DUMMY_STATS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int dummy_xmit(struct sk_buff *skb, struct device *dev); +#ifdef DUMMY_STATS +static struct enet_statistics *dummy_get_stats(struct device *dev); +#endif + +int +dummy_init(struct device *dev) +{ +/* I commented this out as bootup is noisy enough anyway and this driver + seems pretty reliable 8) 8) 8) */ +/* printk ( KERN_INFO "Dummy net driver (94/05/27 v1.0)\n" ); */ + + /* Initialize the device structure. */ + dev->hard_start_xmit = dummy_xmit; + +#if DUMMY_STATS + dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL); + memset(dev->priv, 0, sizeof(struct enet_statistics)); + dev->get_stats = dummy_get_stats; +#endif + + /* Fill in the fields of the device structure with ethernet-generic values. */ + ether_setup(dev); + + return 0; +} + +static int +dummy_xmit(struct sk_buff *skb, struct device *dev) +{ +#if DUMMY_STATS + struct enet_statistics *stats; +#endif + + if (skb == NULL || dev == NULL) + return 0; + + if (skb->free) + kfree_skb(skb, FREE_WRITE); + +#if DUMMY_STATS + stats = (struct enet_statistics *)dev->priv; + stats->tx_packets++; +#endif + + return 0; +} + +#if DUMMY_STATS +static struct enet_statistics * +dummy_get_stats(struct device *dev) +{ + struct enet_statistics *stats = (struct enet_statistics*) dev->priv; + return stats; +} +#endif diff -u --recursive --new-file v1.1.16/linux/drivers/net/net_init.c linux/drivers/net/net_init.c --- v1.1.16/linux/drivers/net/net_init.c Tue May 31 12:48:17 1994 +++ linux/drivers/net/net_init.c Tue May 31 12:33:05 1994 @@ -15,7 +15,9 @@ A secondary advantage is that the dangerous NE*000 netcards can reserve their I/O port region before the SCSI probes start. - register_netdev()/unregister_netdev() by Bjorn Ekwall + Modifications/additions by Bjorn Ekwall : + ethdev_index[MAX_ETH_CARDS] + register_netdev() / unregister_netdev() */ #include @@ -45,8 +47,9 @@ by magic we get them, but otherwise they are un-needed and a space waste] */ -/* The next device number/name to assign: "eth0", "eth1", etc. */ -static int next_ethdev_number = 0; +/* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */ +#define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */ +static struct device *ethdev_index[MAX_ETH_CARDS]; unsigned long lance_init(unsigned long mem_start, unsigned long mem_end); @@ -78,11 +81,11 @@ long. */ -struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp) +struct device * +init_etherdev(struct device *dev, int sizeof_private, unsigned long *mem_startp) { - int i; int new_device = 0; + int i; if (dev == NULL) { int alloc_size = sizeof(struct device) + sizeof("eth%d ") @@ -99,31 +102,17 @@ new_device = 1; } - if (dev->name && dev->name[0] == '\0') - sprintf(dev->name, "eth%d", next_ethdev_number++); - - for (i = 0; i < DEV_NUMBUFFS; i++) - skb_queue_head_init(&dev->buffs[i]); - - dev->hard_header = eth_header; - dev->rebuild_header = eth_rebuild_header; - dev->type_trans = eth_type_trans; - - dev->type = ARPHRD_ETHER; - dev->hard_header_len = ETH_HLEN; - dev->mtu = 1500; /* eth_mtu */ - dev->addr_len = ETH_ALEN; - for (i = 0; i < ETH_ALEN; i++) { - dev->broadcast[i]=0xff; + if (dev->name && + ((dev->name[0] == '\0') || (dev->name[0] == ' '))) { + for (i = 0; i < MAX_ETH_CARDS; ++i) + if (ethdev_index[i] == NULL) { + sprintf(dev->name, "eth%d", i); + ethdev_index[i] = dev; + break; + } } - - /* New-style flags. */ - dev->flags = IFF_BROADCAST; - dev->family = AF_INET; - dev->pa_addr = 0; - dev->pa_brdaddr = 0; - dev->pa_mask = 0; - dev->pa_alen = sizeof(unsigned long); + + ether_setup(dev); /* should this be called here? */ if (new_device) { /* Append the device to the device queue. */ @@ -144,6 +133,19 @@ for (i = 0; i < DEV_NUMBUFFS; i++) skb_queue_head_init(&dev->buffs[i]); + /* register boot-defined "eth" devices */ + if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) { + i = simple_strtoul(dev->name + 3, NULL, 0); + if (ethdev_index[i] == NULL) { + ethdev_index[i] = dev; + } + else if (dev != ethdev_index[i]) { + /* Really shouldn't happen! */ + printk("ether_setup: Ouch! Someone else took %s\n", + dev->name); + } + } + dev->hard_header = eth_header; dev->rebuild_header = eth_rebuild_header; dev->type_trans = eth_type_trans; @@ -186,24 +188,30 @@ { struct device *d = dev_base; unsigned long flags; - + int i; + save_flags(flags); cli(); - if (dev && dev->init) - { - if (dev->init(dev) != 0) - { + if (dev && dev->init) { + if (dev->init(dev) != 0) { restore_flags(flags); return -EIO; } - - if (dev->name && dev->name[0] == '\0') - sprintf(dev->name, "eth%d", next_ethdev_number++); + + if (dev->name && + ((dev->name[0] == '\0') || (dev->name[0] == ' '))) { + for (i = 0; i < MAX_ETH_CARDS; ++i) + if (ethdev_index[i] == NULL) { + sprintf(dev->name, "eth%d", i); + printk("device '%s' loaded\n", dev->name); + ethdev_index[i] = dev; + break; + } + } /* Add device to end of chain */ - if (dev_base) - { + if (dev_base) { while (d->next) d = d->next; d->next = dev; @@ -220,35 +228,48 @@ { struct device *d = dev_base; unsigned long flags; - + int i; + save_flags(flags); cli(); printk("unregister_netdev: device "); - if (dev) { - if (dev->start) - printk("'%s' busy", dev->name); + + if (dev == NULL) { + printk("was NULL\n"); + restore_flags(flags); + return; + } + /* else */ + if (dev->start) + printk("'%s' busy\n", dev->name); + else { + if (dev_base == dev) + dev_base = dev->next; else { - if (dev_base == dev) - dev_base = dev->next; - else { - while (d && (d->next != dev)) - d = d->next; + while (d && (d->next != dev)) + d = d->next; - if (d && (d->next == dev)) { - d->next = dev->next; - printk("'%s' unlinked", dev->name); - } - else - printk("'%s' not found", dev->name); + if (d && (d->next == dev)) { + d->next = dev->next; + printk("'%s' unlinked\n", dev->name); + } + else { + printk("'%s' not found\n", dev->name); + restore_flags(flags); + return; + } + } + for (i = 0; i < MAX_ETH_CARDS; ++i) { + if (ethdev_index[i] == dev) { + ethdev_index[i] = NULL; + break; } } } - else - printk("was NULL"); - printk("\n"); restore_flags(flags); } + /* diff -u --recursive --new-file v1.1.16/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v1.1.16/linux/drivers/net/plip.c Tue May 31 12:48:18 1994 +++ linux/drivers/net/plip.c Tue May 31 12:33:05 1994 @@ -45,6 +45,12 @@ * ***** So we can all compare loads of different PLIP drivers for a bit I've modularised this beastie too. ***** In addition a seperate bidirectional plip module can be done. + * + * WARNING: The PRE 1.1.16 plip will NOT work with this PLIP driver. We + * can't avoid this due to an error in the old plip module. If you must + * mix PLIP's you'll need to fix the _OLD_ one to use 0xFC 0xFC as its + * MAC header not 0xFD. + * */ static char *version = @@ -703,7 +709,7 @@ { /* * set physical address to - * 0xfd.0xfd.ipaddr + * 0xfc.0xfc.ipaddr */ unsigned char *addr = dev->dev_addr; diff -u --recursive --new-file v1.1.16/linux/net/inet/README linux/net/inet/README --- v1.1.16/linux/net/inet/README Tue May 31 12:48:19 1994 +++ linux/net/inet/README Tue May 31 12:33:05 1994 @@ -1,5 +1,18 @@ This is snapshot 014 +Fixes added for 1.1.17 + +o Charles Hedrick's fixes broken fragmentation totally. Mended. +o Contributed 'dummy' device added. Apparently some slip people want it. +o Tried to kill the memory problems with fragments by setting things + up more carefully and guarding them. +o Module fixes by Bj0rn. +o PLIP fix by Tanabe. + +Fixes added for 1.1.16 +o Charles Hedricks fixes to TCP. +o Small fixes all over the place. + Fixes added for 1.1.15 o Modular PLIP and 3c501 drivers. Now you -can- have multiple 3c501's (sort of). diff -u --recursive --new-file v1.1.16/linux/net/inet/arp.c linux/net/inet/arp.c --- v1.1.16/linux/net/inet/arp.c Tue May 24 00:35:00 1994 +++ linux/net/inet/arp.c Tue May 31 12:33:05 1994 @@ -722,17 +722,6 @@ { struct arp_table *entry; unsigned long hash; -/* SHOULD BE FIXED NOW */ - if(paddr==0) - { - printk("ADDRESS BOTCH 0\n"); - if(skb) - { - printk("skb(saddr=%lx, daddr=%lx, raddr=%lx)\n", - skb->saddr,skb->daddr,skb->raddr); - } - } -/* ------------- */ switch (ip_chk_addr(paddr)) { case IS_MYADDR: diff -u --recursive --new-file v1.1.16/linux/net/inet/ip.c linux/net/inet/ip.c --- v1.1.16/linux/net/inet/ip.c Tue May 31 12:48:20 1994 +++ linux/net/inet/ip.c Tue May 31 12:33:05 1994 @@ -171,7 +171,7 @@ { mac = -mac; skb->arp = 0; - skb->raddr = daddr; /* next routing address */ + skb->raddr = daddr; /* next routing address */ } } return mac; @@ -226,7 +226,7 @@ * If the frame is from us and going off machine it MUST MUST MUST * have the output device ip address and never the loopback */ - if (saddr == 0x0100007FL && daddr != 0x0100007FL) + if (saddr == htonl(0x7F000001L) && daddr != htonl(0x7F000001L)) saddr = src;/*rt->rt_dev->pa_addr;*/ raddr = rt->rt_gateway; @@ -665,7 +665,6 @@ /* Finally, release the queue descriptor itself. */ kfree_s(qp, sizeof(struct ipq)); -/* printk("ip_free:done\n");*/ sti(); } @@ -716,7 +715,7 @@ { printk("IP: create: no memory left !\n"); return(NULL); - skb->dev = qp->dev; + skb->dev = qp->dev; } memset(qp, 0, sizeof(struct ipq)); @@ -949,7 +948,7 @@ ihl = (iph->ihl * sizeof(unsigned long)); end = offset + ntohs(iph->tot_len) - ihl; - + /* * Point into the IP datagram 'data' part. */ @@ -1088,6 +1087,7 @@ struct sk_buff *skb2; int left, mtu, hlen, len; int offset; + unsigned long flags; /* * Point into the IP datagram header. @@ -1180,19 +1180,27 @@ * Set up data on packet */ - skb2->arp = 0;/*skb->arp;*/ - skb2->free = skb->free; + skb2->arp = skb->arp; + if(skb->free==0) + printk("IP fragmenter: BUG free!=1 in fragmenter\n"); + skb2->free = 1; skb2->len = len + hlen; skb2->h.raw=(char *) skb2->data; - skb2->raddr = skb->raddr; /* For rebuild_header */ /* * Charge the memory for the fragment to any owner * it might posess */ + save_flags(flags); if (sk) + { + cli(); sk->wmem_alloc += skb2->mem_len; - + skb2->sk=sk; + } + restore_flags(flags); + skb2->raddr = skb->raddr; /* For rebuild_header - must be here */ + /* * Copy the packet header into the new buffer. */ @@ -1227,7 +1235,7 @@ ip_statistics.IpFragCreates++; - ip_queue_xmit(sk, dev, skb2, 1); + ip_queue_xmit(sk, dev, skb2, 2); } ip_statistics.IpFragOKs++; } @@ -1236,7 +1244,7 @@ #ifdef CONFIG_IP_FORWARD -/* +/* * Forward an IP datagram to its next destination. */ @@ -1627,7 +1635,8 @@ /* * Queues a packet to be sent, and starts the transmitter * if necessary. if free = 1 then we free the block after - * transmit, otherwise we don't. + * transmit, otherwise we don't. If free==2 we not only + * free the block but also dont assign a new ip seq number. * This routine also needs to put in the total length, * and compute the checksum */ @@ -1655,7 +1664,7 @@ * Do some book-keeping in the packet for later */ - skb->free = free; + skb->dev = dev; skb->when = jiffies; @@ -1672,7 +1681,17 @@ iph = (struct iphdr *)ptr; skb->ip_hdr = iph; iph->tot_len = ntohs(skb->len-dev->hard_header_len); - iph->id = htons(ip_id_count++); + + /* + * No reassigning numbers to fragments... + */ + + if(free!=2) + iph->id = htons(ip_id_count++); + else + free=1; + + skb->free = free; /* * Do we need to fragment. Again this is inefficient. diff -u --recursive --new-file v1.1.16/linux/net/inet/tcp.c linux/net/inet/tcp.c --- v1.1.16/linux/net/inet/tcp.c Tue May 31 12:48:21 1994 +++ linux/net/inet/tcp.c Tue May 31 12:33:06 1994 @@ -71,6 +71,7 @@ * Matthew Dillon : Reworked TCP machine states as per RFC * Gerhard Koerting: PC/TCP workarounds * Adam Caldwell : Assorted timer/timing errors + * Matthew Dillon : Fixed another RST bug * * * To Fix: @@ -78,7 +79,6 @@ * it causes a select. Linux can - given the official select semantics I * feel that _really_ its the BSD network programs that are bust (notably * inetd, which hangs occasionally because of this). - * Protocol closedown badly messed up. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -2044,7 +2044,9 @@ printk("Clean rcv queue\n"); while((skb=skb_dequeue(&sk->receive_queue))!=NULL) { - if(skb->len > 0 && after(skb->h.th->seq + skb->len + 1 , sk->copied_seq)) + /* The +1 is not needed because the FIN takes up sequence space and + is not read!!! */ + if(skb->len > 0 && after(skb->h.th->seq + skb->len/* + 1 */ , sk->copied_seq)) need_reset = 1; kfree_skb(skb, FREE_READ); } diff -u --recursive --new-file v1.1.16/linux/net/inet/udp.c linux/net/inet/udp.c --- v1.1.16/linux/net/inet/udp.c Tue May 24 00:35:06 1994 +++ linux/net/inet/udp.c Tue May 31 12:35:36 1994 @@ -119,6 +119,15 @@ } /* + * Various people wanted BSD UDP semantics. Well they've come + * back out because they slow down response to stuff like dead + * or unreachable name servers and they screw term users something + * chronic. Oh and it violates RFC1122. So basically fix your + * client code people. + */ + +#ifdef CONFIG_I_AM_A_BROKEN_BSD_WEENIE + /* * It's only fatal if we have connected to them. I'm not happy * with this code. Some BSD comparisons need doing. */ @@ -126,10 +135,15 @@ if (icmp_err_convert[err & 0xff].fatal && sk->state == TCP_ESTABLISHED) { sk->err = icmp_err_convert[err & 0xff].errno; -/* sk->err=ECONNREFUSED;*/ + sk->error_report(sk); } - - sk->error_report(sk); +#else + if (icmp_err_convert[err & 0xff].fatal) + { + sk->err = icmp_err_convert[err & 0xff].errno; + sk->error_report(sk); + } +#endif }