Commit ddd9ed00 authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.14o

parent 28067f4d
VERSION = 0.99 VERSION = 0.99
PATCHLEVEL = 14 PATCHLEVEL = 14
ALPHA = n ALPHA = o
all: Version zImage all: Version zImage
...@@ -50,7 +50,7 @@ SVGA_MODE= -DSVGA_MODE=NORMAL_VGA ...@@ -50,7 +50,7 @@ SVGA_MODE= -DSVGA_MODE=NORMAL_VGA
# standard CFLAGS # standard CFLAGS
# #
CFLAGS = -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -pipe CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe
ifdef CONFIG_CPP ifdef CONFIG_CPP
CFLAGS := $(CFLAGS) -x c++ CFLAGS := $(CFLAGS) -x c++
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
include CONFIG include CONFIG
NETDRV_OBJS := net.a(Space.o) net.a(auto_irq.o) net.a(net_init.o) NETDRV_OBJS := net.a(Space.o) net.a(auto_irq.o) net.a(net_init.o)
CFLAGS := $(CFLAGS) -I../../net/inet -I../../net/socket -I../../net CFLAGS := $(CFLAGS) -I../../net/inet
CPP := $(CPP) -I../../net/inet -I../../net/socket -I../../net CPP := $(CPP) -I../../net/inet
# The point of the makefile... # The point of the makefile...
all: net.a all: net.a
......
...@@ -40,9 +40,9 @@ ...@@ -40,9 +40,9 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/in.h> #include <linux/in.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
#include "ax25/ax25.h" #include "ax25.h"
#endif #endif
#include "eth.h" #include "eth.h"
#include "ip.h" #include "ip.h"
......
...@@ -53,19 +53,27 @@ ...@@ -53,19 +53,27 @@
#define MAYBE_CONTINUE(LABEL,DEV) \ #define MAYBE_CONTINUE(LABEL,DEV) \
{if (buffer) kfree(buffer); \ {if (buffer) kfree(buffer); \
if (cont_extent){ \ if (cont_extent){ \
int block, offset; \ int block, offset, offset1; \
struct buffer_head * bh; \ struct buffer_head * bh; \
buffer = kmalloc(cont_size,GFP_KERNEL); \ buffer = kmalloc(cont_size,GFP_KERNEL); \
block = cont_extent; \ block = cont_extent; \
offset = cont_offset; \ offset = cont_offset; \
offset1 = 0; \
if(ISOFS_BUFFER_SIZE(DEV) == 1024) { \ if(ISOFS_BUFFER_SIZE(DEV) == 1024) { \
block <<= 1; \ block <<= 1; \
if (offset >= 1024) block++; \ if (offset >= 1024) block++; \
offset &= 1023; \ offset &= 1023; \
if(offset + cont_size >= 1024) { \
bh = bread(DEV->i_dev, block++, ISOFS_BUFFER_SIZE(DEV)); \
memcpy(buffer, bh->b_data + offset, 1024 - offset); \
brelse(bh); \
offset1 = 1024 - offset; \
offset = 0; \
} \
}; \ }; \
bh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \ bh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \
if(bh){ \ if(bh){ \
memcpy(buffer, bh->b_data, cont_size); \ memcpy(buffer + offset1, bh->b_data + offset, cont_size - offset1); \
brelse(bh); \ brelse(bh); \
chr = (unsigned char *) buffer; \ chr = (unsigned char *) buffer; \
len = cont_size; \ len = cont_size; \
...@@ -291,10 +299,17 @@ int parse_rock_ridge_inode(struct iso_directory_record * de, ...@@ -291,10 +299,17 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
}; };
break; break;
case SIG('T','F'): case SIG('T','F'):
/* Some RRIP writers incorrectly place ctime in the TF_CREATE field.
Try and handle this correctly for either case. */
cnt = 0; /* Rock ridge never appears on a High Sierra disk */ cnt = 0; /* Rock ridge never appears on a High Sierra disk */
if(rr->u.TF.flags & TF_CREATE) inode->i_ctime = iso_date(rr->u.TF.times[cnt++].time, 0); if(rr->u.TF.flags & TF_CREATE)
if(rr->u.TF.flags & TF_MODIFY) inode->i_mtime = iso_date(rr->u.TF.times[cnt++].time, 0); inode->i_ctime = iso_date(rr->u.TF.times[cnt++].time, 0);
if(rr->u.TF.flags & TF_ACCESS) inode->i_atime = iso_date(rr->u.TF.times[cnt++].time, 0); if(rr->u.TF.flags & TF_MODIFY)
inode->i_mtime = iso_date(rr->u.TF.times[cnt++].time, 0);
if(rr->u.TF.flags & TF_ACCESS)
inode->i_atime = iso_date(rr->u.TF.times[cnt++].time, 0);
if(rr->u.TF.flags & TF_ATTRIBUTES)
inode->i_ctime = iso_date(rr->u.TF.times[cnt++].time, 0);
break; break;
case SIG('S','L'): case SIG('S','L'):
{int slen; {int slen;
......
...@@ -59,8 +59,6 @@ struct options { ...@@ -59,8 +59,6 @@ struct options {
unsigned short handling; unsigned short handling;
unsigned short stream; unsigned short stream;
unsigned tcc; unsigned tcc;
int option_length;
void *option_data;
}; };
......
...@@ -30,14 +30,10 @@ struct linger { ...@@ -30,14 +30,10 @@ struct linger {
#define AF_UNSPEC 0 #define AF_UNSPEC 0
#define AF_UNIX 1 #define AF_UNIX 1
#define AF_INET 2 #define AF_INET 2
#define AF_AX25 3
#define AF_IPX 4
/* Protocol families, same as address families. */ /* Protocol families, same as address families. */
#define PF_UNIX AF_UNIX #define PF_UNIX AF_UNIX
#define PF_INET AF_INET #define PF_INET AF_INET
#define PF_AX25 AF_AX25
#define PF_IPX AF_IPX
/* Flags we can use with send/ and recv. */ /* Flags we can use with send/ and recv. */
#define MSG_OOB 1 #define MSG_OOB 1
...@@ -45,10 +41,6 @@ struct linger { ...@@ -45,10 +41,6 @@ struct linger {
/* Setsockoptions(2) level. */ /* Setsockoptions(2) level. */
#define SOL_SOCKET 1 #define SOL_SOCKET 1
#define SOL_IP 2
#define SOL_IPX 3
#define SOL_AX25 4
#define SOL_TCP 5
/* For setsockoptions(2) */ /* For setsockoptions(2) */
#define SO_DEBUG 1 #define SO_DEBUG 1
...@@ -64,19 +56,6 @@ struct linger { ...@@ -64,19 +56,6 @@ struct linger {
#define SO_NO_CHECK 11 #define SO_NO_CHECK 11
#define SO_PRIORITY 12 #define SO_PRIORITY 12
#define SO_LINGER 13 #define SO_LINGER 13
/* IP options */
#define IP_TOS 1
#define IPTOS_LOWDELAY 0x10
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
#define IP_TTL 2
/* IPX options */
#define IPX_TYPE 1
/* AX.25 options */
#define AX25_WINDOW 1
/* TCP options */
#define TCP_MSS 1
#define TCP_NODELAY 2
/* The various priorities. */ /* The various priorities. */
#define SOPRI_INTERACTIVE 0 #define SOPRI_INTERACTIVE 0
......
...@@ -7,17 +7,10 @@ ...@@ -7,17 +7,10 @@
# #
# Note 2! The CFLAGS definition is now in the main makefile... # Note 2! The CFLAGS definition is now in the main makefile...
SUBDIRS := unix socket # only these two lines should need to be changed to remove inet sockets.
# (and the inet/tcpip.o in net.o)
ifdef CONFIG_INET SUBDIRS := unix inet
SUBDIRS := $(SUBDIRS) inet
endif
ifdef CONFIG_IPX
SUBDIRS := $(SUBDIRS) ipx
endif
ifdef CONFIG_AX25
SUBDIRS := $(SUBDIRS) ax25
endif
SUBOBJS := $(foreach f,$(SUBDIRS),$f/$f.o) SUBOBJS := $(foreach f,$(SUBDIRS),$f/$f.o)
......
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
# include "inet/inet.h" # include "inet/inet.h"
#endif #endif
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
#include "ipx/ipxcall.h" #include "inet/ipxcall.h"
#endif #endif
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
#include "ax25/ax25call.h" #include "inet/ax25call.h"
#endif #endif
struct ddi_proto protocols[] = { struct ddi_proto protocols[] = {
...@@ -53,3 +53,43 @@ struct ddi_proto protocols[] = { ...@@ -53,3 +53,43 @@ struct ddi_proto protocols[] = {
}; };
/*
* Section B: Device Driver Modules.
* This section defines which network device drivers
* get linked into the Linux kernel. It is currently
* only used by the INET protocol. Any takers for the
* other protocols like XNS or Novell?
*
* WARNING: THIS SECTION IS NOT YET USED BY THE DRIVERS !!!!!
*/
/*#include "drv/we8003/we8003.h" Western Digital WD-80[01]3 */
/*#include "drv/dp8390/dp8390.h" Donald Becker's DP8390 kit */
/*#inclde "drv/slip/slip.h" Laurence Culhane's SLIP kit */
struct ddi_device devices[] = {
#if CONF_WE8003
{ "WD80x3[EBT]",
"", 0, 1, we8003_init, NULL,
19, 0, DDI_FCHRDEV,
{ 0x280, 0, 15, 0, 32768, 0xD0000 } },
#endif
#if CONF_DP8390
{ "DP8390/WD80x3",
"", 0, 1, dpwd8003_init, NULL,
20, 0, DDI_FCHRDEV,
{ 0, 0, 0, 0, 0, 0, } },
{ "DP8390/NE-x000",
"", 0, 1, dpne2000_init, NULL,
20, 8, DDI_FCHRDEV,
{ 0, 0, 0, 0, 0, 0, } },
{ "DP8390/3C50x",
"", 0, 1, dpec503_init, NULL,
20, 16, DDI_FCHRDEV,
{ 0, 0, 0, 0, 0, 0, } },
#endif
{ NULL,
"", 0, 0, NULL, NULL,
0, 0, 0,
{ 0, 0, 0, 0, 0, 0 } }
};
...@@ -4,11 +4,9 @@ ...@@ -4,11 +4,9 @@
* but it eventually might move to an upper directory of * but it eventually might move to an upper directory of
* the system. * the system.
* *
* Version: @(#)ddi.c 1.28 27/12/93 * Version: @(#)ddi.c 1.0.5 04/22/93
* *
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
*
* Unused pieces nobbled.
*/ */
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -20,9 +18,6 @@ ...@@ -20,9 +18,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/ddi.h> #include <linux/ddi.h>
#include <linux/interrupt.h>
#include "socket/dev.h"
#undef DDI_DEBUG #undef DDI_DEBUG
...@@ -33,32 +28,64 @@ ...@@ -33,32 +28,64 @@
#endif #endif
extern struct ddi_device devices[]; /* device driver map */
extern struct ddi_proto protocols[]; /* network protocols */ extern struct ddi_proto protocols[]; /* network protocols */
/*
* This function gets called with an ASCII string representing the
* ID of some DDI driver. We loop through the DDI Devices table
* and return the address of the control block that has a matching
* "name" field. It is used by upper-level layers that want to
* dynamically bind some UNIX-domain "/dev/XXXX" file name to a
* DDI device driver. The "iflink(8)" program is an example of
* this behaviour.
*/
struct ddi_device *
ddi_map(const char *id)
{
register struct ddi_device *dev;
PRINTK (("DDI: MAP: looking for \"%s\": ", id));
dev = devices;
while (dev->title != NULL) {
if (strncmp(dev->name, id, DDI_MAXNAME) == 0) {
PRINTK (("OK at 0x%X\n", dev));
return(dev);
}
dev++;
}
PRINTK (("NOT FOUND\n"));
return(NULL);
}
/* /*
* This is the function that is called by a kernel routine during * This is the function that is called by a kernel routine during
* system startup. Its purpose is to walk trough the "devices" * system startup. Its purpose is to walk trough the "devices"
* table (defined above), and to call all moduled defined in it. * table (defined above), and to call all moduled defined in it.
*/ */
void
void ddi_init(void) ddi_init(void)
{ {
struct ddi_proto *pro; struct ddi_proto *pro;
struct ddi_device *dev;
PRINTK (("DDI: Starting up!\n")); PRINTK (("DDI: Starting up!\n"));
/* First off, kick all configured protocols. */ /* First off, kick all configured protocols. */
pro = protocols; pro = protocols;
while (pro->name != NULL) while (pro->name != NULL) {
{
(*pro->init)(pro); (*pro->init)(pro);
pro++; pro++;
} }
dev_init(); /* Done. Now kick all configured device drivers. */
/* Initialize the "Buffer Head" pointers. */ dev = devices;
bh_base[INET_BH].routine = inet_bh; while (dev->title != NULL) {
(*dev->init)(dev);
dev++;
}
/* We're all done... */ /* We're all done... */
} }
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
# #
# Note 2! The CFLAGS definition is now in the main makefile... # Note 2! The CFLAGS definition is now in the main makefile...
CFLAGS := $(CFLAGS) -I../socket -I..
CPP := $(CPP) -I../socket -I..
.c.o: .c.o:
$(CC) $(CFLAGS) -c -o $*.o $< $(CC) $(CFLAGS) -c -o $*.o $<
.s.o: .s.o:
...@@ -18,8 +15,10 @@ CPP := $(CPP) -I../socket -I.. ...@@ -18,8 +15,10 @@ CPP := $(CPP) -I../socket -I..
$(CC) $(CFLAGS) -S -o $*.s $< $(CC) $(CFLAGS) -S -o $*.s $<
OBJS = sockinet.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 devinet.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
# ipx.o ax25.o ax25_in.o ax25_out.o ax25_subr.o ax25_timer.o
ifdef CONFIG_INET ifdef CONFIG_INET
......
NET2Debugged 1.28 README NET2Debugged 1.24 README
------------------------ ------------------------
Major Changes
o PLIP driver sort of works
o UDP and RAW have been partially rewritten for speed
o Internals heavily cleaned up, and memory monitoring of network
memory is now done. (On shift-scroll-lock)
o ARP should now not generate garbage
o Using MSG_PEEK can't cause race conditions and crashes
o Support for bootp clients.
o Supports RFC931 TAP authd
o NFS problems with certain types of network configuration are
fixed.
o Doesn't forward packets for other subnet (can cause packet storms)
o TCP won't ack rst frames causing packet storms (especially with
Lan workplace for DOS).
o Numerous fixes for solidity
o Verify_area used properly.
o MSG_PEEK is faster again
o Minor TCP fixes. Hopefully no more TCP lockups (ha!)
o Donald's promiscuous mode. Go forth and write protocol analysers...
------------------------------------------------------------------------- -------------------------------------------------------------------------
NOTE: NOTE:
Drivers for this stack set must be using alloc_skb() not just Drivers for this stack set must be using alloc_skb() not just
......
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Definitions for the ARP protocol module. * Definitions for the ARP protocol module.
* *
* Version: @(#)arp.h 1.28 24/12/93 * Version: @(#)arp.h 1.0.6 05/21/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
...@@ -26,31 +26,29 @@ ...@@ -26,31 +26,29 @@
#define ARP_QUEUE_MAGIC 0x0432447A /* magic # for queues */ #define ARP_QUEUE_MAGIC 0x0432447A /* magic # for queues */
/* /* This structure defines the ARP mapping cache. */
* This structure defines the ARP mapping cache. struct arp_table {
*/
struct arp_table
{
struct arp_table *next; struct arp_table *next;
volatile unsigned long last_used; volatile unsigned long last_used;
unsigned int flags; unsigned int flags;
#if 1
unsigned long ip; unsigned long ip;
#else
unsigned char pa[MAX_ADDR_LEN];
unsigned char plen;
unsigned char ptype;
#endif
unsigned char ha[MAX_ADDR_LEN]; unsigned char ha[MAX_ADDR_LEN];
unsigned char hlen; unsigned char hlen;
unsigned char htype; unsigned char htype;
}; };
/* /* This is also used in "sock.c" and "tcp.c" - YUCK! - FvK */
* This is also used in "sock.c" and "tcp.c" - YUCK! - FvK
*/
extern struct sk_buff *arp_q; extern struct sk_buff *arp_q;
extern void arp_destroy(unsigned long paddr); extern void arp_destroy(unsigned long paddr);
extern void arp_destroy_maybe(unsigned long paddr);
extern int arp_rcv(struct sk_buff *skb, struct device *dev, extern int arp_rcv(struct sk_buff *skb, struct device *dev,
struct packet_type *pt); struct packet_type *pt);
extern int arp_find(unsigned char *haddr, unsigned long paddr, extern int arp_find(unsigned char *haddr, unsigned long paddr,
......
...@@ -13,8 +13,6 @@ ...@@ -13,8 +13,6 @@
* 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 * 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. * AX.25 now works right, and SPX is feasible.
* Alan Cox : Tidied up ready for the big day.
* Alan Cox : Fixed write select of no IP protocol crash.
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -138,13 +136,6 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock, ...@@ -138,13 +136,6 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
return skb; return skb;
} }
/*
* Free a datagram buffer. This has some conditions to watch. We keep
* a user count so the last user may free the buffer. If however the
* buffer has a valid next pointer it was never removed and all the
* users PEEKed at it - so don't free it yet.
*/
void skb_free_datagram(struct sk_buff *skb) void skb_free_datagram(struct sk_buff *skb)
{ {
unsigned long flags; unsigned long flags;
...@@ -194,11 +185,7 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait) ...@@ -194,11 +185,7 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait)
return(0); return(0);
case SEL_OUT: case SEL_OUT:
if(sk->prot && sk->prot->wspace(sk) >= MIN_WRITE_SPACE) if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE)
{
return(1);
}
if(sk->prot==NULL && sk->sndbuf-sk->wmem_alloc >= MIN_WRITE_SPACE)
{ {
return(1); return(1);
} }
......
...@@ -790,6 +790,7 @@ static inline int bad_mask(unsigned long mask, unsigned long addr) ...@@ -790,6 +790,7 @@ static inline int bad_mask(unsigned long mask, unsigned long addr)
return 0; return 0;
} }
/* Perform the SIOCxIFxxx calls. */ /* Perform the SIOCxIFxxx calls. */
static int static int
dev_ifsioc(void *arg, unsigned int getset) dev_ifsioc(void *arg, unsigned int getset)
......
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Interface (streams) handling functions.
*
* Version: @(#)dev.c 1.28 20/12/93
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
*
* Fixes:
* Alan Cox: check_addr returns a value for a wrong subnet
* ie not us but don't forward this!
* Alan Cox: block timer if the inet_bh handler is running
* Alan Cox: generic queue code added. A lot neater now
* C.E.Hawkins: SIOCGIFCONF only reports 'upped' interfaces
* C.E.Hawkins: IFF_PROMISC support
* Alan Cox: Supports Donald Beckers new hardware
* multicast layer, but not yet multicast lists.
* 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
* Alan Cox: A Couple more escaped verify_area calls die
* Alan Cox: IP_SET_DEV is gone (forever) as per Fred's comment.
* Alan Cox: Grand tidy up ready for the big day.
* Alan Cox: Handles dev_open errors correctly.
* Alan Cox: IP and generic parts split
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
#include "inet.h"
#include "devinet.h"
#include "eth.h"
#include "ip.h"
#include "route.h"
#include "protocol.h"
#include "tcp.h"
#include "skbuff.h"
/*
* Determine a default network mask, based on the IP address.
*/
unsigned long ip_get_mask(unsigned long addr)
{
unsigned long dst;
if (addr == 0L)
return(0L); /* special case */
dst = ntohl(addr);
if (IN_CLASSA(dst))
return(htonl(IN_CLASSA_NET));
if (IN_CLASSB(dst))
return(htonl(IN_CLASSB_NET));
if (IN_CLASSC(dst))
return(htonl(IN_CLASSC_NET));
/* Something else, probably a subnet. */
return(0);
}
/*
* See if a pair of addresses match.
*/
int ip_addr_match(unsigned long me, unsigned long him)
{
int i;
unsigned long mask=0xFFFFFFFF;
DPRINTF((DBG_DEV, "ip_addr_match(%s, ", in_ntoa(me)));
DPRINTF((DBG_DEV, "%s)\n", in_ntoa(him)));
/* Fast path for 99.9% of cases */
if (me == him)
return(1);
for (i = 0; i < 4; i++, me >>= 8, him >>= 8, mask >>= 8)
{
if ((me & 0xFF) != (him & 0xFF))
{
/*
* The only way this could be a match is for
* the rest of addr1 to be 0 or 255.
*/
if (me != 0 && me != mask)
return(0);
return(1);
}
}
return(1);
}
/*
* Check the address for our address, broadcasts, etc.
*
* This routine is used a lot, and in many time critical
* places. It's already _TOO_ slow so be careful how you
* alter it.
*/
int chk_addr(unsigned long addr)
{
struct device *dev;
unsigned long dst;
DPRINTF((DBG_DEV, "chk_addr(%s) --> ", in_ntoa(addr)));
dst = ntohl(addr);
/*
* Accept both `all ones' and `all zeros' as BROADCAST.
* All 0's is the old BSD broadcast.
*/
if (dst == INADDR_ANY || dst == INADDR_BROADCAST)
{
DPRINTF((DBG_DEV, "BROADCAST\n"));
return(IS_BROADCAST);
}
/* Accept all of the `loopback' class A net. */
if ((dst & IN_CLASSA_NET) == 0x7F000000L)
{
DPRINTF((DBG_DEV, "LOOPBACK\n"));
/*
* We force `loopback' to be equal to MY_ADDR.
*/
return(IS_MYADDR);
/* return(IS_LOOPBACK); */
}
/* OK, now check the interface addresses. */
for (dev = dev_base; dev != NULL; dev = dev->next)
{
if (!(dev->flags&IFF_UP))
continue;
if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
return(IS_MYADDR);
/* Is it the exact IP address? */
if (addr == dev->pa_addr)
{
DPRINTF((DBG_DEV, "MYADDR\n"));
return(IS_MYADDR);
}
/* Nope. Check for a subnetwork broadcast. */
if ((addr & dev->pa_mask) == (dev->pa_addr & dev->pa_mask))
{
if ((addr & ~dev->pa_mask) == 0)
{
DPRINTF((DBG_DEV, "SUBBROADCAST-0\n"));
return(IS_BROADCAST);
}
if (((addr & ~dev->pa_mask) | dev->pa_mask)
== INADDR_BROADCAST)
{
DPRINTF((DBG_DEV, "SUBBROADCAST-1\n"));
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"));
return(0); /* no match at all */
}
/*
* Retrieve our own address.
* Because the loopback address (127.0.0.1) is already recognized
* automatically, we can use the loopback interface's address as
* our "primary" interface. This is the addressed used by IP et
* al when it doesn't know which address to use (i.e. it does not
* yet know from or to which interface to go...).
*/
unsigned long my_addr(void)
{
struct device *dev;
for (dev = dev_base; dev != NULL; dev = dev->next)
{
if (dev->flags & IFF_LOOPBACK)
return(dev->pa_addr);
}
return(0);
}
/*
* Find an interface that can handle addresses for a certain address.
*/
struct device *dev_check(unsigned long addr)
{
struct device *dev;
for (dev = dev_base; dev; dev = dev->next)
if ((dev->flags & IFF_UP) && (dev->flags & IFF_POINTOPOINT) &&
(addr == dev->pa_dstaddr))
return dev;
for (dev = dev_base; dev; dev = dev->next)
if ((dev->flags & IFF_UP) && !(dev->flags & IFF_POINTOPOINT) &&
(dev->flags & IFF_LOOPBACK ? (addr == dev->pa_addr) :
(dev->pa_mask & addr) == (dev->pa_addr & dev->pa_mask)))
break;
/* no need to check broadcast addresses */
return dev;
}
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Definitions for the INET bits of the interfaces handler.
*
*/
#ifndef _DEVINET_H
#define _DEVINET_H
#ifndef _DEV_H
#include "dev.h"
#endif
extern int ip_addr_match(unsigned long addr1, unsigned long addr2);
extern int chk_addr(unsigned long addr);
extern struct device *dev_check(unsigned long daddr);
extern unsigned long my_addr(void);
#endif /* _DEVINET_H */
...@@ -5,27 +5,24 @@ ...@@ -5,27 +5,24 @@
* *
* Ethernet-type device handling. * Ethernet-type device handling.
* *
* Version: @(#)eth.c 1.28 20/12/93 * Version: @(#)eth.c 1.0.7 05/25/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk> * Mark Evans, <evansmp@uhura.aston.ac.uk>
* *
* Fixes: * Fixes:
* Mr Linux : Arp problems. * Mr Linux : Arp problems
* Alan Cox : Generic queue tidyup (very tiny here). * Alan Cox : Generic queue tidyup (very tiny here)
* Alan Cox : eth_header ntohs should be htons. * Alan Cox : eth_header ntohs should be htons
* Alan Cox : eth_rebuild_header missing an htons and * Alan Cox : eth_rebuild_header missing an htons and
* minor other things. * minor other things.
* Tegge : Arp bug fixes.
* Alan Cox : Tidy up ready for the big day.
* *
* 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
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -36,19 +33,18 @@ ...@@ -36,19 +33,18 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/in.h> #include <linux/in.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "eth.h" #include "eth.h"
#include "ip.h" #include "ip.h"
#include "route.h" #include "route.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include <linux/errno.h> #include <linux/errno.h>
#include "arp.h" #include "arp.h"
#ifdef ETH_DEBUG
/* Display an Ethernet address in readable format. */ /* Display an Ethernet address in readable format. */
char *eth_print(unsigned char *ptr) char *eth_print(unsigned char *ptr)
{ {
...@@ -61,16 +57,32 @@ char *eth_print(unsigned char *ptr) ...@@ -61,16 +57,32 @@ char *eth_print(unsigned char *ptr)
); );
return(buff); return(buff);
} }
#endif
#ifdef ETH_DEBUG void eth_setup(char *str, int *ints)
{
/* struct device *d = dev_base;
* Display the contents of the Ethernet MAC header.
*/ if (!str || !*str)
return;
while (d) {
if (!strcmp(str,d->name)) {
if (ints[0] > 0)
d->irq=ints[1];
if (ints[0] > 1)
d->base_addr=ints[2];
if (ints[0] > 2)
d->mem_start=ints[3];
if (ints[0] > 3)
d->mem_end=ints[4];
break;
}
d=d->next;
}
}
void eth_dump(struct ethhdr *eth) /* Display the contents of the Ethernet MAC header. */
void
eth_dump(struct ethhdr *eth)
{ {
if (inet_debug != DBG_ETH) return; if (inet_debug != DBG_ETH) return;
...@@ -79,17 +91,10 @@ void eth_dump(struct ethhdr *eth) ...@@ -79,17 +91,10 @@ void eth_dump(struct ethhdr *eth)
printk("TYPE = %04X\n", ntohs(eth->h_proto)); printk("TYPE = %04X\n", ntohs(eth->h_proto));
} }
#endif
/*
* Create the Ethernet MAC header.
*
* ARP might prevent this from working all in one go. See also
* the rebuild header function.
*/
int eth_header(unsigned char *buff, struct device *dev, unsigned short type, /* Create the Ethernet MAC header. */
int
eth_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)
{ {
struct ethhdr *eth; struct ethhdr *eth;
...@@ -102,8 +107,7 @@ int eth_header(unsigned char *buff, struct device *dev, unsigned short type, ...@@ -102,8 +107,7 @@ int eth_header(unsigned char *buff, struct device *dev, unsigned short type,
eth->h_proto = htons(type); eth->h_proto = htons(type);
/* We don't ARP for the LOOPBACK device... */ /* We don't ARP for the LOOPBACK device... */
if (dev->flags & IFF_LOOPBACK) if (dev->flags & IFF_LOOPBACK) {
{
DPRINTF((DBG_DEV, "ETH: No header for loopback\n")); DPRINTF((DBG_DEV, "ETH: No header for loopback\n"));
memcpy(eth->h_source, dev->dev_addr, dev->addr_len); memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
memset(eth->h_dest, 0, dev->addr_len); memset(eth->h_dest, 0, dev->addr_len);
...@@ -111,21 +115,16 @@ int eth_header(unsigned char *buff, struct device *dev, unsigned short type, ...@@ -111,21 +115,16 @@ int eth_header(unsigned char *buff, struct device *dev, unsigned short type,
} }
/* Check if we can use the MAC BROADCAST address. */ /* Check if we can use the MAC BROADCAST address. */
if (chk_addr(daddr) == IS_BROADCAST) if (chk_addr(daddr) == IS_BROADCAST) {
{
DPRINTF((DBG_DEV, "ETH: Using MAC Broadcast\n")); DPRINTF((DBG_DEV, "ETH: Using MAC Broadcast\n"));
memcpy(eth->h_source, dev->dev_addr, dev->addr_len); memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
memcpy(eth->h_dest, dev->broadcast, dev->addr_len); memcpy(eth->h_dest, dev->broadcast, dev->addr_len);
return(dev->hard_header_len); return(dev->hard_header_len);
} }
/*
* We disable interrupts here to avoid a race if the ARP
* reply is too quick.
*/
cli(); cli();
memcpy(eth->h_source, &saddr, 4); memcpy(eth->h_source, &saddr, 4);
/* No. Ask ARP to resolve the Ethernet address. */ /* No. Ask ARP to resolve the Ethernet address. */
if (arp_find(eth->h_dest, daddr, dev, dev->pa_addr/* saddr */)) if (arp_find(eth->h_dest, daddr, dev, saddr))
{ {
sti(); sti();
if(type!=ETH_P_IP) if(type!=ETH_P_IP)
...@@ -142,14 +141,9 @@ int eth_header(unsigned char *buff, struct device *dev, unsigned short type, ...@@ -142,14 +141,9 @@ int eth_header(unsigned char *buff, struct device *dev, unsigned short type,
} }
/* /* Rebuild the Ethernet MAC header. */
* Rebuild the Ethernet MAC header. int
* eth_rebuild_header(void *buff, struct device *dev)
* We've got a 'stuck' packet that failed to go out before. See if
* the arp is resolved and we can finally shift it.
*/
int eth_rebuild_header(void *buff, struct device *dev)
{ {
struct ethhdr *eth; struct ethhdr *eth;
unsigned long src, dst; unsigned long src, dst;
...@@ -161,19 +155,15 @@ int eth_rebuild_header(void *buff, struct device *dev) ...@@ -161,19 +155,15 @@ int eth_rebuild_header(void *buff, struct device *dev)
DPRINTF((DBG_DEV, "ETH: RebuildHeader: SRC=%s ", in_ntoa(src))); DPRINTF((DBG_DEV, "ETH: RebuildHeader: SRC=%s ", in_ntoa(src)));
DPRINTF((DBG_DEV, "DST=%s\n", in_ntoa(dst))); DPRINTF((DBG_DEV, "DST=%s\n", in_ntoa(dst)));
if(eth->h_proto!=htons(ETH_P_ARP)) /* This ntohs kind of helps a bit! */ if(eth->h_proto!=htons(ETH_P_ARP)) /* This ntohs kind of helps a bit! */
if (arp_find(eth->h_dest, dst, dev, dev->pa_addr /* src */)) if (arp_find(eth->h_dest, dst, dev, src)) return(1);
/* Still not known */
return(1);
memcpy(eth->h_source, dev->dev_addr, dev->addr_len); memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
return(0); return(0);
} }
/* /* Add an ARP entry for a host on this interface. */
* Add an ARP entry for a host on this interface. void
*/ eth_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
void eth_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
{ {
struct ethhdr *eth; struct ethhdr *eth;
...@@ -182,19 +172,9 @@ void eth_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev) ...@@ -182,19 +172,9 @@ void eth_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
} }
/* /* Determine the packet's protocol ID. */
* Determine the packet's protocol ID. unsigned short
* eth_type_trans(struct sk_buff *skb, struct device *dev)
* Ethernet comes in two 'species' DIX (Digitial Intel Xerox) and IEE802.3
* needless to say they are different. Fortunately there is a way of telling
* them apart. All 'normal' modern DIX service ID's are >1536.
* All IEE802.3 frames have a length at this position and that cannot be
* >=1536. Note IEE802.3 frames have a second 802.2 header normally. We don't
* deal with this bit in the current kernel, but a user using SOCK_PACKET
* for 802.3 frames can do so.
*/
unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev)
{ {
struct ethhdr *eth; struct ethhdr *eth;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Internet Control Message Protocol (ICMP) * Internet Control Message Protocol (ICMP)
* *
* Version: @(#)icmp.c 1.28 20/12/93 * Version: @(#)icmp.c 1.0.11 06/02/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
* Fixes: * Fixes:
* Alan Cox : Generic queue usage. * Alan Cox : Generic queue usage.
* Gerhard Koerting: ICMP addressing corrected * Gerhard Koerting: ICMP addressing corrected
* Tegge : Subnet problems
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -22,7 +21,6 @@ ...@@ -22,7 +21,6 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -30,14 +28,14 @@ ...@@ -30,14 +28,14 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/in.h> #include <linux/in.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "ip.h" #include "ip.h"
#include "route.h" #include "route.h"
#include "protocol.h" #include "protocol.h"
#include "icmp.h" #include "icmp.h"
#include "tcp.h" #include "tcp.h"
#include "skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -65,30 +63,21 @@ struct icmp_err icmp_err_convert[] = { ...@@ -65,30 +63,21 @@ struct icmp_err icmp_err_convert[] = {
}; };
#ifdef ICMP_DEBUG
/* Display the contents of an ICMP header. */ /* Display the contents of an ICMP header. */
static void static void
print_icmp(struct icmphdr *icmph) print_icmp(struct icmphdr *icmph)
{ {
if (inet_debug != DBG_ICMP) if (inet_debug != DBG_ICMP) return;
return;
printk("ICMP: type = %d, code = %d, checksum = %X\n", printk("ICMP: type = %d, code = %d, checksum = %X\n",
icmph->type, icmph->code, icmph->checksum); icmph->type, icmph->code, icmph->checksum);
printk(" gateway = %s\n", in_ntoa(icmph->un.gateway)); printk(" gateway = %s\n", in_ntoa(icmph->un.gateway));
} }
#endif
/* /* Send an ICMP message. */
* Send an ICMP message. void
* icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
* ICMP is the control message protocol for error reporting in IP.
* A good document to start with for this stuff is RFC 791.
*/
void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct iphdr *iph; struct iphdr *iph;
...@@ -105,13 +94,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -105,13 +94,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
sizeof(struct iphdr) + 8; /* amount of header to return */ sizeof(struct iphdr) + 8; /* amount of header to return */
skb = (struct sk_buff *) alloc_skb(len, GFP_ATOMIC); skb = (struct sk_buff *) alloc_skb(len, GFP_ATOMIC);
/* We just forget about failed ICMP messages. ICMP is unreliable anyway and
things will sort out in time */
if (skb == NULL) if (skb == NULL)
return; return;
skb->sk = NULL; skb->sk = NULL;
skb->mem_addr = skb;
skb->mem_len = len;
len -= sizeof(struct sk_buff); len -= sizeof(struct sk_buff);
/* Find the IP header. */ /* Find the IP header. */
...@@ -120,9 +108,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -120,9 +108,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
/* 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, dev->pa_addr, iph->saddr, offset = ip_build_header(skb, dev->pa_addr, iph->saddr,
&dev, IPPROTO_ICMP, NULL, len, 25, IPTOS_RELIABILITY); &dev, IPPROTO_ICMP, NULL, len);
if (offset < 0) if (offset < 0) {
{
skb->sk = NULL; skb->sk = NULL;
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
return; return;
...@@ -140,20 +127,17 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -140,20 +127,17 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
icmph->checksum = ip_compute_csum((unsigned char *)icmph, icmph->checksum = ip_compute_csum((unsigned char *)icmph,
sizeof(struct icmphdr) + sizeof(struct iphdr) + 8); sizeof(struct icmphdr) + sizeof(struct iphdr) + 8);
#ifdef ICMP_DEBUG
DPRINTF((DBG_ICMP, ">>\n")); DPRINTF((DBG_ICMP, ">>\n"));
print_icmp(icmph); print_icmp(icmph);
#endif
/* Send it and free it. */ /* Send it and free it. */
ip_queue_xmit(NULL, dev, skb, 1); ip_queue_xmit(NULL, dev, skb, 1);
} }
/* /* Handle ICMP_UNREACH and ICMP_QUENCH. */
* Handle ICMP_UNREACH and ICMP_QUENCH. static void
*/ icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb)
static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb)
{ {
struct inet_protocol *ipprot; struct inet_protocol *ipprot;
struct iphdr *iph; struct iphdr *iph;
...@@ -162,8 +146,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb) ...@@ -162,8 +146,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb)
err = (icmph->type << 8) | icmph->code; err = (icmph->type << 8) | icmph->code;
iph = (struct iphdr *) (icmph + 1); iph = (struct iphdr *) (icmph + 1);
switch(icmph->code & 7) switch(icmph->code & 7) {
{
case ICMP_NET_UNREACH: case ICMP_NET_UNREACH:
DPRINTF((DBG_ICMP, "ICMP: %s: network unreachable.\n", DPRINTF((DBG_ICMP, "ICMP: %s: network unreachable.\n",
in_ntoa(iph->daddr))); in_ntoa(iph->daddr)));
...@@ -198,15 +181,13 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb) ...@@ -198,15 +181,13 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb)
/* This can change while we are doing it. */ /* This can change while we are doing it. */
ipprot = (struct inet_protocol *) inet_protos[hash]; ipprot = (struct inet_protocol *) inet_protos[hash];
while(ipprot != NULL) while(ipprot != NULL) {
{
struct inet_protocol *nextip; struct inet_protocol *nextip;
nextip = (struct inet_protocol *) ipprot->next; nextip = (struct inet_protocol *) ipprot->next;
/* Pass it off to everyone who wants it. */ /* Pass it off to everyone who wants it. */
if (iph->protocol == ipprot->protocol && ipprot->err_handler) if (iph->protocol == ipprot->protocol && ipprot->err_handler) {
{
ipprot->err_handler(err, (unsigned char *)(icmph + 1), ipprot->err_handler(err, (unsigned char *)(icmph + 1),
iph->daddr, iph->saddr, ipprot); iph->daddr, iph->saddr, ipprot);
} }
...@@ -218,19 +199,16 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb) ...@@ -218,19 +199,16 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb)
} }
/* /* Handle ICMP_REDIRECT. */
* Handle ICMP_REDIRECT. static void
*/ icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev)
static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev)
{ {
struct iphdr *iph; struct iphdr *iph;
unsigned long ip; unsigned long ip;
iph = (struct iphdr *) (icmph + 1); iph = (struct iphdr *) (icmph + 1);
ip = iph->daddr; ip = iph->daddr;
switch(icmph->code & 7) switch(icmph->code & 7) {
{
case ICMP_REDIR_NET: case ICMP_REDIR_NET:
rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY), rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
ip, 0, icmph->un.gateway, dev); ip, 0, icmph->un.gateway, dev);
...@@ -254,7 +232,8 @@ static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct dev ...@@ -254,7 +232,8 @@ static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct dev
/* Handle ICMP_ECHO ("ping") requests. */ /* Handle ICMP_ECHO ("ping") requests. */
static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, static void
icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
unsigned long saddr, unsigned long daddr, int len, unsigned long saddr, unsigned long daddr, int len,
struct options *opt) struct options *opt)
{ {
...@@ -264,20 +243,20 @@ static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device ...@@ -264,20 +243,20 @@ static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device
size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len; size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len;
skb2 = alloc_skb(size, GFP_ATOMIC); skb2 = alloc_skb(size, GFP_ATOMIC);
if (skb2 == NULL) if (skb2 == NULL) {
{
skb->sk = NULL; skb->sk = NULL;
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
return; return;
} }
skb2->sk = NULL; skb2->sk = NULL;
skb2->mem_addr = skb2;
skb2->mem_len = size;
skb2->free = 1; skb2->free = 1;
/* Build Layer 2-3 headers for message back to source */ /* Build Layer 2-3 headers for message back to source */
offset = ip_build_header(skb2, daddr, saddr, &dev, offset = ip_build_header(skb2, daddr, saddr, &dev,
IPPROTO_ICMP, opt, len, 255, IPTOS_RELIABILITY); IPPROTO_ICMP, opt, len);
if (offset < 0) if (offset < 0) {
{
printk("ICMP: Could not build IP Header for ICMP ECHO Response\n"); printk("ICMP: Could not build IP Header for ICMP ECHO Response\n");
kfree_skb(skb2,FREE_WRITE); kfree_skb(skb2,FREE_WRITE);
skb->sk = NULL; skb->sk = NULL;
...@@ -304,11 +283,9 @@ static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device ...@@ -304,11 +283,9 @@ static void icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device
} }
/* /* Handle the ICMP INFORMATION REQUEST. */
* Handle the ICMP INFORMATION REQUEST. static void
*/ icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
static void icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
unsigned long saddr, unsigned long daddr, int len, unsigned long saddr, unsigned long daddr, int len,
struct options *opt) struct options *opt)
{ {
...@@ -318,11 +295,9 @@ static void icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device ...@@ -318,11 +295,9 @@ static void icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device
} }
/* /* Handle ICMP_ADRESS_MASK requests. */
* Handle ICMP_ADRESS_MASK requests. static void
*/ icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
unsigned long saddr, unsigned long daddr, int len, unsigned long saddr, unsigned long daddr, int len,
struct options *opt) struct options *opt)
{ {
...@@ -332,20 +307,20 @@ static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct devi ...@@ -332,20 +307,20 @@ static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct devi
size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len; size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len;
skb2 = alloc_skb(size, GFP_ATOMIC); skb2 = alloc_skb(size, GFP_ATOMIC);
if (skb2 == NULL) if (skb2 == NULL) {
{
skb->sk = NULL; skb->sk = NULL;
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
return; return;
} }
skb2->sk = NULL; skb2->sk = NULL;
skb2->mem_addr = skb2;
skb2->mem_len = size;
skb2->free = 1; skb2->free = 1;
/* Build Layer 2-3 headers for message back to source */ /* Build Layer 2-3 headers for message back to source */
offset = ip_build_header(skb2, daddr, saddr, &dev, offset = ip_build_header(skb2, daddr, saddr, &dev,
IPPROTO_ICMP, opt, len, 255, IPTOS_RELIABILITY); IPPROTO_ICMP, opt, len);
if (offset < 0) if (offset < 0) {
{
printk("ICMP: Could not build IP Header for ICMP ADDRESS Response\n"); printk("ICMP: Could not build IP Header for ICMP ADDRESS Response\n");
kfree_skb(skb2,FREE_WRITE); kfree_skb(skb2,FREE_WRITE);
skb->sk = NULL; skb->sk = NULL;
...@@ -375,11 +350,9 @@ static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct devi ...@@ -375,11 +350,9 @@ static void icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct devi
} }
/* /* Deal with incoming ICMP packets. */
* Deal with incoming ICMP packets. int
*/ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
unsigned long daddr, unsigned short len, unsigned long daddr, unsigned short len,
unsigned long saddr, int redo, struct inet_protocol *protocol) unsigned long saddr, int redo, struct inet_protocol *protocol)
{ {
...@@ -387,8 +360,7 @@ int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, ...@@ -387,8 +360,7 @@ int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
unsigned char *buff; unsigned char *buff;
/* Drop broadcast packets. */ /* Drop broadcast packets. */
if (chk_addr(daddr) == IS_BROADCAST) if (chk_addr(daddr) == IS_BROADCAST) {
{
DPRINTF((DBG_ICMP, "ICMP: Discarded broadcast from %s\n", DPRINTF((DBG_ICMP, "ICMP: Discarded broadcast from %s\n",
in_ntoa(saddr))); in_ntoa(saddr)));
skb1->sk = NULL; skb1->sk = NULL;
...@@ -400,20 +372,17 @@ int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, ...@@ -400,20 +372,17 @@ int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
icmph = (struct icmphdr *) buff; icmph = (struct icmphdr *) buff;
/* Validate the packet first */ /* Validate the packet first */
if (ip_compute_csum((unsigned char *) icmph, len)) if (ip_compute_csum((unsigned char *) icmph, len)) {
{
/* Failed checksum! */ /* Failed checksum! */
printk("ICMP: failed checksum from %s!\n", in_ntoa(saddr)); printk("ICMP: failed checksum from %s!\n", in_ntoa(saddr));
skb1->sk = NULL; skb1->sk = NULL;
kfree_skb(skb1, FREE_READ); kfree_skb(skb1, FREE_READ);
return(0); return(0);
} }
#ifdef ICMP_DEBUG
print_icmp(icmph); print_icmp(icmph);
#endif
/* Parse the ICMP message */ /* Parse the ICMP message */
switch(icmph->type) switch(icmph->type) {
{
case ICMP_TIME_EXCEEDED: case ICMP_TIME_EXCEEDED:
case ICMP_DEST_UNREACH: case ICMP_DEST_UNREACH:
case ICMP_SOURCE_QUENCH: case ICMP_SOURCE_QUENCH:
...@@ -458,16 +427,11 @@ int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, ...@@ -458,16 +427,11 @@ int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
} }
/* /* Perform any ICMP-related I/O control requests. */
* Perform any ICMP-related I/O control requests. int
* icmp_ioctl(struct sock *sk, int cmd, unsigned long arg)
* In the case of ICMP all the user can do is play with the debygging
*/
int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{ {
switch(cmd) switch(cmd) {
{
case DDIOCSDBG: case DDIOCSDBG:
return(dbg_ioctl((void *) arg, DBG_ICMP)); return(dbg_ioctl((void *) arg, DBG_ICMP));
default: default:
......
This diff is collapsed.
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include <linux/ip.h> #include <linux/ip.h>
#include "sockinet.h"
#include "sock.h" /* struct sock */
/* IP flags. */ /* IP flags. */
#define IP_CE 0x8000 /* Flag: "Congestion" */ #define IP_CE 0x8000 /* Flag: "Congestion" */
...@@ -69,8 +69,7 @@ extern int ip_build_header(struct sk_buff *skb, ...@@ -69,8 +69,7 @@ extern int ip_build_header(struct sk_buff *skb,
unsigned long saddr, unsigned long saddr,
unsigned long daddr, unsigned long daddr,
struct device **dev, int type, struct device **dev, int type,
struct options *opt, int len, struct options *opt, int len);
int tos,int ttl);
extern unsigned short ip_compute_csum(unsigned char * buff, int len); extern unsigned short ip_compute_csum(unsigned char * buff, int len);
extern int ip_rcv(struct sk_buff *skb, struct device *dev, extern int ip_rcv(struct sk_buff *skb, struct device *dev,
struct packet_type *pt); struct packet_type *pt);
...@@ -78,6 +77,5 @@ extern void ip_queue_xmit(struct sock *sk, ...@@ -78,6 +77,5 @@ extern void ip_queue_xmit(struct sock *sk,
struct device *dev, struct sk_buff *skb, struct device *dev, struct sk_buff *skb,
int free); int free);
extern void ip_retransmit(struct sock *sk, int all); extern void ip_retransmit(struct sock *sk, int all);
extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen);
extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen);
#endif /* _IP_H */ #endif /* _IP_H */
...@@ -5,59 +5,55 @@ ...@@ -5,59 +5,55 @@
* *
* Pseudo-driver for the loopback interface. * Pseudo-driver for the loopback interface.
* *
* Version: @(#)loopback.c 1.28 20/12/93 * Version: @(#)loopback.c 1.0.4b 08/16/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald Becker, <becker@super.org> * Donald Becker, <becker@super.org>
* *
* This file should be in drivers/net, but our glorious leader
* has put it here, and who are we to argue with the Linus 8-)
*
* 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
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/tty.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/if_ether.h> /* For the statistics structure. */ #include <linux/if_ether.h> /* For the statistics structure. */
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/io.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "eth.h" #include "eth.h"
#include "ip.h" #include "ip.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include "arp.h" #include "arp.h"
static int loopback_xmit(struct sk_buff *skb, struct device *dev) static int
loopback_xmit(struct sk_buff *skb, struct device *dev)
{ {
struct enet_statistics *stats = (struct enet_statistics *)dev->priv; struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
int done; int done;
DPRINTF((DBG_LOOPB, "loopback_xmit(dev=%X, skb=%X)\n", dev, skb)); DPRINTF((DBG_LOOPB, "loopback_xmit(dev=%X, skb=%X)\n", dev, skb));
if (skb == NULL || dev == NULL) if (skb == NULL || dev == NULL) return(0);
return(0);
cli(); cli();
if (dev->tbusy != 0) if (dev->tbusy != 0) {
{
sti(); sti();
stats->tx_errors++; stats->tx_errors++;
return(1); return(1);
...@@ -66,11 +62,9 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) ...@@ -66,11 +62,9 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev)
sti(); sti();
done = dev_rint((unsigned char *)(skb+1), skb->len, 0, dev); done = dev_rint((unsigned char *)(skb+1), skb->len, 0, dev);
if (skb->free) if (skb->free) kfree_skb(skb, FREE_WRITE);
kfree_skb(skb, FREE_WRITE);
while (done != 1) while (done != 1) {
{
done = dev_rint(NULL, 0, 0, dev); done = dev_rint(NULL, 0, 0, dev);
} }
stats->tx_packets++; stats->tx_packets++;
...@@ -95,13 +89,15 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) ...@@ -95,13 +89,15 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev)
return(0); return(0);
} }
static struct enet_statistics *get_stats(struct device *dev) static struct enet_statistics *
get_stats(struct device *dev)
{ {
return (struct enet_statistics *)dev->priv; return (struct enet_statistics *)dev->priv;
} }
/* Initialize the rest of the LOOPBACK device. */ /* Initialize the rest of the LOOPBACK device. */
int loopback_init(struct device *dev) int
loopback_init(struct device *dev)
{ {
dev->mtu = 2000; /* MTU */ dev->mtu = 2000; /* MTU */
dev->tbusy = 0; dev->tbusy = 0;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* PACKET - implements raw packet sockets. * PACKET - implements raw packet sockets.
* *
* Version: @(#)packet.c 1.28 20/12/93 * Version: @(#)packet.c 1.0.6 05/25/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
* added. Also fixed the peek/read crash * added. Also fixed the peek/read crash
* from all old Linux datagram code. * from all old Linux datagram code.
* Alan Cox : Uses the improved datagram code. * Alan Cox : Uses the improved datagram code.
* Alan Cox : Clean up for final release.
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -32,12 +31,12 @@ ...@@ -32,12 +31,12 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/in.h> #include <linux/in.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "ip.h" #include "ip.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -45,23 +44,18 @@ ...@@ -45,23 +44,18 @@
#include "udp.h" #include "udp.h"
#include "raw.h" #include "raw.h"
/*
* I'm sure there should be one of these, not one every file.
*/
static unsigned long min(unsigned long a, unsigned long b) static unsigned long
min(unsigned long a, unsigned long b)
{ {
if (a < b) if (a < b) return(a);
return(a);
return(b); return(b);
} }
/* /* This should be the easiest of all, all we do is copy it into a buffer. */
* This should be the easiest of all, all we do is copy it into a buffer. int
*/ packet_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
int packet_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
{ {
struct sock *sk; struct sock *sk;
...@@ -72,26 +66,22 @@ int packet_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -72,26 +66,22 @@ int packet_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
skb->sk = sk; skb->sk = sk;
/* Charge it too the socket. */ /* Charge it too the socket. */
if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) {
{
skb->sk = NULL; skb->sk = NULL;
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
return(0); return(0);
} }
sk->rmem_alloc += skb->mem_len; sk->rmem_alloc += skb->mem_len;
skb_queue_tail(&sk->rqueue,skb); skb_queue_tail(&sk->rqueue,skb);
wake_up(sk->sleep);
release_sock(sk); release_sock(sk);
sk->data_ready(sk,skb->len);
return(0); return(0);
} }
/* /* This will do terrible things if len + ipheader + devheader > dev->mtu */
* This will do terrible things if len + ipheader + devheader > dev->mtu static int
* Since only root can use these thats okish... packet_sendto(struct sock *sk, unsigned char *from, int len,
*/
static int packet_sendto(struct sock *sk, unsigned char *from, int len,
int noblock, unsigned flags, struct sockaddr_in *usin, int noblock, unsigned flags, struct sockaddr_in *usin,
int addr_len) int addr_len)
{ {
...@@ -101,69 +91,64 @@ static int packet_sendto(struct sock *sk, unsigned char *from, int len, ...@@ -101,69 +91,64 @@ static int packet_sendto(struct sock *sk, unsigned char *from, int len,
int err; int err;
/* Check the flags. */ /* Check the flags. */
if (flags) if (flags) return(-EINVAL);
return(-EINVAL); if (len < 0) return(-EINVAL);
if (len < 0)
return(-EINVAL);
/* Get and verify the address. */ /* Get and verify the address. */
if (usin) if (usin) {
{ if (addr_len < sizeof(saddr)) return(-EINVAL);
if (addr_len < sizeof(saddr))
return(-EINVAL);
err=verify_area(VERIFY_READ, usin, sizeof(saddr)); err=verify_area(VERIFY_READ, usin, sizeof(saddr));
if(err) if(err)
return err; return err;
memcpy_fromfs(&saddr, usin, sizeof(saddr)); memcpy_fromfs(&saddr, usin, sizeof(saddr));
} } else
else
return(-EINVAL); return(-EINVAL);
err=verify_area(VERIFY_READ,from,len); err=verify_area(VERIFY_READ,from,len);
if(err) if(err)
return(err); return(err);
/* Find the device first to size check it */ /* Find the device first to size check it */
saddr.sa_data[13] = 0; saddr.sa_data[13] = 0;
dev = dev_get(saddr.sa_data); dev = dev_get(saddr.sa_data);
if (dev == NULL) if (dev == NULL) {
{
return(-ENXIO); return(-ENXIO);
} }
if(len>dev->mtu) if(len>dev->mtu)
return -EMSGSIZE; return -EMSGSIZE;
/* Now allocate the buffer, knowing 4K pagelimits wont break this line */ /* Now allocate the buffer, knowing 4K pagelimits wont break this line */
skb = (struct sk_buff *) sk->prot->wmalloc(sk, len+sizeof(*skb), 0, GFP_KERNEL); skb = (struct sk_buff *) sk->prot->wmalloc(sk, len+sizeof(*skb), 0, GFP_KERNEL);
/* This shouldn't happen, but it could. */ /* This shouldn't happen, but it could. */
if (skb == NULL) if (skb == NULL) {
{
DPRINTF((DBG_PKT, "packet_sendto: write buffer full?\n")); DPRINTF((DBG_PKT, "packet_sendto: write buffer full?\n"));
return(-ENOMEM); return(-ENOMEM);
} }
/* Fill it in */ /* Fill it in */
skb->mem_addr = skb;
skb->mem_len = len + sizeof(*skb);
skb->sk = sk; skb->sk = sk;
skb->free = 1; skb->free = 1;
memcpy_fromfs (skb+1, from, len); memcpy_fromfs (skb+1, from, len);
skb->len = len; skb->len = len;
skb->next = NULL; skb->next = NULL;
if (dev->flags & IFF_UP) if (dev->flags & IFF_UP) dev->queue_xmit(skb, dev, sk->priority);
dev->queue_xmit(skb, dev, sk->priority); else kfree_skb(skb, FREE_WRITE);
else
kfree_skb(skb, FREE_WRITE);
return(len); return(len);
} }
static int packet_write(struct sock *sk, unsigned char *buff, static int
packet_write(struct sock *sk, unsigned char *buff,
int len, int noblock, unsigned flags) int len, int noblock, unsigned flags)
{ {
return(packet_sendto(sk, buff, len, noblock, flags, NULL, 0)); return(packet_sendto(sk, buff, len, noblock, flags, NULL, 0));
} }
static void packet_close(struct sock *sk, int timeout) static void
packet_close(struct sock *sk, int timeout)
{ {
sk->inuse = 1; sk->inuse = 1;
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
...@@ -174,13 +159,13 @@ static void packet_close(struct sock *sk, int timeout) ...@@ -174,13 +159,13 @@ static void packet_close(struct sock *sk, int timeout)
} }
static int packet_init(struct sock *sk) static int
packet_init(struct sock *sk)
{ {
struct packet_type *p; struct packet_type *p;
p = (struct packet_type *) kmalloc(sizeof(*p), GFP_KERNEL); p = (struct packet_type *) kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) if (p == NULL) return(-ENOMEM);
return(-ENOMEM);
p->func = packet_rcv; p->func = packet_rcv;
p->type = sk->num; p->type = sk->num;
...@@ -198,7 +183,8 @@ static int packet_init(struct sock *sk) ...@@ -198,7 +183,8 @@ static int packet_init(struct sock *sk)
* This should be easy, if there is something there * This should be easy, if there is something there
* we return it, otherwise we block. * we return it, otherwise we block.
*/ */
int packet_recvfrom(struct sock *sk, unsigned char *to, int len, int
packet_recvfrom(struct sock *sk, unsigned char *to, int len,
int noblock, unsigned flags, struct sockaddr_in *sin, int noblock, unsigned flags, struct sockaddr_in *sin,
int *addr_len) int *addr_len)
{ {
...@@ -208,15 +194,11 @@ int packet_recvfrom(struct sock *sk, unsigned char *to, int len, ...@@ -208,15 +194,11 @@ int packet_recvfrom(struct sock *sk, unsigned char *to, int len,
int err; int err;
saddr = (struct sockaddr *)sin; saddr = (struct sockaddr *)sin;
if (len == 0) if (len == 0) return(0);
return(0); if (len < 0) return(-EINVAL);
if (len < 0)
return(-EINVAL);
if (sk->shutdown & RCV_SHUTDOWN) if (sk->shutdown & RCV_SHUTDOWN) return(0);
return(0); if (addr_len) {
if (addr_len)
{
err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len)); err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
if(err) if(err)
return err; return err;
...@@ -234,8 +216,7 @@ int packet_recvfrom(struct sock *sk, unsigned char *to, int len, ...@@ -234,8 +216,7 @@ int packet_recvfrom(struct sock *sk, unsigned char *to, int len,
memcpy_tofs(to, skb+1, copied); /* Don't use skb_copy_datagram here: We can't get frag chains */ memcpy_tofs(to, skb+1, copied); /* Don't use skb_copy_datagram here: We can't get frag chains */
/* Copy the address. */ /* Copy the address. */
if (saddr) if (saddr) {
{
struct sockaddr addr; struct sockaddr addr;
addr.sa_family = skb->dev->type; addr.sa_family = skb->dev->type;
...@@ -251,15 +232,15 @@ int packet_recvfrom(struct sock *sk, unsigned char *to, int len, ...@@ -251,15 +232,15 @@ int packet_recvfrom(struct sock *sk, unsigned char *to, int len,
} }
int packet_read(struct sock *sk, unsigned char *buff, int
packet_read(struct sock *sk, unsigned char *buff,
int len, int noblock, unsigned flags) int len, int noblock, unsigned flags)
{ {
return(packet_recvfrom(sk, buff, len, noblock, flags, NULL, NULL)); return(packet_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
} }
struct proto packet_prot = struct proto packet_prot = {
{
sock_wmalloc, sock_wmalloc,
sock_rmalloc, sock_rmalloc,
sock_wfree, sock_wfree,
...@@ -283,8 +264,6 @@ struct proto packet_prot = ...@@ -283,8 +264,6 @@ struct proto packet_prot =
NULL, NULL,
packet_init, packet_init,
NULL, NULL,
NULL, /* No set/get socket options */
NULL,
128, 128,
0, 0,
{NULL,}, {NULL,},
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* PROC file system. It is mainly used for debugging and * PROC file system. It is mainly used for debugging and
* statistics. * statistics.
* *
* Version: @(#)proc.c 1.28 20/12/93 * Version: @(#)proc.c 1.0.5 05/27/93
* *
* Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
...@@ -18,7 +18,10 @@ ...@@ -18,7 +18,10 @@
* 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. * Alan Cox : Make /proc safer.
* Alan Cox : Final clean up. *
* To Do:
* Put the creating userid in the proc/net/... files. This will
* allow us to write an RFC931 daemon for Linux
* *
* 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
...@@ -34,13 +37,13 @@ ...@@ -34,13 +37,13 @@
#include <linux/in.h> #include <linux/in.h>
#include <linux/param.h> #include <linux/param.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "ip.h" #include "ip.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "udp.h" #include "udp.h"
#include "socket/skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include "raw.h" #include "raw.h"
/* /*
...@@ -50,7 +53,8 @@ ...@@ -50,7 +53,8 @@
* As in get_unix_netinfo, the buffer might be too small. If this * As in get_unix_netinfo, the buffer might be too small. If this
* happens, get__netinfo returns only part of the available infos. * happens, get__netinfo returns only part of the available infos.
*/ */
static int get__netinfo(struct proto *pro, char *buffer, int format) static int
get__netinfo(struct proto *pro, char *buffer, int format)
{ {
struct sock **s_array; struct sock **s_array;
struct sock *sp; struct sock *sp;
...@@ -67,12 +71,10 @@ static int get__netinfo(struct proto *pro, char *buffer, int format) ...@@ -67,12 +71,10 @@ static int get__netinfo(struct proto *pro, char *buffer, int format)
* (eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing * (eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing
* with timers we just concede defeat and cli(). * 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(); cli();
sp = s_array[i]; sp = s_array[i];
while(sp != NULL) while(sp != NULL) {
{
dest = sp->daddr; dest = sp->daddr;
src = sp->saddr; src = sp->saddr;
destp = sp->dummy_th.dest; destp = sp->dummy_th.dest;
...@@ -93,8 +95,7 @@ static int get__netinfo(struct proto *pro, char *buffer, int format) ...@@ -93,8 +95,7 @@ static int get__netinfo(struct proto *pro, char *buffer, int format)
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",
pro->name); pro->name);
return(strlen(buffer)); return(strlen(buffer));
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* INET protocol dispatch tables. * INET protocol dispatch tables.
* *
* Version: @(#)protocol.c 1.28 20/12/93 * Version: @(#)protocol.c 1.0.5 05/25/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
* Alan Cox : Ahah! udp icmp errors don't work because * Alan Cox : Ahah! udp icmp errors don't work because
* udp_err is never called! * udp_err is never called!
* Alan Cox : Added new fields for init and ready for * Alan Cox : Added new fields for init and ready for
* proper fragmentation (_NO_ 4K limits!). * proper fragmentation (_NO_ 4K limits!)
* Alan Cox : Final clean up.
* *
* 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
...@@ -31,18 +30,17 @@ ...@@ -31,18 +30,17 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/in.h> #include <linux/in.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "ip.h" #include "ip.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "socket/skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include "icmp.h" #include "icmp.h"
#include "udp.h" #include "udp.h"
static struct inet_protocol tcp_protocol = static struct inet_protocol tcp_protocol = {
{
tcp_rcv, /* TCP handler */ tcp_rcv, /* TCP handler */
NULL, /* No fragment handler (and won't be for a long time) */ NULL, /* No fragment handler (and won't be for a long time) */
tcp_err, /* TCP error control */ tcp_err, /* TCP error control */
...@@ -54,8 +52,7 @@ static struct inet_protocol tcp_protocol = ...@@ -54,8 +52,7 @@ static struct inet_protocol tcp_protocol =
}; };
static struct inet_protocol udp_protocol = static struct inet_protocol udp_protocol = {
{
udp_rcv, /* UDP handler */ udp_rcv, /* UDP handler */
NULL, /* Will be UDP fraglist handler */ NULL, /* Will be UDP fraglist handler */
udp_err, /* UDP error control */ udp_err, /* UDP error control */
...@@ -67,8 +64,7 @@ static struct inet_protocol udp_protocol = ...@@ -67,8 +64,7 @@ static struct inet_protocol udp_protocol =
}; };
static struct inet_protocol icmp_protocol = static struct inet_protocol icmp_protocol = {
{
icmp_rcv, /* ICMP handler */ icmp_rcv, /* ICMP handler */
NULL, /* ICMP never fragments anyway */ NULL, /* ICMP never fragments anyway */
NULL, /* ICMP error control */ NULL, /* ICMP error control */
...@@ -81,31 +77,29 @@ static struct inet_protocol icmp_protocol = ...@@ -81,31 +77,29 @@ static struct inet_protocol icmp_protocol =
struct inet_protocol *inet_protocol_base = &icmp_protocol; struct inet_protocol *inet_protocol_base = &icmp_protocol;
struct inet_protocol *inet_protos[MAX_INET_PROTOS] = {
struct inet_protocol *inet_protos[MAX_INET_PROTOS] =
{
NULL NULL
}; };
struct inet_protocol *inet_get_protocol(unsigned char prot) struct inet_protocol *
inet_get_protocol(unsigned char prot)
{ {
unsigned char hash; unsigned char hash;
struct inet_protocol *p; struct inet_protocol *p;
DPRINTF((DBG_PROTO, "get_protocol (%d)\n ", prot)); DPRINTF((DBG_PROTO, "get_protocol (%d)\n ", prot));
hash = prot & (MAX_INET_PROTOS - 1); hash = prot & (MAX_INET_PROTOS - 1);
for (p = inet_protos[hash] ; p != NULL; p=p->next) for (p = inet_protos[hash] ; p != NULL; p=p->next) {
{
DPRINTF((DBG_PROTO, "trying protocol %d\n", p->protocol)); DPRINTF((DBG_PROTO, "trying protocol %d\n", p->protocol));
if (p->protocol == prot) if (p->protocol == prot) return((struct inet_protocol *) p);
return((struct inet_protocol *) p);
} }
return(NULL); return(NULL);
} }
void inet_add_protocol(struct inet_protocol *prot) void
inet_add_protocol(struct inet_protocol *prot)
{ {
unsigned char hash; unsigned char hash;
struct inet_protocol *p2; struct inet_protocol *p2;
...@@ -117,10 +111,8 @@ void inet_add_protocol(struct inet_protocol *prot) ...@@ -117,10 +111,8 @@ void inet_add_protocol(struct inet_protocol *prot)
/* Set the copy bit if we need to. */ /* Set the copy bit if we need to. */
p2 = (struct inet_protocol *) prot->next; p2 = (struct inet_protocol *) prot->next;
while(p2 != NULL) while(p2 != NULL) {
{ if (p2->protocol == prot->protocol) {
if (p2->protocol == prot->protocol)
{
prot->copy = 1; prot->copy = 1;
break; break;
} }
...@@ -129,41 +121,37 @@ void inet_add_protocol(struct inet_protocol *prot) ...@@ -129,41 +121,37 @@ void inet_add_protocol(struct inet_protocol *prot)
} }
int inet_del_protocol(struct inet_protocol *prot) int
inet_del_protocol(struct inet_protocol *prot)
{ {
struct inet_protocol *p; struct inet_protocol *p;
struct inet_protocol *lp = NULL; struct inet_protocol *lp = NULL;
unsigned char hash; unsigned char hash;
hash = prot->protocol & (MAX_INET_PROTOS - 1); hash = prot->protocol & (MAX_INET_PROTOS - 1);
if (prot == inet_protos[hash]) if (prot == inet_protos[hash]) {
{
inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next; inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
return(0); return(0);
} }
p = (struct inet_protocol *) inet_protos[hash]; p = (struct inet_protocol *) inet_protos[hash];
while(p != NULL) while(p != NULL) {
{
/* /*
* We have to worry if the protocol being deleted is * We have to worry if the protocol being deleted is
* the last one on the list, then we may need to reset * the last one on the list, then we may need to reset
* someones copied bit. * someones copied bit.
*/ */
if (p->next != NULL && p->next == prot) if (p->next != NULL && p->next == prot) {
{
/* /*
* if we are the last one with this protocol and * if we are the last one with this protocol and
* there is a previous one, reset its copy bit. * there is a previous one, reset its copy bit.
*/ */
if (p->copy == 0 && lp != NULL) if (p->copy == 0 && lp != NULL) lp->copy = 0;
lp->copy = 0;
p->next = prot->next; p->next = prot->next;
return(0); return(0);
} }
if (p->next != NULL && p->next->protocol == prot->protocol) if (p->next != NULL && p->next->protocol == prot->protocol) {
{
lp = p; lp = p;
} }
......
This diff is collapsed.
...@@ -47,10 +47,10 @@ static struct rtable *rt_base = NULL; ...@@ -47,10 +47,10 @@ static struct rtable *rt_base = NULL;
static struct rtable *rt_loopback = NULL; static struct rtable *rt_loopback = NULL;
/* Dump the contents of a routing table entry. */ /* Dump the contents of a routing table entry. */
static void rt_print(struct rtable *rt) static void
rt_print(struct rtable *rt)
{ {
if (rt == NULL || inet_debug != DBG_RT) if (rt == NULL || inet_debug != DBG_RT) return;
return;
printk("RT: %06lx NXT=%06lx FLAGS=0x%02x\n", printk("RT: %06lx NXT=%06lx FLAGS=0x%02x\n",
(long) rt, (long) rt->rt_next, rt->rt_flags); (long) rt, (long) rt->rt_next, rt->rt_flags);
...@@ -162,8 +162,8 @@ static inline struct device * get_gw_dev(unsigned long gw) ...@@ -162,8 +162,8 @@ static inline struct device * get_gw_dev(unsigned long gw)
/* /*
* rewrote rt_add(), as the old one was weird. Linus * rewrote rt_add(), as the old one was weird. Linus
*/ */
void rt_add(short flags, unsigned long dst, unsigned long mask, void
unsigned long gw, struct device *dev) rt_add(short flags, unsigned long dst, unsigned long mask, unsigned long gw, struct device *dev)
{ {
struct rtable *r, *rt; struct rtable *r, *rt;
struct rtable **rp; struct rtable **rp;
...@@ -280,18 +280,21 @@ static int rt_new(struct rtentry *r) ...@@ -280,18 +280,21 @@ static int rt_new(struct rtentry *r)
} }
static int rt_kill(struct rtentry *r) static int
rt_kill(struct rtentry *r)
{ {
struct sockaddr_in *trg; struct sockaddr_in *trg;
trg = (struct sockaddr_in *) &r->rt_dst; trg = (struct sockaddr_in *) &r->rt_dst;
rt_del(trg->sin_addr.s_addr); rt_del(trg->sin_addr.s_addr);
return 0;
return(0);
} }
/* Called from the PROCfs module. */ /* Called from the PROCfs module. */
int rt_get_info(char *buffer) int
rt_get_info(char *buffer)
{ {
struct rtable *r; struct rtable *r;
char *pos; char *pos;
...@@ -308,7 +311,7 @@ int rt_get_info(char *buffer) ...@@ -308,7 +311,7 @@ int rt_get_info(char *buffer)
r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric, r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
r->rt_mask); r->rt_mask);
} }
return pos - buffer; return(pos - buffer);
} }
/* /*
...@@ -337,7 +340,8 @@ struct rtable * rt_route(unsigned long daddr, struct options *opt) ...@@ -337,7 +340,8 @@ struct rtable * rt_route(unsigned long daddr, struct options *opt)
} }
int rt_ioctl(unsigned int cmd, void *arg) int
rt_ioctl(unsigned int cmd, void *arg)
{ {
struct device *dev; struct device *dev;
struct rtentry rt; struct rtentry rt;
...@@ -349,17 +353,15 @@ int rt_ioctl(unsigned int cmd, void *arg) ...@@ -349,17 +353,15 @@ int rt_ioctl(unsigned int cmd, void *arg)
case DDIOCSDBG: case DDIOCSDBG:
ret = dbg_ioctl(arg, DBG_RT); ret = dbg_ioctl(arg, DBG_RT);
break; break;
case SIOCADDRT: case SIOCADDRT:
case SIOCDELRT: case SIOCDELRT:
if (!suser()) if (!suser()) return(-EPERM);
return -EPERM; err=verify_area(VERIFY_READ, arg, sizeof(struct rtentry));
err = verify_area(VERIFY_READ, arg, sizeof(struct rtentry));
if(err) if(err)
return err; return err;
memcpy_fromfs(&rt, arg, sizeof(struct rtentry)); memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
if (rt.rt_dev) { if (rt.rt_dev) {
err = verify_area(VERIFY_READ, rt.rt_dev, sizeof namebuf); err=verify_area(VERIFY_READ, rt.rt_dev, sizeof namebuf);
if(err) if(err)
return err; return err;
memcpy_fromfs(&namebuf, rt.rt_dev, sizeof namebuf); memcpy_fromfs(&namebuf, rt.rt_dev, sizeof namebuf);
...@@ -368,10 +370,9 @@ int rt_ioctl(unsigned int cmd, void *arg) ...@@ -368,10 +370,9 @@ int rt_ioctl(unsigned int cmd, void *arg)
} }
ret = (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt); ret = (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
return ret; return(ret);
} }
...@@ -303,9 +303,6 @@ struct sk_buff *skb_peek(struct sk_buff *volatile* list) ...@@ -303,9 +303,6 @@ struct sk_buff *skb_peek(struct sk_buff *volatile* list)
return *list; return *list;
} }
#ifdef UNUSED_NOW
/* /*
* Get a clone of an sk_buff. This is the safe way to peek at * Get a clone of an sk_buff. This is the safe way to peek at
* a socket queue without accidents. Its a bit long but most * a socket queue without accidents. Its a bit long but most
...@@ -372,8 +369,6 @@ struct sk_buff *skb_peek_copy(struct sk_buff *volatile* list) ...@@ -372,8 +369,6 @@ struct sk_buff *skb_peek_copy(struct sk_buff *volatile* list)
return(newsk); return(newsk);
} }
#endif
/* /*
* Free an sk_buff. This still knows about things it should * Free an sk_buff. This still knows about things it should
* not need to like protocols and sockets. * not need to like protocols and sockets.
...@@ -409,14 +404,12 @@ void kfree_skb(struct sk_buff *skb, int rw) ...@@ -409,14 +404,12 @@ void kfree_skb(struct sk_buff *skb, int rw)
else else
skb->sk->wmem_alloc-=skb->mem_len; skb->sk->wmem_alloc-=skb->mem_len;
if(!skb->sk->dead) if(!skb->sk->dead)
skb->sk->write_space(skb->sk); wake_up(skb->sk->sleep);
kfree_skbmem(skb->mem_addr,skb->mem_len); kfree_skbmem(skb->mem_addr,skb->mem_len);
} }
} }
else else
{
kfree_skbmem(skb->mem_addr, skb->mem_len); kfree_skbmem(skb->mem_addr, skb->mem_len);
}
} }
/* /*
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
* Alan Cox : Fraglist support (idea by Donald Becker) * Alan Cox : Fraglist support (idea by Donald Becker)
* Alan Cox : 'users' counter. Combines with datagram changes to avoid skb_peek_copy * Alan Cox : 'users' counter. Combines with datagram changes to avoid skb_peek_copy
* being used. * being used.
* Alan Cox : Extra fields for RAW fixes
* *
* 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
...@@ -29,7 +28,7 @@ ...@@ -29,7 +28,7 @@
#include <linux/malloc.h> #include <linux/malloc.h>
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
#include "ipx/ipx.h" #include "ipx.h"
#endif #endif
#define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALLOC_SKB /* For the drivers to know */
...@@ -39,8 +38,7 @@ ...@@ -39,8 +38,7 @@
#define FREE_WRITE 0 #define FREE_WRITE 0
struct sk_buff struct sk_buff {
{
unsigned long magic_debug_cookie; unsigned long magic_debug_cookie;
struct sk_buff *volatile next; struct sk_buff *volatile next;
struct sk_buff *volatile prev; struct sk_buff *volatile prev;
...@@ -50,8 +48,7 @@ struct sk_buff ...@@ -50,8 +48,7 @@ struct sk_buff
volatile unsigned long when; /* used to compute rtt's */ volatile unsigned long when; /* used to compute rtt's */
struct device *dev; struct device *dev;
void *mem_addr; void *mem_addr;
union union {
{
struct tcphdr *th; struct tcphdr *th;
struct ethhdr *eth; struct ethhdr *eth;
struct iphdr *iph; struct iphdr *iph;
...@@ -63,7 +60,6 @@ struct sk_buff ...@@ -63,7 +60,6 @@ struct sk_buff
ipx_packet *ipx; ipx_packet *ipx;
#endif #endif
} h; } h;
struct iphdr * ip_hdr;
unsigned long mem_len; unsigned long mem_len;
unsigned long len; unsigned long len;
unsigned long fraglen; unsigned long fraglen;
......
This diff is collapsed.
/*
* Definitions for the socket handler
*
* Version: @(#)sock.h 1.28 26/12/93
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
* Florian La Roche <flla@stud.uni-sb.de>
*
* Fixes:
* Alan Cox : Volatiles in skbuff pointers. See
* skbuff comments. May be overdone,
* better to prove they can be removed
* than the reverse.
* Alan Cox : Added a zapped field for tcp to note
* a socket is reset and must stay shut up
* Alan Cox : New fields for options
* Pauline Middelink : identd support
* Alan Cox : Split into sock.h and sockinet.h
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _SOCKINET_H
#define _SOCKINET_H
#ifndef _SOCK_H
#include "socket/sock.h"
#endif
#ifndef _PROTOCOL_H_
#include "protocol.h"
#endif
struct proto {
void *(*wmalloc)(struct sock *sk,
unsigned long size, int force,
int priority);
void *(*rmalloc)(struct sock *sk,
unsigned long size, int force,
int priority);
void (*wfree)(struct sock *sk, void *mem,
unsigned long size);
void (*rfree)(struct sock *sk, void *mem,
unsigned long size);
unsigned long (*rspace)(struct sock *sk);
unsigned long (*wspace)(struct sock *sk);
void (*close)(struct sock *sk, int timeout);
int (*read)(struct sock *sk, unsigned char *to,
int len, int nonblock, unsigned flags);
int (*write)(struct sock *sk, unsigned char *to,
int len, int nonblock, unsigned flags);
int (*sendto)(struct sock *sk,
unsigned char *from, int len, int noblock,
unsigned flags, struct sockaddr_in *usin,
int addr_len);
int (*recvfrom)(struct sock *sk,
unsigned char *from, int len, int noblock,
unsigned flags, struct sockaddr_in *usin,
int *addr_len);
int (*build_header)(struct sk_buff *skb,
unsigned long saddr,
unsigned long daddr,
struct device **dev, int type,
struct options *opt, int len,
int ttl, int tos);
int (*connect)(struct sock *sk,
struct sockaddr_in *usin, int addr_len);
struct sock *(*accept) (struct sock *sk, int flags);
void (*queue_xmit)(struct sock *sk,
struct device *dev, struct sk_buff *skb,
int free);
void (*retransmit)(struct sock *sk, int all);
void (*write_wakeup)(struct sock *sk);
void (*read_wakeup)(struct sock *sk);
int (*rcv)(struct sk_buff *buff, struct device *dev,
struct options *opt, unsigned long daddr,
unsigned short len, unsigned long saddr,
int redo, struct inet_protocol *protocol);
int (*select)(struct sock *sk, int which,
select_table *wait);
int (*ioctl)(struct sock *sk, int cmd,
unsigned long arg);
int (*init)(struct sock *sk);
void (*shutdown)(struct sock *sk, int how);
int (*setsockopt)(struct sock *sk, int level, int optname,
char *optval, int optlen);
int (*getsockopt)(struct sock *sk, int level, int optname,
char *optval, int *option);
unsigned short max_header;
unsigned long retransmits;
struct sock *sock_array[SOCK_ARRAY_SIZE];
char name[80];
};
extern void destroy_sock(struct sock *sk);
extern unsigned short get_new_socknum(struct proto *, unsigned short);
extern void put_sock(unsigned short, struct sock *);
extern void release_sock(struct sock *sk);
extern struct sock *get_sock(struct proto *, unsigned short,
unsigned long, unsigned short,
unsigned long);
/* declarations from timer.c */
extern struct sock *timer_base;
void delete_timer (struct sock *);
void reset_timer (struct sock *, int, unsigned long);
void net_timer (unsigned long);
#endif
This diff is collapsed.
...@@ -75,20 +75,16 @@ ...@@ -75,20 +75,16 @@
* normal compare so long as neither of the numbers is within * normal compare so long as neither of the numbers is within
* 4K of wrapping. Otherwise we must check for the wrap. * 4K of wrapping. Otherwise we must check for the wrap.
*/ */
static inline int before (unsigned long seq1, unsigned long seq2) static inline int
before (unsigned long seq1, unsigned long seq2)
{ {
/* this inequality is strict. */ /* this inequality is strict. */
if (seq1 == seq2) if (seq1 == seq2) return(0);
return(0);
if (seq1 < seq2) if (seq1 < seq2) {
{ if ((unsigned long)seq2-(unsigned long)seq1 < 65536UL) {
if ((unsigned long)seq2-(unsigned long)seq1 < 65536UL)
{
return(1); return(1);
} } else {
else
{
return(0); return(0);
} }
} }
...@@ -97,22 +93,23 @@ static inline int before (unsigned long seq1, unsigned long seq2) ...@@ -97,22 +93,23 @@ static inline int before (unsigned long seq1, unsigned long seq2)
* Now we know seq1 > seq2. So all we need to do is check * Now we know seq1 > seq2. So all we need to do is check
* to see if seq1 has wrapped. * to see if seq1 has wrapped.
*/ */
if (seq2 < 8192UL && seq1 > (0xffffffffUL - 8192UL)) if (seq2 < 8192UL && seq1 > (0xffffffffUL - 8192UL)) {
{
return(1); return(1);
} }
return(0); return(0);
} }
static inline int after(unsigned long seq1, unsigned long seq2) static inline int
after(unsigned long seq1, unsigned long seq2)
{ {
return(before(seq2, seq1)); return(before(seq2, seq1));
} }
/* is s2<=s1<=s3 ? */ /* is s2<=s1<=s3 ? */
static inline int between(unsigned long seq1, unsigned long seq2, unsigned long seq3) static inline int
between(unsigned long seq1, unsigned long seq2, unsigned long seq3)
{ {
return(after(seq1+1, seq2) && before(seq1, seq3+1)); return(after(seq1+1, seq2) && before(seq1, seq3+1));
} }
...@@ -124,7 +121,8 @@ static inline int between(unsigned long seq1, unsigned long seq2, unsigned long ...@@ -124,7 +121,8 @@ static inline int between(unsigned long seq1, unsigned long seq2, unsigned long
* convinced that this is the solution for the 'getpeername(2)' * convinced that this is the solution for the 'getpeername(2)'
* problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK * problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK
*/ */
static inline const int tcp_connected(const int state) static inline const int
tcp_connected(const int state)
{ {
return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT || return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT ||
state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 || state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 ||
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* TIMER - implementation of software timers. * TIMER - implementation of software timers.
* *
* Version: @(#)timer.c 1.28 22/12/93 * Version: @(#)timer.c 1.0.7 05/25/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
* of inet_bh() with this socket being handled it goes * of inet_bh() with this socket being handled it goes
* BOOM! Have to stop timer going off if inet_bh is * BOOM! Have to stop timer going off if inet_bh is
* active or the destroy causes crashes. * active or the destroy causes crashes.
* Alan Cox : Clean up for final release
* Alan Cox : Oops - timeouts destroyed permanent arp entries!
* *
* 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
...@@ -43,15 +41,16 @@ ...@@ -43,15 +41,16 @@
#include <asm/system.h> #include <asm/system.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "ip.h" #include "ip.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "skbuff.h" #include "skbuff.h"
#include "sockinet.h" #include "sock.h"
#include "arp.h" #include "arp.h"
void delete_timer (struct sock *t) void
delete_timer (struct sock *t)
{ {
unsigned long flags; unsigned long flags;
...@@ -64,12 +63,14 @@ void delete_timer (struct sock *t) ...@@ -64,12 +63,14 @@ void delete_timer (struct sock *t)
restore_flags (flags); restore_flags (flags);
} }
void reset_timer (struct sock *t, int timeout, unsigned long len) void
reset_timer (struct sock *t, int timeout, unsigned long len)
{ {
delete_timer (t); delete_timer (t);
if (timeout != -1) if (timeout != -1)
t->timeout = timeout; t->timeout = timeout;
#if 1 #if 1
/* FIXME: ??? */ /* FIXME: ??? */
if ((int) len < 0) /* prevent close to infinite timers. THEY _DO_ */ if ((int) len < 0) /* prevent close to infinite timers. THEY _DO_ */
...@@ -85,15 +86,14 @@ void reset_timer (struct sock *t, int timeout, unsigned long len) ...@@ -85,15 +86,14 @@ void reset_timer (struct sock *t, int timeout, unsigned long len)
* something, but we must be sure to process all of the * something, but we must be sure to process all of the
* sockets that need it. * sockets that need it.
*/ */
void
void net_timer (unsigned long data) net_timer (unsigned long data)
{ {
struct sock *sk = (struct sock*)data; struct sock *sk = (struct sock*)data;
int why = sk->timeout; int why = sk->timeout;
/* timeout is overwritten by 'delete_timer' and 'reset_timer' */ /* timeout is overwritten by 'delete_timer' and 'reset_timer' */
if (sk->inuse || in_inet_bh()) if (sk->inuse || in_inet_bh()) {
{
sk->timer.expires = 10; sk->timer.expires = 10;
add_timer(&sk->timer); add_timer(&sk->timer);
return; return;
...@@ -105,19 +105,16 @@ void net_timer (unsigned long data) ...@@ -105,19 +105,16 @@ void net_timer (unsigned long data)
reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN); reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
/* Always see if we need to send an ack. */ /* Always see if we need to send an ack. */
if (sk->ack_backlog) if (sk->ack_backlog) {
{
sk->prot->read_wakeup (sk); sk->prot->read_wakeup (sk);
if (! sk->dead) if (! sk->dead)
wake_up (sk->sleep); wake_up (sk->sleep);
} }
/* Now we need to figure out why the socket was on the timer. */ /* Now we need to figure out why the socket was on the timer. */
switch (why) switch (why) {
{
case TIME_DONE: case TIME_DONE:
if (! sk->dead || sk->state != TCP_CLOSE) if (! sk->dead || sk->state != TCP_CLOSE) {
{
printk ("non dead socket in time_done\n"); printk ("non dead socket in time_done\n");
release_sock (sk); release_sock (sk);
break; break;
...@@ -144,7 +141,7 @@ void net_timer (unsigned long data) ...@@ -144,7 +141,7 @@ void net_timer (unsigned long data)
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
delete_timer (sk); delete_timer (sk);
/* Kill the ARP entry in case the hardware has changed. */ /* Kill the ARP entry in case the hardware has changed. */
arp_destroy_maybe (sk->daddr); arp_destroy (sk->daddr);
if (!sk->dead) if (!sk->dead)
wake_up (sk->sleep); wake_up (sk->sleep);
sk->shutdown = SHUTDOWN_MASK; sk->shutdown = SHUTDOWN_MASK;
...@@ -155,11 +152,9 @@ void net_timer (unsigned long data) ...@@ -155,11 +152,9 @@ void net_timer (unsigned long data)
/* It could be we got here because we needed to send an ack. /* It could be we got here because we needed to send an ack.
* So we need to check for that. * So we need to check for that.
*/ */
if (sk->send_head) if (sk->send_head) {
{
if (jiffies < (sk->send_head->when + backoff (sk->backoff) if (jiffies < (sk->send_head->when + backoff (sk->backoff)
* (2 * sk->mdev + sk->rtt))) * (2 * sk->mdev + sk->rtt))) {
{
reset_timer (sk, TIME_WRITE, (sk->send_head->when reset_timer (sk, TIME_WRITE, (sk->send_head->when
+ backoff (sk->backoff) * (2 * sk->mdev + sk->rtt)) - jiffies); + backoff (sk->backoff) * (2 * sk->mdev + sk->rtt)) - jiffies);
release_sock (sk); release_sock (sk);
...@@ -170,24 +165,19 @@ void net_timer (unsigned long data) ...@@ -170,24 +165,19 @@ void net_timer (unsigned long data)
DPRINTF ((DBG_TMR, "retransmitting.\n")); DPRINTF ((DBG_TMR, "retransmitting.\n"));
sk->prot->retransmit (sk, 0); sk->prot->retransmit (sk, 0);
if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7)) if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
|| (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) {
{
DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 1\n")); DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 1\n"));
arp_destroy_maybe (sk->daddr); arp_destroy (sk->daddr);
ip_route_check (sk->daddr); ip_route_check (sk->daddr);
} }
if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) {
{
DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 2\n")); DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 2\n"));
sk->err = ETIMEDOUT; sk->err = ETIMEDOUT;
if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2
|| sk->state == TCP_LAST_ACK) || sk->state == TCP_LAST_ACK) {
{
sk->state = TCP_TIME_WAIT; sk->state = TCP_TIME_WAIT;
reset_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN); reset_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
} } else {
else
{
sk->prot->close (sk, 1); sk->prot->close (sk, 1);
break; break;
} }
...@@ -200,35 +190,29 @@ void net_timer (unsigned long data) ...@@ -200,35 +190,29 @@ void net_timer (unsigned long data)
if (sk->prot->write_wakeup) if (sk->prot->write_wakeup)
sk->prot->write_wakeup (sk); sk->prot->write_wakeup (sk);
sk->retransmits++; sk->retransmits++;
if (sk->shutdown == SHUTDOWN_MASK) if (sk->shutdown == SHUTDOWN_MASK) {
{
sk->prot->close (sk, 1); sk->prot->close (sk, 1);
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
} }
if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7)) if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
|| (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) {
{
DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 1\n")); DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 1\n"));
arp_destroy_maybe (sk->daddr); arp_destroy (sk->daddr);
ip_route_check (sk->daddr); ip_route_check (sk->daddr);
release_sock (sk); release_sock (sk);
break; break;
} }
if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) {
{
DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 2\n")); DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 2\n"));
arp_destroy_maybe (sk->daddr); arp_destroy (sk->daddr);
sk->err = ETIMEDOUT; sk->err = ETIMEDOUT;
if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2) if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2) {
{
sk->state = TCP_TIME_WAIT; sk->state = TCP_TIME_WAIT;
if (!sk->dead) if (!sk->dead)
wake_up (sk->sleep); wake_up (sk->sleep);
release_sock (sk); release_sock (sk);
} } else {
else
{
sk->prot->close (sk, 1); sk->prot->close (sk, 1);
} }
break; break;
......
This diff is collapsed.
...@@ -6,13 +6,12 @@ ...@@ -6,13 +6,12 @@
* Various kernel-resident INET utility functions; mainly * Various kernel-resident INET utility functions; mainly
* for format conversion and debugging output. * for format conversion and debugging output.
* *
* Version: @(#)utils.c 1.28 20/12/93 * Version: @(#)utils.c 1.0.7 05/18/93
* *
* Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* *
* Fixes: * Fixes:
* Alan Cox : verify_area check. * Alan Cox : verify_area check.
* Alan Cox : Clean up to match code style
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -33,7 +32,7 @@ ...@@ -33,7 +32,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <stdarg.h> #include <stdarg.h>
#include "inet.h" #include "inet.h"
#include "devinet.h" #include "dev.h"
#include "eth.h" #include "eth.h"
#include "ip.h" #include "ip.h"
#include "protocol.h" #include "protocol.h"
...@@ -42,10 +41,7 @@ ...@@ -42,10 +41,7 @@
#include "arp.h" #include "arp.h"
/* /* Display an IP address in readable format. */
* Display an IP address in readable format.
*/
char *in_ntoa(unsigned long in) char *in_ntoa(unsigned long in)
{ {
static char buff[18]; static char buff[18];
...@@ -58,50 +54,43 @@ char *in_ntoa(unsigned long in) ...@@ -58,50 +54,43 @@ char *in_ntoa(unsigned long in)
} }
/* /* Convert an ASCII string to binary IP. */
* Convert an ASCII string to binary IP. unsigned long
*/ in_aton(char *str)
unsigned long in_aton(char *str)
{ {
unsigned long l; unsigned long l;
unsigned int val; unsigned int val;
int i; int i;
l = 0; l = 0;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
{
l <<= 8; l <<= 8;
if (*str != '\0') if (*str != '\0') {
{
val = 0; val = 0;
while (*str != '\0' && *str != '.') while (*str != '\0' && *str != '.') {
{
val *= 10; val *= 10;
val += *str - '0'; val += *str - '0';
str++; str++;
} }
l |= val; l |= val;
if (*str != '\0') if (*str != '\0') str++;
str++;
} }
} }
return(htonl(l)); return(htonl(l));
} }
void dprintf(int level, char *fmt, ...) void
dprintf(int level, char *fmt, ...)
{ {
va_list args; va_list args;
char *buff; char *buff;
extern int vsprintf(char * buf, const char * fmt, va_list args); extern int vsprintf(char * buf, const char * fmt, va_list args);
if (level != inet_debug) if (level != inet_debug) return;
return;
buff = (char *) kmalloc(256, GFP_ATOMIC); buff = (char *) kmalloc(256, GFP_ATOMIC);
if (buff != NULL) if (buff != NULL) {
{
va_start(args, fmt); va_start(args, fmt);
vsprintf(buff, fmt, args); vsprintf(buff, fmt, args);
va_end(args); va_end(args);
...@@ -111,19 +100,18 @@ void dprintf(int level, char *fmt, ...) ...@@ -111,19 +100,18 @@ void dprintf(int level, char *fmt, ...)
} }
int dbg_ioctl(void *arg, int level) int
dbg_ioctl(void *arg, int level)
{ {
int val; int val;
int err; int err;
if (!suser()) if (!suser()) return(-EPERM);
return(-EPERM);
err=verify_area(VERIFY_READ, (void *)arg, sizeof(int)); err=verify_area(VERIFY_READ, (void *)arg, sizeof(int));
if(err) if(err)
return err; return err;
val = get_fs_long((int *)arg); val = get_fs_long((int *)arg);
switch(val) switch(val) {
{
case 0: /* OFF */ case 0: /* OFF */
inet_debug = DBG_OFF; inet_debug = DBG_OFF;
break; break;
......
#
# Makefile for the Linux socket support layer.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
CFLAGS := $(CFLAGS) -I../inet -I..
CPP := $(CPP) -I../inet -I..
.c.o:
$(CC) $(CFLAGS) -c -o $*.o $<
.s.o:
$(AS) -o $*.o $<
.c.s:
$(CC) $(CFLAGS) -S -o $*.s $<
OBJS = datagram.o dev.o skbuff.o sock.o
socket.o: $(OBJS)
$(LD) -r -o socket.o $(OBJS)
dep:
$(CPP) -M *.c > .depend
tar:
tar -cvf /dev/f1 .
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* the PROC file system and the "unix" family of networking * the PROC file system and the "unix" family of networking
* protocols. It is mainly used for debugging and statistics. * protocols. It is mainly used for debugging and statistics.
* *
* Version: @(#)proc.c 1.28 25/12/93 * Version: @(#)proc.c 1.0.4 05/23/93
* *
* Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
...@@ -16,14 +16,12 @@ ...@@ -16,14 +16,12 @@
* Fred Baumgarten, <dc6iq@insu1.etec.uni-kalrsruhe.de> * Fred Baumgarten, <dc6iq@insu1.etec.uni-kalrsruhe.de>
* *
* Fixes: * Fixes:
* Anonymous : Comment errors
* *
* 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
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#include <linux/autoconf.h> #include <linux/autoconf.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -35,10 +33,7 @@ ...@@ -35,10 +33,7 @@
#include "unix.h" #include "unix.h"
/* /* Called from PROCfs. */
* Called from PROCfs.
*/
int unix_get_info(char *buffer) int unix_get_info(char *buffer)
{ {
char *pos; char *pos;
...@@ -47,10 +42,8 @@ int unix_get_info(char *buffer) ...@@ -47,10 +42,8 @@ int unix_get_info(char *buffer)
pos = buffer; pos = buffer;
pos += sprintf(pos, "Num RefCount Protocol Flags Type St Path\n"); pos += sprintf(pos, "Num RefCount Protocol Flags Type St Path\n");
for(i = 0; i < NSOCKETS; i++) for(i = 0; i < NSOCKETS; i++) {
{ if (unix_datas[i].refcnt) {
if (unix_datas[i].refcnt)
{
pos += sprintf(pos, "%2d: %08X %08X %08lX %04X %02X", i, pos += sprintf(pos, "%2d: %08X %08X %08lX %04X %02X", i,
unix_datas[i].refcnt, unix_datas[i].refcnt,
unix_datas[i].protocol, unix_datas[i].protocol,
...@@ -60,13 +53,10 @@ int unix_get_info(char *buffer) ...@@ -60,13 +53,10 @@ int unix_get_info(char *buffer)
); );
/* If socket is bound to a filename, we'll print it. */ /* If socket is bound to a filename, we'll print it. */
if(unix_datas[i].sockaddr_len>0) if(unix_datas[i].sockaddr_len>0) {
{
pos += sprintf(pos, " %s\n", pos += sprintf(pos, " %s\n",
unix_datas[i].sockaddr_un.sun_path); unix_datas[i].sockaddr_un.sun_path);
} } else { /* just add a newline */
else
{ /* just add a newline */
*pos='\n'; *pos='\n';
pos++; pos++;
*pos='\0'; *pos='\0';
...@@ -77,9 +67,7 @@ int unix_get_info(char *buffer) ...@@ -77,9 +67,7 @@ int unix_get_info(char *buffer)
* Since sockets may have very very long paths, we make * Since sockets may have very very long paths, we make
* PATH_MAX+80 the minimum space left for a new line. * PATH_MAX+80 the minimum space left for a new line.
*/ */
if (pos > buffer+PAGE_SIZE-80-PATH_MAX) {
if (pos > buffer+PAGE_SIZE-80-PATH_MAX)
{
printk("UNIX: netinfo: oops, too many sockets.\n"); printk("UNIX: netinfo: oops, too many sockets.\n");
return(pos - buffer); return(pos - buffer);
} }
......
This diff is collapsed.
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