From: David van Moolenbroek Date: Tue, 14 Feb 2017 15:26:43 +0000 (+0000) Subject: Retire inet: the previous MINIX TCP/IP service X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=refs%2Fchanges%2F33%2F3433%2F1;p=minix.git Retire inet: the previous MINIX TCP/IP service This commit (temporarily) leaves MINIX 3 without a TCP/IP service. Thanks go out to Philip Homburg for providing this TCP/IP stack in the first place. It has served MINIX well for a long time. Change-Id: I0e3eb6fe64204081e4e3c2b9d6e6bd642f121973 --- diff --git a/distrib/sets/lists/minix-base/mi b/distrib/sets/lists/minix-base/mi index c87e3eb62..0d94a8b31 100644 --- a/distrib/sets/lists/minix-base/mi +++ b/distrib/sets/lists/minix-base/mi @@ -100,7 +100,7 @@ ./etc/gettytab minix-base ./etc/group minix-base ./etc/hostname.file minix-base -./etc/inet.conf minix-base +./etc/inet.conf minix-base obsolete ./etc/kyua minix-tests kyua ./etc/man.conf minix-base ./etc/master.passwd minix-base @@ -148,13 +148,13 @@ ./etc/rc.d/syslogd minix-base ./etc/rc.d/ttys minix-base ./etc/rc.d/wscons minix-base -./etc/rc.daemons.dist minix-base +./etc/rc.daemons.dist minix-base obsolete ./etc/rc.minix minix-base ./etc/rc.shutdown minix-base ./etc/rc.subr minix-base ./etc/release minix-base ./etc/resolv.conf minix-base -./etc/rs.inet minix-base +./etc/rs.inet minix-base obsolete ./etc/rs.single minix-base ./etc/saslc.d minix-base crypto ./etc/saslc.d/postfix minix-base crypto @@ -175,7 +175,7 @@ ./etc/system.conf minix-base ./etc/system.conf.d minix-base ./etc/system.conf.d/hello minix-base -./etc/system.conf.d/inet minix-base +./etc/system.conf.d/inet minix-base obsolete ./etc/system.conf.d/ipc minix-base ./etc/system.conf.d/lwip minix-base obsolete ./etc/system.conf.d/random minix-base @@ -231,7 +231,7 @@ ./service/ds minix-base ./service/ext2 minix-base ./service/hello minix-base -./service/inet minix-base +./service/inet minix-base obsolete ./service/input minix-base ./service/ipc minix-base ./service/is minix-base diff --git a/distrib/sets/lists/minix-comp/mi b/distrib/sets/lists/minix-comp/mi index 3c37fce67..cb3a3be9e 100644 --- a/distrib/sets/lists/minix-comp/mi +++ b/distrib/sets/lists/minix-comp/mi @@ -1231,7 +1231,7 @@ ./usr/include/minix/priv.h minix-comp ./usr/include/minix/procfs.h minix-comp ./usr/include/minix/profile.h minix-comp -./usr/include/minix/queryparam.h minix-comp +./usr/include/minix/queryparam.h minix-comp obsolete ./usr/include/minix/rmib.h minix-comp ./usr/include/minix/rs.h minix-comp ./usr/include/minix/safecopies.h minix-comp diff --git a/distrib/sets/lists/minix-debug/mi b/distrib/sets/lists/minix-debug/mi index 88f9dbd36..866978bf7 100644 --- a/distrib/sets/lists/minix-debug/mi +++ b/distrib/sets/lists/minix-debug/mi @@ -180,7 +180,7 @@ ./usr/libdata/debug/service/ds.debug minix-debug debug ./usr/libdata/debug/service/ext2.debug minix-debug debug ./usr/libdata/debug/service/hello.debug minix-debug debug -./usr/libdata/debug/service/inet.debug minix-debug debug +./usr/libdata/debug/service/inet.debug minix-debug debug,obsolete ./usr/libdata/debug/service/input.debug minix-debug debug ./usr/libdata/debug/service/ipc.debug minix-debug debug ./usr/libdata/debug/service/is.debug minix-debug debug diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 895353269..38fbc48f0 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -3253,17 +3253,17 @@ ./usr/man/man4/disk.4 minix-man ./usr/man/man4/dosfile.4 minix-man ./usr/man/man4/esdi.4 minix-man -./usr/man/man4/eth.4 minix-man +./usr/man/man4/eth.4 minix-man obsolete ./usr/man/man4/fd.4 minix-man -./usr/man/man4/ip.4 minix-man +./usr/man/man4/ip.4 minix-man obsolete ./usr/man/man4/keyboard.4 minix-man ./usr/man/man4/lp.4 minix-man ./usr/man/man4/mtio.4 minix-man ./usr/man/man4/ncr810.4 minix-man -./usr/man/man4/psip.4 minix-man +./usr/man/man4/psip.4 minix-man obsolete ./usr/man/man4/tape.4 minix-man ./usr/man/man4/tty.4 minix-man -./usr/man/man4/udp.4 minix-man +./usr/man/man4/udp.4 minix-man obsolete ./usr/man/man4/uds.4 minix-man obsolete ./usr/man/man5 minix-man ./usr/man/man5/TZ.5 minix-man @@ -3402,7 +3402,7 @@ ./usr/man/man8/i2cscan.8 minix-man ./usr/man/man8/ifconfig.8 minix-man ./usr/man/man8/in.httpd.8 minix-man obsolete -./usr/man/man8/inet.8 minix-man +./usr/man/man8/inet.8 minix-man obsolete ./usr/man/man8/init.8 minix-man ./usr/man/man8/installboot_nbsd.8 minix-man ./usr/man/man8/intr.8 minix-man diff --git a/etc/Makefile b/etc/Makefile index 5e27adde9..1adef736a 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -104,8 +104,8 @@ BIN1+= \ rc.shutdown services shells \ syslog.conf # MINIX-only files: -BIN1+= boot.cfg.default rc.daemons.dist rc.minix \ - rs.inet rs.single termcap utmp +BIN1+= boot.cfg.default rc.minix \ + rs.single termcap utmp .else BIN1+= bootptab changelist csh.cshrc csh.login \ csh.logout daily daily.conf dm.conf envsys.conf floppytab ftpchroot \ @@ -320,7 +320,6 @@ install-etc-files: .PHONY .MAKE check_DESTDIR MAKEDEV .for owner group mode sdir tdir files in \ ${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ group \ ${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ hostname.file \ - ${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ inet.conf \ ${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ mk.conf \ ${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ resolv.conf \ ${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ motd \ diff --git a/etc/rc.daemons.dist b/etc/rc.daemons.dist deleted file mode 100644 index 23e20d860..000000000 --- a/etc/rc.daemons.dist +++ /dev/null @@ -1,5 +0,0 @@ -daemonize talkd -daemonize tcpd shell /usr/libexec/rshd -daemonize tcpd telnet in.telnetd -daemonize tcpd ftp /usr/libexec/ftpd -daemonize tcpd finger /usr/libexec/fingerd diff --git a/etc/rs.inet b/etc/rs.inet deleted file mode 100755 index 7cadab4f2..000000000 --- a/etc/rs.inet +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -# Recovery script for INET. It restarts daemons dependent on it in order -# to recover TCP state. - -kill_by_name() -{ - label="$1" - pid=`ps ax | grep "$label" | grep -v grep | sed 's,[ ]*\([0-9]*\).*,\1,'` - if [ X"$pid" = X ] - then - return 1 # No such process - fi - echo "killing pid $pid for $label" - kill -9 $pid -} - -daemonize() -{ - # Function to start a daemon, if it exists. - local IFS=':' - local name="$1" - test "$1" = tcpd && name="$2" - - for dir in $PATH - do - if [ -f "$dir/$1" ] - then - - # check if this service is disabled at the boot monitor. - if disabled $name; then return; fi - - echo -n " $name" - "$@" & - return - fi - done -} - -disabled() -{ - ifs="$IFS"; IFS=, - for skip in `sysenv disable` - do - if [ "$skip" = "$1" ] - then - IFS="$ifs"; unset ifs - return 0 - fi - done - IFS="$ifs"; unset ifs - return 1 -} - -exec > /dev/console -echo "Arguments: $@" - -restarts=$(grep restarts /proc/service/$1 |cut -d: -f2) -restarts=$(( $restarts + 1 )) -minix-service down "$1" -kill_by_name dhcpd -kill_by_name nonamed -kill_by_name syslogd - -# Wait a moment to let daemons clean themselves up -sleep 3 -minix-service up /service/inet -script /etc/rs.inet -dev /dev/ip -restarts $restarts -daemonize dhcpd -daemonize nonamed -L -daemonize syslogd - -# Restart SSH daemon if installed and running -if [ -f /usr/pkg/etc/rc.d/sshd ] -then - /usr/pkg/etc/rc.d/sshd status | grep -v not > /dev/null - if [ $? -eq 0 ] - then - /usr/pkg/etc/rc.d/sshd restart - fi -fi diff --git a/etc/usr/rc b/etc/usr/rc index 529baa396..87ef1ecc6 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -105,11 +105,7 @@ up() } get_eth_labels() { - # Filter out the non-vlan ethernet entries from inet.conf. - # Produce as output a list of "drivername_instancenr"-formatted labels. - sed 's/\008/ /g' /etc/inet.conf | \ - sed -n 's/^ *eth[0-9][0-9]* *\([^ ][^ ]*\) *\([0-9][0-9]*\).*$/\1_\2/p' | \ - grep -v '^vlan_' + # Nothing yet. } # Detect expansion boards on the BeagleBone and load the proper drivers. @@ -155,8 +151,6 @@ capemgr() { done } -DAEMONS=/etc/rc.daemons - case $action in start) # Select console font. @@ -192,8 +186,6 @@ start) eval up $driver -label $label $arg -period 5HZ done - up inet -script /etc/rs.inet -dev /dev/ip - # pty needs to know the "tty" group ID up pty -dev /dev/ptmx -args "gid=`stat -f '%g' /dev/ptmx`" @@ -214,9 +206,6 @@ start) echo . - # Network initialization. - (: /dev/null && net=t # Is there a TCP/IP server? - echo -n "Starting daemons:" daemonize update @@ -355,37 +344,6 @@ start) echo . fi - if [ "$net" ] - then - if [ -f /etc/rc.net ] - then - # Let a customized TCP/IP initialization script figure it out. - . /etc/rc.net - else - # Standard network daemons. - echo -n "Starting networking:" - if grep -s 'psip0.*default' /etc/inet.conf >/dev/null - then ifconfig -h 10.0.0.1 - else - daemonize dhcpd - fi - daemonize nonamed -L - if [ -f "$DAEMONS" ] - then . "$DAEMONS" - fi - # The last daemon has been started, so close the list: - echo . - fi - fi - - if [ "$net" ] - then - # Get the nodename from the DNS and set it. - trap '' 2 - intr -t 20 hostaddr -h - trap 2 - fi - # Load the stored hostname into the sysctl database. test -r /etc/hostname.file && hostname $(cat /etc/hostname.file) diff --git a/minix/commands/DESCRIBE/DESCRIBE.sh b/minix/commands/DESCRIBE/DESCRIBE.sh index 09f56ecf5..472dc9517 100644 --- a/minix/commands/DESCRIBE/DESCRIBE.sh +++ b/minix/commands/DESCRIBE/DESCRIBE.sh @@ -130,35 +130,6 @@ do ;; 6,0) des="line printer, parallel port" dev=lp ;; - 7,*) - d=`expr $minor % 8` - n=`expr $minor / 8` - case $d in - 0) des="IP stat" dev=ipstat - ;; - 1) case $name in - psip*) - des="Pseudo IP #$n" dev=psip - ;; - *) des="raw ethernet #$n" dev=eth - esac - ;; - 2) des="raw IP #$n" dev=ip - ;; - 3) des="TCP/IP #$n" dev=tcp - ;; - 4) des="UDP #$n" dev=udp - esac - case $d in - [0123]) - if [ "$name" = "$dev" ] - then - des="$des (default)" - else - dev=$dev$n - fi - esac - ;; 9,0) des="unix98 pseudoterminal master" dev=ptmx ;; diff --git a/minix/commands/MAKEDEV/MAKEDEV.sh b/minix/commands/MAKEDEV/MAKEDEV.sh index 8c8a98b12..8279a4f46 100755 --- a/minix/commands/MAKEDEV/MAKEDEV.sh +++ b/minix/commands/MAKEDEV/MAKEDEV.sh @@ -30,7 +30,6 @@ RAMDISK_DEVICES=" ttyc1 ttyc2 ttyc3 tty00 tty01 tty02 tty03 " -#eth => ip tcp udp STD_DEVICES=" ${RAMDISK_DEVICES} bmp085b1s77 bmp085b2s77 bmp085b3s77 @@ -40,7 +39,7 @@ STD_DEVICES=" eepromb2s54 eepromb2s55 eepromb2s56 eepromb2s57 eepromb3s50 eepromb3s51 eepromb3s52 eepromb3s53 eepromb3s54 eepromb3s55 eepromb3s56 eepromb3s57 - eth fb0 fbd filter hello + fb0 fbd filter hello i2c-1 i2c-2 i2c-3 klog ptmx random sht21b1s40 sht21b2s40 sht21b3s40 @@ -128,7 +127,6 @@ Where key is one of the following: ttyc1 ... ttyc7 # Virtual consoles tty00 ... tty03 # Make serial lines ttyp0 ... ttyq0 ... # Make tty, pty pairs - eth ip tcp udp # One of these makes some TCP/IP devices audio mixer # Make audio devices klog # Make /dev/klog ptmx # Make /dev/ptmx @@ -277,20 +275,6 @@ do makedev eepromb${bus}s5${slave_low} b ${major} 0 ${uname} ${gname} ${permissions} ;; - eth|ip|tcp|udp|eth0|ip0|tcp0|udp0) - # TCP/IP devices. - makedev ipstat c 7 0 ${uname} ${gname} 666 - makedev eth0 c 7 1 ${uname} ${gname} ${permissions} - makedev ip0 c 7 2 ${uname} ${gname} ${permissions} - makedev tcp0 c 7 3 ${uname} ${gname} 666 - makedev udp0 c 7 4 ${uname} ${gname} 666 - - # Default interface - makedev eth c 7 1 ${uname} ${gname} ${permissions} - makedev ip c 7 2 ${uname} ${gname} ${permissions} - makedev tcp c 7 3 ${uname} ${gname} 666 - makedev udp c 7 4 ${uname} ${gname} 666 - ;; fb0) # Framebuffer driver makedev ${dev} c 19 0 ${uname} ${gname} 644 diff --git a/minix/fs/procfs/service.c b/minix/fs/procfs/service.c index bcc327bd4..e9efa1a00 100644 --- a/minix/fs/procfs/service.c +++ b/minix/fs/procfs/service.c @@ -125,7 +125,6 @@ service_get_policies(struct policies * pol, index_t slot) { .label = "ptyfs", .policy_str = "" }, { .label = "vbfs", .policy_str = "" }, /* net */ - { .label = "inet", .policy_str = "reset" }, { .label = "lwip", .policy_str = "" }, /* servers */ { .label = "devman", .policy_str = "restart" }, diff --git a/minix/include/minix/Makefile b/minix/include/minix/Makefile index 07e00bd18..72e3afa63 100644 --- a/minix/include/minix/Makefile +++ b/minix/include/minix/Makefile @@ -15,7 +15,7 @@ INCS+= acpi.h audio_fw.h bitmap.h \ inputdriver.h ipc.h ipc_filter.h ipcconst.h \ keymap.h log.h mmio.h mthread.h minlib.h \ netdriver.h optset.h padconf.h partition.h portio.h \ - priv.h procfs.h profile.h queryparam.h \ + priv.h procfs.h profile.h \ rmib.h rs.h safecopies.h sched.h sef.h sffs.h \ sockdriver.h sockevent.h sound.h spin.h \ sys_config.h sysctl.h sysinfo.h \ diff --git a/minix/include/minix/dmap.h b/minix/include/minix/dmap.h index c02731747..0bb46e49f 100644 --- a/minix/include/minix/dmap.h +++ b/minix/include/minix/dmap.h @@ -25,7 +25,7 @@ #define TTY_MAJOR 4 /* 4 = /dev/tty00 (ttys) */ #define CTTY_MAJOR 5 /* 5 = /dev/tty */ #define PRINTER_MAJOR 6 /* 6 = /dev/lp (printer driver) */ -#define INET_MAJOR 7 /* 7 = /dev/ip (inet) */ + /* 7 = (unused) */ /* 8 = /dev/c1 */ #define PTY_MAJOR 9 /* 9 = /dev/ptyp0 (pty driver) */ /* 10 = /dev/c2 */ diff --git a/minix/include/minix/queryparam.h b/minix/include/minix/queryparam.h deleted file mode 100644 index 4755d1245..000000000 --- a/minix/include/minix/queryparam.h +++ /dev/null @@ -1,42 +0,0 @@ -/* queryparam.h - query program parameters Author: Kees J. Bot - * 22 Apr 1994 - */ -#ifndef _MINIX__QUERYPARAM_H -#define _MINIX__QUERYPARAM_H - - -typedef size_t _mnx_size_t; - -struct export_param_list { - char *name; /* "variable", "[", ".field", or NULL. */ - void *offset; /* Address of a variable or field offset. */ - size_t size; /* Size of the resulting object. */ -}; - -struct export_params { - struct export_param_list *list; /* List of exported parameters. */ - struct export_params *next; /* Link several sets of parameters. */ -}; - -#ifdef __STDC__ -#define qp_stringize(var) #var -#define qp_dotstringize(var) "." #var -#else -#define qp_stringize(var) "var" -#define qp_dotstringize(var) ".var" -#endif -#define QP_VARIABLE(var) { qp_stringize(var), &(var), sizeof(var) } -#define QP_ARRAY(var) { "[", 0, sizeof((var)[0]) } -#define QP_VECTOR(var,ptr,len) { qp_stringize(var), &(ptr), -1 },\ - { "[", &(len), sizeof(*(ptr)) } -#define QP_FIELD(field, type) { qp_dotstringize(field), \ - (void *)offsetof(type, field), \ - sizeof(((type *)0)->field) } -#define QP_END() { 0, 0, 0 } - -void qp_export(struct export_params *_ex_params); -int queryparam(int (*_qgetc) (void), void **_paddress, _mnx_size_t - *_psize); -#endif /* _MINIX__QUERYPARAM_H */ - -/* $PchId: queryparam.h,v 1.1 2005/06/28 14:31:26 philip Exp $ */ diff --git a/minix/kernel/debug.h b/minix/kernel/debug.h index 446904102..cca571915 100644 --- a/minix/kernel/debug.h +++ b/minix/kernel/debug.h @@ -51,7 +51,7 @@ #define DEBUG_DUMPIPCF 0 /* If defined, restrict DEBUG_DUMPIPC to particular process names */ -/* #define DEBUG_DUMPIPC_NAMES { "tty", "inet" } */ +/* #define DEBUG_DUMPIPC_NAMES { "tty", "pty" } */ /* DEBUG_IPCSTATS collects information on who sends messages to whom. */ #define DEBUG_IPCSTATS 0 diff --git a/minix/man/man2/select.2 b/minix/man/man2/select.2 index 21f31db82..003ce33c8 100644 --- a/minix/man/man2/select.2 +++ b/minix/man/man2/select.2 @@ -27,7 +27,7 @@ up to and including file descriptor , for reading, writing, or exceptional conditions, respectively. .B Select currently supports regular files, pipes, named pipes, -inet, and tty file descriptors (including pty). +sockets, and character devices. If the .I readfds diff --git a/minix/man/man2/socket.2 b/minix/man/man2/socket.2 index ef65fd461..d3f3a5a8f 100644 --- a/minix/man/man2/socket.2 +++ b/minix/man/man2/socket.2 @@ -49,6 +49,4 @@ Could not allocate a file descriptor. .BR shutdown(2), .BR getsockopt(2), .BR setsockopt(2), -.BR ip(4), -.BR inet(8), .BR unix(8) diff --git a/minix/man/man4/Makefile b/minix/man/man4/Makefile index 27a3f12f0..7da35b1ae 100644 --- a/minix/man/man4/Makefile +++ b/minix/man/man4/Makefile @@ -1,4 +1,4 @@ -MAN= console.4 controller.4 dev.4 fd.4 ip.4 lp.4 mtio.4 tty.4 +MAN= console.4 controller.4 dev.4 fd.4 lp.4 mtio.4 tty.4 MLINKS += console.4 keyboard.4 MLINKS += controller.4 disk.4 @@ -9,8 +9,5 @@ MLINKS += controller.4 esdi.4 MLINKS += controller.4 aha1540.4 MLINKS += controller.4 ncr810.4 MLINKS += controller.4 dosfile.4 -MLINKS += ip.4 eth.4 -MLINKS += ip.4 psip.4 -MLINKS += ip.4 udp.4 .include diff --git a/minix/man/man4/dev.4 b/minix/man/man4/dev.4 index ff115f52f..6fad71f1d 100644 --- a/minix/man/man4/dev.4 +++ b/minix/man/man4/dev.4 @@ -179,9 +179,8 @@ The device sends any bytes written to it to the printer. .SS "TCP/IP (major 7)" The TCP/IP task is not a kernel task, but a server like PM and VFS. It sits -between VFS and the DP8390 task that manages the ethernet boards. Together -they implement the TCP/IP protocol. See also -.BR ip (4). +between VFS and the drivers that manage the ethernet boards. Together +they implement the TCP/IP protocol. .SS "Controller 1 (major 8)" Like controller 0 (major 3), but managing a second controller with devices .BR /dev/c1* . @@ -215,7 +214,6 @@ All MINIX 3 devices .BR console (4), .BR fd (4), .BR controller (4), -.BR ip (4), .BR uds (4), .BR tty (4), .BR MAKEDEV (8). @@ -223,8 +221,8 @@ All MINIX 3 devices There are five prominent errors that processes accessing device files may provoke: .IP "ENODEV \- No such device" 5 -There is no driver managing the device class this device belongs to. Either -the driver is configured out, or it is not loaded (inet). +There is no driver managing the device class this device belongs to, typically +because it is not loaded. .IP "ENXIO \- No such device or address" This device is not available. Either the driver does not support it at all, or the hardware isn't available, i.e. accessing the second disk on a system diff --git a/minix/man/man4/ip.4 b/minix/man/man4/ip.4 deleted file mode 100644 index 483971353..000000000 --- a/minix/man/man4/ip.4 +++ /dev/null @@ -1,1466 +0,0 @@ -.\" -.\" Copyright 1994 Vrije Universiteit, The Netherlands. -.\" For full copyright and restrictions on use see the file COPYRIGHT in the -.\" top level of the Amoeba distribution. -.\" -.ig - Software: Philip Homburg, 1991 - Document: Philip Homburg, Sept 3, 1991 - Modified: Greg Sharp and Philip Homburg, March 1992 - - merged with udp(L) and made a little more complete. - Greg Sharp, April 1992 - - updated keywords for auto index generation - Modified: Kees J. Bot, June 1994 - - changed to man(7) format for MINIX 3. -.. -.TH IP 4 -.SH NAME -ip, eth, psip, udp, tcp \- Internet Protocol server devices and definitions -.SH DESCRIPTION -.de SP -.if t .sp 0.4 -.if n .sp -.. -The -.BR ip* , -.BR eth* , -.BR psip* , -.BR tcp* , -and -.B udp* -devices give access to the Internet Protocol (IP) services in MINIX 3. -There can be up to 16 different networks, with 4 network devices each -(a network has either an -.B eth* -or a -.B psip* -device, not both.) -The -.B * -in the device names is a decimal number, so one may see names from -.B ip0 -to -.BR ip15 . -A program scanning all networks must try all 16, and not stop if one in -between is missing. One network is the default network. Its devices are -linked to names without numbers. -.PP -The -.B eth* -and -.B psip* -devices give direct access to the network packets at the lowest level. -The -.BR ip* , -.BR tcp* , -and -.B udp* -devices give access to IP, TCP, or UDP services. -.PP -Most programs that use TCP/IP use code like the following to access the -proper devices: -.PP -.RS -.nf -if ((tcp_device= getenv("TCP_DEVICE")) == NULL) - tcp_device= "/dev/tcp"; -.fi -.RE -.PP -The low level networking programs such as -.BR ifconfig (8) -also have options to select the device they are working with. The -convention is: -.PP -.RS -.BI ETH_DEVICE= device -.br -.BI -E " device" -.RS -Device to use as raw ethernet device instead of the default /dev/eth. -.RE -.SP -.BI PSIP_DEVICE= device -.br -.BI -P " device" -.RS -Pseudo IP device to use instead of -.BR /dev/psip . -.RE -.SP -.BI IP_DEVICE= device -.br -.BI -I " device" -.RS -IP device to use instead of -.BR /dev/ip . -.RE -.SP -.BI TCP_DEVICE= device -.br -.BI -T " device" -.RS -TCP device to use instead of -.BR /dev/tcp . -.RE -.SP -.BI UDP_DEVICE= device -.br -.BI -U " device" -.RS -UDP device to use instead of -.BR /dev/udp . -.RE -.RE -.SS Programming -Access to the IP services is provided using filedescriptors to open IP -devices. These open IP channels can be configured with -.BR ioctl (2) -calls, and data can be transferred by calls to -.BR read (2), -and -.BR write (2). -.SS "Types (general)" -.IP -.br -Defines -.BR u8_t , -.BR u16_t , -.B u32_t -and -.B i32_t -(and -.BR U8_t , -.BR U16_t , -.B U32_t -and -.B I32_t -for use in prototypes). -.SS "Types (eth)" -.IP -.br -Defines struct ether_addr (\fBether_addr_t\fP) and -.B ether_type_t -and -.B Ether_type_t -for use in prototypes. -.IP -.br -Defines struct nwio_ethopt (\fBnwio_ethopt_t\fP) and -struct nwio_ethstat (\fBnwio_ethstat_t\fP) -.IP -.br -Defines struct eth_hdr (\fBeth_hdr_t\fP) -.SS "Types (psip)" -.IP -.br -[[[No description available yet.]]] -.IP -.br -[[[No description available yet.]]] -.SS "Types (ip)" -.IP -.br -Defines -.BR ipaddr_t , -.BR ipproto_t -and struct ip_hdropt (\fBip_hdropt_t\fP). -.IP -.br -Defines struct nwio_ipconf (\fBnwio_ipconf_t\fP) and -struct nwio_ipopt (\fBnwio_ipopt_t\fP) -.IP -.br -Defines struct ip_hdr (\fBip_hdr_t\fP) -.IP -.br -Defines struct nwio_route (\fBnwio_route_t\fP) -.SS "Types (tcp)" -.IP -.br -Defines -.B tcpport_t -and -.B Tcpport_t -for use in prototypes. -.IP -.br -Defines struct nwio_tcpconf (\fBnwio_tcpconf_t\fP), -struct nwio_tcpcl (\fBnwio_tcpcl_t\fP), -struct nwio_tcpatt (\fBnwio_tcpatt_t\fP) and -struct nwio_tcpopt (\fBnwio_tcpopt_t\fP). -.IP -.br -Defines struct tcp_hdr (\fBtcp_hdr_t\fP) and struct tcp_hdropt -(\fBtcp_hdropt_t\fP). -.SS "Types (udp)" -.IP -.br -Defines -.B udpport_t -and -.B Udpport_t -for use in prototypes. -.IP -.br -Defines struct nwio_udpopt (\fBnwio_udpopt_t\fP). -.IP -.br -Defines struct udp_hdr (\fBudp_hdr_t\fP) and struct udp_io_hdr -(\fBudp_io_hdr_t\fP). -.SS "Byte Order Conversion" -All 16-bit and 32-bit quantities in IP headers must be in network byte -order. The macros described in -.BR hton (3) -can be used to convert these values to and from the byte order used by -the host machine. -.SS "The Internet Checksum" -The -.B oneC_sum -function (see -.BR oneC_sum (3)) -is used to calculate the one's complement checksum needed for IP network -packets. -.SS "General Functions" -.PP -.ft B -\fIfd\fP = open(\fItcpip_device\fP, O_RDWR) -.ft R -.PP -This is how one normally obtains a filedescriptor for a new TCP/IP channel. -.I tcpip_device -names one of the TCP/IP devices. The channel may be used both to send or to -receive data. -.PP -.ft B -\fIn\fP = read(\fIfd\fP, \fIbuf\fP, \fIsize\fP) -.ft R -.PP -Receives one packet (low level devices) or a number of bytes (TCP stream). -Returns the the number of bytes placed into -.IR buf , -or returns -1 with an error code placed into -.BR errno . -.PP -.ft B -\fIn\fP = write(\fIfd\fP, \fIbuf\fP, \fIsize\fP) -.ft R -.PP -Sends one packet (low level devices) or a number of bytes (TCP stream). -Returns -.I size -or -1 with the error code placed into -.BR errno . -The TCP/IP -.B read -and -.B write -functions behave like reads and writes on pipes when it comes to signals. -.SS "ETH Functions" -.PP -.ft B -ioctl(\fIfd\fP, NWIOGETHSTAT, &struct nwio_ethstat) -.ft R -.PP -The -.B NWIOGETHSTAT -ioctl -returns the Ethernet address and some statistics of the Ethernet server of -the channel -.IR fd . -The result is returned in the nwio_ethstat structure. -The \fBstruct nwio_ethstat\fP is defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_ethstat -{ - ether_addr_t nwes_addr; - eth_stat_t nwes_stat; -} nwio_ethstat_t; -.SP -typedef struct eth_stat -{ - unsigned long ets_recvErr, /* # receive errors */ - ets_sendErr, /* # send error */ - ets_OVW, /* # buffer overwrite warnings, - (packets arrive faster than - can be processed) */ - ets_CRCerr, /* # crc errors of read */ - ets_frameAll, /* # frames not aligned (# bits - not a multiple of 8) */ - ets_missedP, /* # packets missed due to too - slow packet processing */ - ets_packetR, /* # packets received */ - ets_packetT, /* # packets transmitted */ - ets_transDef, /* # transmission deferred (there - was a transmission of an - other station in progress */ - ets_collision, /* # collisions */ - ets_transAb, /* # transmissions aborted due - to excessive collisions */ - ets_carrSense, /* # carrier sense lost */ - ets_fifoUnder, /* # fifo underruns (processor - is too busy) */ - ets_fifoOver, /* # fifo overruns (processor is - too busy) */ - ets_CDheartbeat, /* # times unable to transmit - collision signal */ - ets_OWC; /* # times out of window - collision */ -} eth_stat_t; -.if t .ft R -.fi -.RE -.PP -.ft B -ioctl(\fIfd\fP, NWIOSETHOPT, &struct nwio_ethopt) -.ft R -.PP -Before an Ethernet channel can be used to send or receive -Ethernet packets, it has to be configured using the -.B NWIOSETHOPT -ioctl. -The structure -.B nwio_ethopt -is defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_ethopt -{ - u32_t nweo_flags; - ether_addr_t nweo_multi, nweo_rem; - ether_type_t nweo_type; -} nwio_ethopt_t; -.SP -#define NWEO_NOFLAGS 0x0000L -#define NWEO_ACC_MASK 0x0003L -# define NWEO_EXCL 0x00000001L -# define NWEO_SHARED 0x00000002L -# define NWEO_COPY 0x00000003L -#define NWEO_LOC_MASK 0x0010L -# define NWEO_EN_LOC 0x00000010L -# define NWEO_DI_LOC 0x00100000L -#define NWEO_BROAD_MASK 0x0020L -# define NWEO_EN_BROAD 0x00000020L -# define NWEO_DI_BROAD 0x00200000L -#define NWEO_MULTI_MASK 0x0040L -# define NWEO_EN_MULTI 0x00000040L -# define NWEO_DI_MULTI 0x00400000L -#define NWEO_PROMISC_MASK 0x0080L -# define NWEO_EN_PROMISC 0x00000080L -# define NWEO_DI_PROMISC 0x00800000L -#define NWEO_REM_MASK 0x0100L -# define NWEO_REMSPEC 0x00000100L -# define NWEO_REMANY 0x01000000L -#define NWEO_TYPE_MASK 0x0200L -# define NWEO_TYPESPEC 0x00000200L -# define NWEO_TYPEANY 0x02000000L -#define NWEO_RW_MASK 0x1000L -# define NWEO_RWDATONLY 0x00001000L -# define NWEO_RWDATALL 0x10000000L -.if t .ft R -.fi -.RE -.PP -The configuration is divided in a number of section (covered by the xx_MASK -macros). -Options can be set in the -.B nweo_flags -field. -The first section (\fBNWEO_ACC_MASK\fP) controls the access to a certain -Ethernet packet type. -If -.B NWEO_EXCL -is selected then this is the only channel that can send or -receive Ethernet packets of the selected type. -If -.B NWEO_SHARED -is selected then multiple channels (which all have to -select -.BR NWEO_SHARED ) -can use the same Ethernet type, they all can send -packets but incoming packets will be delivered to at most one of them. -If -.B NWEO_COPY -is selected then multiple channels have access to the same -Ethernet type and all receive a copy of an incoming packet. -.LP -The -.B NWEO_LOC_MASK -flags control the delivery of packets with a destination -address equal to the Ethernet address of the machine. -If -.B NWEO_EN_LOC -is selected then these packets will be delivered and with -.B NWEO_DI_LOC -they will be discarded. -.PP -.BR NWEO_BROAD_MASK , -.BR NWEO_MULTI_MASK , -and -.B NWEO_PROMISC_MASK -do the same to broadcast packets, -multicast packets and promiscuous mode packets as -.B NWEO_LOC_MASK -does for local packets. -Except that the precise multicast address is taken from the \fBnweo_multi\fP -field. -.LP -The -.B NWEO_REM_MASK -flags control whether communication is restricted to -single destination or not. -.B NWEO_REMSPEC -restricts sending and receiving of packets to the single -remote computer specified in the \fBnweo_rem\fP field. -.B NWEO_REMANY -allows sending to and receiving from any remote computer. -.PP -.B NWEO_TYPESPEC -restricts sending and receiving of packets to the type -specified in \fBnweo_type\fP. -The type has to be in network byte order (using -.BR hton (3)). -.B NWEO_TYPEANY -allows any type. -.PP -If the Ethernet header is completely specified by the -.B nweo_flags -i.e., all of -.BR NWEO_EN_LOC , -.BR NWEO_DI_BROAD , -.BR NWEO_DI_MULTI , -.BR NWEO_DI_PROMISC , -.BR NWEO_REMSPEC -and -.B NWEO_TYPESPEC -are -specified, then -.B NWEO_RWDATONLY -can be used to send and receive only the data part of an Ethernet packet. -If -.B NWEO_RWDATALL -is specified then both Ethernet header and data are used. -.SS "PSIP Functions" -.PP -[[[No description available yet.]]] -.SS "IP Functions" -.PP -.ft B -ioctl(\fIfd\fP, NWIOGIPCONF, &struct nwio_ipconf) -.ft R -.PP -The -.B NWIOGIPCONF -ioctl reports the Internet Address and the netmask. -For the \fInwio_ipconf\fP structure see the \fBNWIOSIPCONF\fP ioctl below. -.PP -.ft B -ioctl(\fIfd\fP, NWIOGIPOROUTE, &struct nwio_route) -.ft R -.PP -The -.B NWIOGIPOROUTE -ioctl can be used to query an IP server about its routing table. -[[[NWIODIPOROUTE, NWIOGIPIROUTE, NWIODIPIROUTE?]]] -The structure \fBnwio_route\fP is defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_route -{ - u32_t nwr_ent_no; - u32_t nwr_ent_count; - ipaddr_t nwr_dest; - ipaddr_t nwr_netmask; - ipaddr_t nwr_gateway; - u32_t nwr_dist; - u32_t nwr_flags; - u32_t nwr_pref; -} nwio_route_t; -.SP -#define NWRF_EMPTY 0 -#define NWRF_INUSE 1 -#define NWRF_FIXED 2 -.if t .ft R -.fi -.RE -.PP -The requested entry is taken from \fBnwr_ent_no\fP. -Entries are counted from 0, so the value 0 can be used for an initial query. -The size of the routing table is returned in \fBnwr_ent_count\fP. -The \fBnwr_flags\fP indicates if the entry is in use (\fBNWRF_INUSE\fP) and -if the entry was inserted manually (using \fBNWIOSIPOROUTE\fP) or generated -by the IP server itself. -The route is described by -.BR nwr_dest , -.BR nwr_netmask , -.BR nwr_gateway , -.BR nwr_dist , -and -.BR nwr_pref . -\fBNwr_dest\fP and \fBnwr_netmask\fP select the destination addresses. -A value of 0.0.0.0 (0x0) in both \fBnwr_dest\fP and \fBnwr_netmask\fP means -every host. -A value of 255.255.255.255 (0xffffffff) in \fBnwr_netmask\fP means a single -host. -Other values of \fBnwr_netmask\fP are netmasks for the network specified -by \fBnwr_dest\fP. -\fBNwr_gateway\fP is gateway that should be used. -\fBNwr_dist\fP is a minimal distance. -Packets with a time to live smaller than \fBnwr_dist\fP will not reach the -destination. -If two routes have equal netmask and distance fields but different -gateways then the gateway with highest value in \fBnwr_pref\fP is used. -.PP -.ft B -ioctl(\fIfd\fP, NWIOSIPCONF, &struct nwio_ipconf) -.ft R -.PP -The -.B NWIOSIPCONF -ioctl can be used to inform the IP server about its Internet Address -and/or its netmask. -Normally an IP server will discover its Internet Address using the RARP -protocol. -.B NWIOSIPCONF -can be used in the case that the RARP failed, or the netmask has to be changed. -Note that higher level protocols (TCP and UDP) assume that the Internet Address -of an IP device does not change, therefore TCP and UDP stop functioning if -the Internet Address is changed. -.PP -The structure \fBnwio_ipconf\fP is defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_ipconf -{ - u32_t nwic_flags; - ipaddr_t nwic_ipaddr; - ipaddr_t nwic_netmask; -} nwio_ipconf_t; -.SP -#define NWIC_NOFLAGS 0x0 -#define NWIC_FLAGS 0x3 -# define NWIC_IPADDR_SET 0x1 -# define NWIC_NETMASK_SET 0x2 -.if t .ft R -.fi -.RE -.PP -The function of \fBnwio_ipconf\fP depends on the value of \fBnwic_flags\fP. -If -.B NWIC_IPADDR_SET -is set then the Internet Address will be set to -\fBnwic_ipaddr\fP. -If -.B NWIC_NETMASK_SET -is set then the Internet Address will be set to -\fBnwic_netmask\fP. -.PP -.ft B -ioctl(\fIfd\fP, NWIOSIPOPT, &struct nwio_ipopt) -.ft R -.PP -Before an IP channel can be used, it has to be configured using the -.B NWIOSIPOPT -ioctl. -The structure \fBnwio_ipopt\fP is defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_ipopt -{ - u32_t nwio_flags; - ipaddr_t nwio_rem; - ip_hdropt_t nwio_hdropt; - u8_t nwio_tos; - u8_t nwio_ttl; - u8_t nwio_df; - ipproto_t nwio_proto; -} nwio_ipopt_t; -.SP -#define NWIO_NOFLAGS 0x0000L -#define NWIO_ACC_MASK 0x0003L -# define NWIO_EXCL 0x00000001L -# define NWIO_SHARED 0x00000002L -# define NWIO_COPY 0x00000003L -#define NWIO_LOC_MASK 0x0010L -# define NWIO_EN_LOC 0x00000010L -# define NWIO_DI_LOC 0x00100000L -#define NWIO_BROAD_MASK 0x0020L -# define NWIO_EN_BROAD 0x00000020L -# define NWIO_DI_BROAD 0x00200000L -#define NWIO_REM_MASK 0x0100L -# define NWIO_REMSPEC 0x00000100L -# define NWIO_REMANY 0x01000000L -#define NWIO_PROTO_MASK 0x0200L -# define NWIO_PROTOSPEC 0x00000200L -# define NWIO_PROTOANY 0x02000000L -#define NWIO_HDR_O_MASK 0x0400L -# define NWIO_HDR_O_SPEC 0x00000400L -# define NWIO_HDR_O_ANY 0x04000000L -#define NWIO_RW_MASK 0x1000L -# define NWIO_RWDATONLY 0x00001000L -# define NWIO_RWDATALL 0x10000000L -.if t .ft R -.fi -.RE -.PP -The options are divided in several categories: -.BR NWIO_ACC_MASK , -.BR NWIO_LOC_MASK , -.BR NWIO_BROAD_MASK , -.BR NWIO_REM_MASK , -.BR NWIO_PROTO_MASK , -.B NWIO_HDR_O_MASK -and -.BR NWIO_RW_MASK . -A channel is configured when one option of each category is set. -.PP -The options covered by -.B NWIO_ACC_MASK -control the number of channels that -can use one IP protocol. -If -.B NWIO_EXCL -is specified then only that channel can use a certain IP protocol. -If -.B NWIO_SHARED -then multiple channels that all have to specify -.B NWIO_SHARED -can use the same IP protocol, but incoming packets will -be delivered to a most one channel. -.B NWIO_COPY -does not impose any restrictions. -Every channel gets a copy of an incoming packet. -.PP -.B NWIO_LOC_MASK -and -.B NWIO_BROAD_MASK -control the delivery of packets. -If -.B NWIO_EN_LOC -is specified then packets that are explicitly send to -the IP server are delivered. -If -.B NWIO_EN_BROAD -is specified then broadcast packets are delivered. -Either one or both of them can be disabled with -.B NWIO_DI_LOC -and -.BR NWIO_DI_BROAD . -.PP -.B NWIO_REMSPEC -can be used to restrict communication to one remote host. -This host is taken from the \fBnwio_rem\fP field. -If any remote host is to be allowed then -.B NWIO_REMANY -can be used. -.PP -.B NWIO_PROTOSPEC -restricts communication to one IP protocol, specified -in \fBnwio_proto\fP. -.B NWIO_PROTOANY -allows any protocol to be sent or received. -.PP -.B NWIO_HDR_O_SPEC -specifies all IP header options in advance. -The values are taken from -.BR nwio_hdropt , -.BR nwio_tos , -.BR nwio_ttl , -and -.BR nwio_df . -\fBNwio_hdropt\fP specifies the IP options that should be present in an -outgoing packet. -\fBIp_hdropt_t\fP is defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct ip_hdropt -{ - u8_t iho_opt_siz; - u8_t iho_data[IP_MAX_HDR_SIZE-IP_MIN_HDR_SIZE]; -} ip_hdropt_t; -.if t .ft R -.fi -.RE -.PP -The bytes of size \fBiho_opt_siz\fP in \fBiho_data\fP are appended to the IP -header. -\fBNwio_tos\fP specifies the value of the ``type of service'' bits, -\fBnwio_ttl\fP gives the value of the ``time to live'' field and \fBnwio_df\fP -specifies whether fragmentation is disallowed or not. -.B NWIO_HDR_O_ANY -specifies that the header options should be specified at -each write request. -.PP -.B NWIO_RWDATONLY -specifies that the header should be omitted from a -write request. -This option can only be used when all header fields are specified in previous -options: -.BR NWIO_EN_LOC , -.BR NWIO_DI_BROAD , -.BR NWIO_REMSPEC , -.B NWIO_PROTOSPEC -and -.BR NWIO_HDR_O_SPEC . -A read operation will also only return the data part, so the IP options will -be lost. -.PP -.ft B -ioctl(\fIfd\fP, NWIOSIPOROUTE, &struct nwio_route) -.ft R -.PP -The -.B NWIOSIPOROUTE -ioctl adds a route to the routing table. -See \fBNWIOGIPOROUTE\fP above for a description of the \fBnwio_route\fP -structure. -The fields \fBnwr_ent_no\fP and \fBnwr_ent_count\fP are ignored. -.SS "TCP Functions" -.PP -.ft B -ioctl(\fIfd\fP, NWIOTCPCONN, &struct nwio_tcpcl) -.ft R -.PP -The -.B NWIOTCPCONN -ioctl tries to setup a connection with a remote TCP/IP server. -The channel must be fully configured (see -.BR NWIOSTCPCONF ) -and values for the local port, the remote port and the remote address have be -specified using -.B NWTC_LP_SET -or -.BR NWTC_LP_SEL , -.B NWTC_SET_RA -and -.BR NWTC_SET_RP . -The struct nwio_tcpcl is defined in as: -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_tcpcl -{ - long nwtcl_flags; - long nwtcl_ttl; -} nwio_tcpcl_t; -.if t .ft R -.fi -.RE -.PP -Set the -.B nwtcl_flags -field to zero before the connect or listen call. [[[Further explanation of -nwio_tcpcl?]]] -.PP -.ft B -ioctl(\fIfd\fP, NWIOGTCPCONF, &struct nwio_tcpconf) -.ft R -.PP -This call reports the current configuration of a TCP channel. -The -.B nwtc_flags -field shows the status of the -.BR access , -.BR locport , -.B remaddr -and -.B remport -fields. -.B Nwtc_locaddr -contains the Internet address of the TCP/IP server. -.B Remaddr -contains the Internet address of the remote TCP/IP server when set with -.B NWTC_SET_RA -or after a successful connect or listen (see -.B NWIOTCPCONN -or -.BR NWIOTCPLISTEN ). -.B Nwio_locport -contains the local TCP/IP port set with -.B NWTC_LP_SET -or the selected port set with -.BR NWTC_LP_SEL . -.B Nwtc_remport -contains the TCP port of the remote TCP/IP server as set with -.B NWIO_SET_RP -or after a successful connect or listen. -.PP -A value of 0 (zero) is reported for -.BR nwtc_remaddr , -.B nwtc_locport -or -.B nwtc_remport -when no value is set either explicitly or implicitly. -.PP -.ft B -ioctl(\fIfd\fP, NWIOTCPLISTEN, &struct nwio_tcpcl) -.ft R -.PP -The -.B NWIOTCPLISTEN -ioctl waits until a remote TCP/IP server tries to connect to this channel. -The channel has to be configured (see -.BR NWIOSTCPCONF ). -An additional restriction is that the local port -must be set (with -.BR NWTC_LP_SET ) -or selected (with -.BR NWTC_LP_SEL ). -When a remote address is set only connections for that host are accepted, and -when a remote port is set only connections from that port are accepted. -After a successful listen -.B NWIOGTCPCONF -can be used to find out what the address and port of the other side are. -.PP -.ft B -ioctl(\fIfd\fP, NWIOSTCPCONF, &struct nwio_tcpconf) -.ft R -.PP -Before a TCP channel can be used it must configured using the -.B NWIOSTCPCONF -ioctl. -The parameters to -.B NWIOSTCPCONF -are the channel file descriptor and a -.B struct nwio_tcpconf -as defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_tcpconf -{ - u32_t nwtc_flags; - ipaddr_t nwtc_locaddr; - ipaddr_t nwtc_remaddr; - tcpport_t nwtc_locport; - tcpport_t nwtc_remport; -} nwio_tcpconf_t; -.SP -#define NWTC_NOFLAGS 0x0000L -#define NWTC_ACC_MASK 0x0003L -# define NWTC_EXCL 0x00000001L -# define NWTC_SHARED 0x00000002L -# define NWTC_COPY 0x00000003L -#define NWTC_LOCPORT_MASK 0x0030L -# define NWTC_LP_UNSET 0x00000010L -# define NWTC_LP_SET 0x00000020L -# define NWTC_LP_SEL 0x00000030L -#define NWTC_REMADDR_MASK 0x0100L -# define NWTC_SET_RA 0x00000100L -# define NWTC_UNSET_RA 0x01000000L -#define NWTC_REMPORT_MASK 0x0200L -# define NWTC_SET_RP 0x00000200L -# define NWTC_UNSET_RP 0x02000000L -.if t .ft R -.fi -.RE -.PP -A tcp channel is considered configured when one flag in each category has -been selected. -Thus one of -.BR NWTC_EXCL , -.B NWTC_SHARED -or -.BR NWTC_COPY , -one of -.BR NWTC_LP_UNSET , -.B NWTC_LP_SET -or -.BR NWTC_LP_SEL , -one of -.B NWTC_SET_RA -or -.BR NWTC_UNSET_RA , -and one of -.B NWTC_SET_RP -or -.BR NWTC_UNSET_RP . -.PP -The acc flags control the access to a certain TCP port. -.B NWTC_EXCL -means exclusive access. -An attempt to configure a channel will be denied if the same port is specified -as that of a channel that requested exclusive access. -.B NWTC_SHARED -indicates that several channels use the same port but cooperate. -If the shared mode is specified for one channel than all other channel that -use the same port should also be configured with the -.B NWTC_SHARED -flag. -.B NWTC_COPY -is specified when the programmer does not care about other channels. -This is the default. -.PP -The locport flags control which TCP port is used for communication. -.B NWTC_LP_UNSET -indicates the absence of a local port. -This is the default. -.B NWTC_LP_SET -means that the -.B nwtc_locport -field contains the local port to be used by TCP. -This value must be in network byte order (see -.BR hton (3).) -.B NWTC_LP_SEL -requests the TCP server to pick a port. -This port will be in the range from 32768 to 65535 and will be unique. -.LP -The -.B remaddr -flags specify which hosts are acceptable for connections. -.B NWTC_SET_RA -indicates that only connection to the host specified in -.B nwtc_remaddr -are acceptable. -.B Nwtc_remaddr -should be in network byte order (see -.BR hton (3).) -.B NWTC_UNSET_RA -allows every host on the other side of a connection. -This is the default. -.PP -The -.B remport -flags specify which remote ports are acceptable for connections. -.B NWTC_SET_RP -indicates that only the port specified in -.B nwtc_remport -is acceptable. -.B NWTC_UNSET_RP -allows every port on the other side of a connection. -This is the default. -.PP -.ft B -ioctl(\fIfd\fP, NWIOTCPSHUTDOWN) -.ft R -.PP -The -.B NWIOTCPSHUTDOWN -tells the TCP/IP server that no more data will be sent over the channel -specified by -.IR fd . -This command can be issued when the channel is connected to a remote TCP/IP -server. -The TCP/IP server will tell the remote TCP/IP server and the client of the -remote TCP/IP server will receive an end-of-file indication. -.PP -.ft B -ioctl(\fIfd\fP, NWIOGTCPOPT, &struct nwio_tcpopt) -.br -ioctl(\fIfd\fP, NWIOSTCPOPT, &struct nwio_tcpopt) -.ft R -.PP -The behaviour of a TCP channel may be changed by setting a number of -options. The TCP options can be obtained with the -.B NWIOGTCPOPT -ioctl and set with the -.B NWIOSTCPOPT -ioctl. The options are passed in a -.B struct nwio_tcpopt -as defined in : -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_tcpopt -{ - u32_t nwto_flags; -} nwio_tcpopt_t; -.SP -#define NWTO_NOFLAG 0x0000L -#define NWTO_SND_URG_MASK 0x0001L -# define NWTO_SND_URG 0x00000001L -# define NWTO_SND_NOTURG 0x00010000L -#define NWTO_RCV_URG_MASK 0x0002L -# define NWTO_RCV_URG 0x00000002L -# define NWTO_RCV_NOTURG 0x00020000L -#define NWTO_BSD_URG_MASK 0x0004L -# define NWTO_BSD_URG 0x00000004L -#define NWTO_DEL_RST_MASK 0x0008L -# define NWTO_DEL_RST 0x00000008L -.if t .ft R -.fi -.RE -.PP -The -.B NWTO_SND_URG -option causes bytes written to the channel to be send out as urgent data. -On receiving an -.B EURG -error the -.B NWTO_RCV_URG -option must be set to switch over to reading urgent data. When all urgent -data has been read an -.B ENOURG -error will follow, -indicating that the option must be cleared with -.BR NWTO_RCV_NOTURG . -Alas the BSD implementation of urgent data disagrees with the RFC's, so to -be BSD compatible one must set the -.B NWTO_BSD_URG -option beforehand on a channel that is to send or receive urgent data. -Given that the BSD implementation is the regarded as the TCP/IP standard one -should always use the BSD style. The -.B NWTO_DEL_RST -option delays a failure response on a connect to the same port as the -current open connection. Without this option a connect would fail if -a server is not yet listening. With this option a connect will linger -on until the server starts listening. This option is useful for a server -that opens a connection, tells the remote end the local port number and -then listens (FTP), or for a program that forks off servers for incoming -connections (TELNET). A new connection may come in before a new listen -can be started, so it is nice if the new connect doesn't fail. Use this -option only when it is clearly needed. -.SS "UDP Functions" -.PP -.ft B -ioctl(\fIfd\fP, NWIOGUDPOPT, &struct nwio_udpopt) -.ft R -.PP -The -.B NWIOGUDPOPT -ioctl returns the current options that result from the default options -and the options set with -.BR NWIOSUDPOPT . -When -.B NWUO_LP_SEL -or -.B NWUO_LP_SET -is selected the local port is returned in -.BR nwuo_locport . -When -.B NWUO_RP_SET -is selected the remote port is returned in -.BR nwuo_remport . -The local address is always returned in -.BR nwuo_locaddr , -and when -.B NWUO_RA_SET -is selected the remote address is returned in -.BR nwuo_remaddr . -.PP -.ft B -ioctl(\fIfd\fP, NWIOSUDPOPT, &struct nwio_udpopt) -.ft R -.PP -A UDP channel must be configured using the -.B NWIOSUDPOPT -ioctl before any data can be read or written. -.B NWIOSUDPOPT -takes two parameters, a file descriptor to an open UDP device and -pointer to a -.B nwio_udpopt -structure that describes the requested configuration. -The -.B nwio_udpopt -structure is defined in as: -.PP -.RS -.nf -.if t .ft C -typedef struct nwio_udpopt -{ - unsigned long nwuo_flags; - udpport_t nwuo_locport; - udpport_t nwuo_remport; - ipaddr_t nwuo_locaddr; - ipaddr_t nwuo_remaddr; -} nwio_udpopt_t; -.SP -#define NWUO_NOFLAGS 0x0000L -#define NWUO_ACC_MASK 0x0003L -#define NWUO_EXCL 0x00000001L -#define NWUO_SHARED 0x00000002L -#define NWUO_COPY 0x00000003L -#define NWUO_LOCPORT_MASK 0x000CL -#define NWUO_LP_SEL 0x00000004L -#define NWUO_LP_SET 0x00000008L -#define NWUO_LP_ANY 0x0000000CL -#define NWUO_LOCADDR_MASK 0x0010L -#define NWUO_EN_LOC 0x00000010L -#define NWUO_DI_LOC 0x00100000L -#define NWUO_BROAD_MASK 0x0020L -#define NWUO_EN_BROAD 0x00000020L -#define NWUO_DI_BROAD 0x00200000L -#define NWUO_REMPORT_MASK 0x0100L -#define NWUO_RP_SET 0x00000100L -#define NWUO_RP_ANY 0x01000000L -#define NWUO_REMADDR_MASK 0x0200L -#define NWUO_RA_SET 0x00000200L -#define NWUO_RA_ANY 0x02000000L -#define NWUO_RW_MASK 0x1000L -#define NWUO_RWDATONLY 0x00001000L -#define NWUO_RWDATALL 0x10000000L -#define NWUO_IPOPT_MASK 0x2000L -#define NWUO_EN_IPOPT 0x00002000L -#define NWUO_DI_IPOPT 0x20000000L -.if t .ft R -.fi -.RE -.PP -A UDP channel is considered configured when one flag in each category has been -selected. -Thus one of -.BR NWUO_EXCL , -.B NWUO_SHARED -or -.BR NWUO_COPY , -one of -.BR NWUO_LP_SEL , -.B NWUO_LP_SET -or -.BR NWUO_LP_ANY , -one of -.B NWUO_EN_LOC -or -.BR NWUO_DI_LOC , -one of -.BR NWUO_EN_BROAD , -or -.BR NWUO_DI_BROAD , -one of -.BR NWUO_RP_SET , -or -.BR NWUO_RP_ANY , -one of -.BR NWUO_RA_SET , -or -.BR NWUO_RA_ANY , -one of -.BR NWUO_RWDATONLY , -or -.BR NWUO_RWDATALL , -and one of -.BR NWUO_EN_IPOPT , -or -.BR NWUO_DI_IPOPT . -The acc flags control the access to a certain UDP port. -.B NWUO_EXCL -means exclusive access: -no other channel can use this port. -.B NWUO_SHARED -means shared access: -only channels that specify shared access can use this port -and all packets that are received are handed to at most one channel. -.B NWUO_COPY -imposes no access restriction and all channels get a copy of every received -packet for that port. -.PP -The -.B locport -flags control the selection of the UDP port for this channel. -.B NWUO_LP_SEL -requests the server to pick a port. -This port will be in the range from 32768 to 65535 and it will be unique. -.B NWUO_LP_SET -sets the local port to the value of the -.B nwuo_locport -field. -.B NWUO_LP_ANY -does not select a port. -Reception of data is therefore not possible but it is -possible to send data. -.PP -The -.B locaddr -flags control the reception of packets. -.B NWUO_EN_LOC -enables the reception of packets with the local IP address as destination. -.B NWUO_DI_LOC -disables the reception of packet for the local IP address. -.PP -The -.B broad -flags control the reception of broadcast packets. -.B NWUO_EN_BROAD -enables the reception of broadcast packets and -.B NWUO_DI_BROAD -disables the reception of broadcast packets. -.PP -The -.B remport -flags let the client to specify one specific remote UDP port or -to allow any remote port. -.B NWUO_RP_SET -sets the remote UDP port to the value of -.BR nwuo_remport . -Only packets with a matching remote port will be delivered -and all packets will be sent to that port. -.B NWUO_RP_ANY -allows reception of packets form any port and when transmitting packets the -remote port has to be specified. -.PP -The -.B remaddr -flags control the remote IP address. -.B NWUO_RA_SET -sets the remote IP address the value of -.BR nwuo_remaddr . -Only packets from that address will be delivered and all packets will be sent -to that address. -.B NWUO_RA_ANY -allows reception of packets from any host and when transmitting packets the -remote host has to be specified. -.PP -The -.B rw -flags control the format of the data to be sent or received. -With -.B NWUO_RWDATONLY -only the data part of a UDP packet is sent to the server and only the data -part is received from the server. -The -.B NWUO_RWDATALL -mode presents the data part of a UDP packet with a header that contains -the source and destination IP address, source and destination UDP ports, -the IP options, etc. -The server expects such a header in front of the data to be transmitted. -.ig \" Some for Philip to explain properly: -The header is defined in and looks like this: -.PP -.RS -.nf -.if t .ft C -typedef struct udp_io_hdr -{ - ipaddr_t uih_src_addr; - ipaddr_t uih_dst_addr; - udpport_t uih_src_port; - udpport_t uih_dst_port; - u16_t uih_ip_opt_len; - u16_t uih_data_len; -} udp_io_hdr_t; -.if t .ft R -.fi -.RE -.PP -The first four fields are the source and destination IP addresses and -ports. -.B Uih_ip_opt_len -is ???. -.B Uih_data_len -should equal the length of the packet data (packet lenght minus the -header.) ??? -.. -.PP -The -.B ipopt -flags control the delivery and transmission of IP options. -When -.B NWUO_EN_IPOPT -is set IP, options will be delivered and sent. -When -.B NWUO_DI_IPOPT -is set IP option will be stripped from received packets and no IP options will -be sent. -.ig \" MINIX 3 doesn't have this stuff (yet? ever?) -.SS "UDP Library Functions" -.PP -The following routines provide an somewhat easier to use interface to UDP than -the routines described above (\fBtcpip_open\fP, \fBudp_ioc_setopt\fP, -\fBtcpip_read\fP and \fBtcpip_write\fP). -.LP -.sC -errstat -udp_connect(udp_cap, chan_cap, srcport, dstport, dstaddr, flags) -capability *udp_cap; -capability *chan_cap; -udpport_t srcport; -udpport_t dstport; -ipaddr_t dstaddr; -int flags; -.eC -.kW "\fIudp_connect\fP" -\fIUdp_connect\fP combines the functionality of \fItcpip_open\fP and -\fIudp_ioc_setopt\fP. -A pointer to a UDP server capability should be passed in \fIudp_cap\fP, and -the channel capability will be returned in the capability pointed to by -\fIchan_cap\fP. -If \fIsrcport\fP is 0 then an unused port will be selected, otherwise the local -port will be set to \fIsrcport\fP. -If \fIdstport\fP is non-zero then communication will be restricted to remote ports -that equal to \fIdstport\fP, otherwise any data can be sent to or received from -any remote port. -The same thing applies to \fIdstaddr\fP; if \fIdstaddr\fP is non-zero then -only \fIdstaddr\fP can be reached. -Currently no flags are defined so \fIflags\fP should be 0. -.sH -udp_reconnect -.LP -.sC -errstat -udp_reconnect(chan_cap, srcport, dstport, dstaddr, flags) -capability *chan_cap; -udpport_t srcport; -udpport_t dstport; -ipaddr_t dstaddr; -int flags; -.eC -.kW "\fIudp_reconnect\fP" -\fIUdp_reconnect\fP is the same as \fIudp_connect\fP except that an existing -channel capability is (re)used. -.sH -udp_read_msg -.LP -.sC -errstat -udp_read_msg(chan_cap, msg, msglen, actlen, flags) -capability *chan_cap; -char *msg; -int msglen; -int *actlen; -int flags; -.eC -.kW "\fIudp_read_msg\fP" -\fIUdp_read_msg\fP delivers a UDP packet. -The data part of the UDP packet is -prepended with an \fIudp_io_hdr\fP. -The actual length of the possibly truncated packet is returned in \fIactlen\fP. -No flags are defined so \fIflags\fP should be 0. -.sH -udp_write_msg -.LP -.sC -errstat -udp_write_msg(chan_cap, msg, msglen, flags) -capability *chan_cap; -char *msg; -int msglen; -int flags; -.eC -.kW "\fIudp_write_msg\fP" -A UDP packet can be sent with \fIudp_write_msg\fP. -\fIMsg\fP should point to a \fIudp_io_hdr\fP followed by the data part of the -UDP packet. -The \fIuih_dst_addr\fP and \fIuih_dst_port\fP fields of the \fIudp_io_hdr\fP -should be filled in if no values are specified in the \fIudp_connect\fP, -or \fIudp_reconnect\fP. -.sH -udp_close -.LP -.sC -errstat -udp_close(chan_cap, flags) -capability *chan_cap; -int flags; -.eC -.kW "\fIudp_close\fP" -\fIUdp_close\fP cleans up the administration kept by the UDP library but does -not destroy the capability. -The function should be used if the capability is passed to another process -and should continue to exist. -No flags are defined so \fIflags\fP should be 0. -.sH -udp_destroy -.LP -.sC -errstat -udp_destroy(chan_cap, flags) -capability *chan_cap; -int flags; -.eC -.kW "\fIudp_destroy\fP" -\fIUdp_destroy\fP not only cleans up the administration kept by the UDP library -but also destroys the channel capability. -.. -.SH FILES -.IP /dev/eth* \w'/dev/psip*mmm'u -Raw ethernet. The numbers in the device names are decimal, so one may see -names from -.B eth0 -to -.BR eth15 . - -.IP /dev/psip* -First and second Pseudo IP network. -.IP /dev/ip* -IP devices for two ethernets and two Pseudo IP networks. -.IP /dev/tcp* -TCP devices for same four networks. -.IP /dev/udp* -UDP devices. -.IP "/dev/eth, /dev/psip, /dev/ip, /dev/tcp, /dev/udp" -Devices for the default network, links to the devices above. -.B Eth -is only present if ethernet is the default, -.B psip -only for pseudo IP. -.SH "SEE ALSO" -.BR hton (3), -.BR oneC_sum (3), -.BR inet (8), -.BR boot (8). -.SH DIAGNOSTICS -Several errors may be returned by the TCP/IP server. The error code -is found in the -.B errno -variable if the -.BR read , -.BR write , -or -.B ioctl -call returns -1. The TCP/IP error codes defined in are, among others: -.IP EPACKSIZE 5c -This indicates an attempt to read or write with a buffer that is too -large or too small. -.IP ENOBUFS -The TCP/IP server has insufficient memory to execute the request. -.IP ENOTTY -This indicates an attempt to execute a command the particular server -does not understand. -For example, a -.B NWIOGTCPCONF -on an ETH channel. -.IP EBADMODE -The request is refused because the channel is not fully configured, in the -wrong state or the parameters are invalid. -.IP ENETUNREACH -The destination network is not reachable. -.IP EHOSTUNREACH -The destination host is not reachable. -.IP EISCONN -The channel is already connected so a second request is refused. -.IP EADDRINUSE -This address is in use. -.IP ECONNREFUSED -The connection is refused by the other side. -.IP ECONNRESET -The connection is reset (non-gracefully terminated) by the other side. -.IP ETIMEDOUT -The connection is terminated due to an expired timer. -.IP EURG -Urgent data is present and the current receive mode does not allow urgent data -to be transferred. -.IP ENOURG -No urgent data is present and a request came for urgent data. -.IP ENOTCONN -The request requires a connected channel and the channel is not connected. -.IP ESHUTDOWN -The connection is shut down. -That is, a -.B NWIOTCPSHUTDOWN -has been executed so no more data can be transmitted. -.IP ENOCONN -The connection does not exist. -.IP EGENERIC -A generic error code for extremely weird cases. -.SH AUTHOR -Philip Homburg (philip@cs.vu.nl) - -.\" -.\" $PchId: ip.4,v 1.4 2001/01/08 19:58:14 philip Exp $ diff --git a/minix/man/man7/hier.7 b/minix/man/man7/hier.7 index b47a72505..50902ab49 100644 --- a/minix/man/man7/hier.7 +++ b/minix/man/man7/hier.7 @@ -45,8 +45,6 @@ System configuration and data files; see also \fB/usr/etc/\fP. \fBhosts\fP TCP/IP hosts database, \fBhosts\fP(5) \fBhosts.equiv\fP trusted remote users or hosts, \fBrhosts\fP(5) - \fBinet.conf\fP - internet server config file, \fBinet\fP(8) \fBkeymap\fP keymap for custom keyboard, \fBloadkeys\fP(1) \fBman.conf\fP configuration file for man(1), \fBman.conf\fP(5) @@ -132,8 +130,7 @@ Contains source and majority of system utilities and files \fBarpa\fP include files for Internet service protocols \fBmachine\fP machine specific include files \fBminix\fP MINIX 3 kernel include files - \fBnetinet\fP include files for Inernet standard protocols, see - \fBinet\fP(8) + \fBnetinet\fP include files for Internet standard protocols \fBsys\fP system C include files. ... diff --git a/minix/man/man8/config.8 b/minix/man/man8/config.8 index 87948107c..3988c8ea9 100644 --- a/minix/man/man8/config.8 +++ b/minix/man/man8/config.8 @@ -179,23 +179,6 @@ on this. Note also the boot variable, you can use it to put more characters on the screen, at the cost of video memory. .TP -.SB ENABLE_DP8390 -Master switch to enable the network drivers. They are required by the -network server, -.BR inet . -See -.BR boot (8) -for information on configuring network support. -.TP -.SB ENABLE_WDETH -Enable code for the WD8003 and WD8013 cards in the network driver. -.TP -.SB ENABLE_NE2000 -Enable code for the NE1000 and NE2000 cards. -.TP -.SB ENABLE_3C503 -Enable code for the 3Com Etherlink II (3C503). -.TP .SB NR_PTYS Number of pseudo terminals supported, by default .BR 0 , @@ -238,56 +221,6 @@ Number of active file locks by These locks are often used by programs that update a shared file, like mail programs do with mail boxes. A "no locks available" error indicates that this table has run out. -.PP -.ti 2m -.B inet/inet_config.h -.br -The maximum number of TCP/IP networks is: -.TP -.B IP_PORT_MAX -Sets the maximum number of networks that can be defined in -.BR /etc/inet.conf . -.BR 8086 , -.BR 286 : -By default 2. -.BR 386 : -By default 4. -.PP -.ti 2m -.B inet/buf.c -.br -The number of 512 byte buffers allocated for data within the TCP/IP server is: -.TP -.B BUF512_NR -These buffers are a shared resource used by the server for any data it wants -to play with. For incoming data this number of buffers determines the time -packets are kept around, with each new packet evicting an old packet. It's -no big deal if packets get lost before a user process reads them, packets -get lost all the time. The only real problem is outgoing TCP data. The -default setting for -.SB BUF512_NR -allows up to four backlogged TCP streams, i.e. when data is output faster -then it is read. If more buffers are needed then one of the TCP connections -is shut down. When this happens you will see a "not enough buffers left" -error. This could happen for instance if a MINIX 3 web server is assaulted by -a browser that likes to open several connections to the server -simultaneously. The fix is to increase -.SB BUF512_NR -to allow more slow outgoing TCP streams. -.BR 86 : -The default of -.B 32 -buffers can be increased up to -.BR 64 . -(The "TCP window size" has been limited in 16-bit mode to keep the buffer -use by TCP down.) -.BR 386 : -The default of -.B 128 -can be increased to any value you like, but -.B 512 -seems to be more than enough. Minix-vmd uses 512 by default, and it seems -happy that way. .SH "SEE ALSO" .BR controller (4), .BR usage (8), diff --git a/minix/net/Makefile b/minix/net/Makefile index 67fab21a8..374b5e974 100644 --- a/minix/net/Makefile +++ b/minix/net/Makefile @@ -1,7 +1,6 @@ .include .if ${MKIMAGEONLY} == "no" -SUBDIR+= inet SUBDIR+= uds .endif # ${MKIMAGEONLY} == "no" diff --git a/minix/net/inet/Makefile b/minix/net/inet/Makefile deleted file mode 100644 index 85a47f5a1..000000000 --- a/minix/net/inet/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Makefile for inet. -PROG= inet -SRCS= buf.c clock.c inet.c inet_config.c \ - mnx_eth.c mq.c qp.c sr.c \ - udp.c arp.c eth.c event.c \ - icmp.c io.c ip.c ip_ioctl.c \ - ip_lib.c ip_read.c ip_write.c \ - ipr.c rand256.c tcp.c tcp_lib.c \ - tcp_recv.c tcp_send.c ip_eth.c \ - ip_ps.c psip.c \ - queryparam.c version.c rtinfo.c -MAN= inet.8 - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -.PATH: ${.CURDIR}/generic - -DPADD+= ${LIBCHARDRIVER} ${LIBSYS} -LDADD+= -lchardriver -lsys - -CPPFLAGS+= -I${.CURDIR} -D'ARGS(a)=a' - -.include diff --git a/minix/net/inet/buf.c b/minix/net/inet/buf.c deleted file mode 100644 index 28d948454..000000000 --- a/minix/net/inet/buf.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* -This file contains routines for buffer management. - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" - -#include -#include - -#include "generic/assert.h" -#include "generic/buf.h" - -THIS_FILE - -#ifndef BUF_USEMALLOC -#define BUF_USEMALLOC 0 -#endif - -#ifndef BUF512_NR -#define BUF512_NR 512 -#endif -#ifndef BUF2K_NR -#define BUF2K_NR 0 -#endif -#ifndef BUF32K_NR -#define BUF32K_NR 0 -#endif - -#define ACC_NR ((BUF512_NR+BUF2K_NR+BUF32K_NR)*3) -#define CLIENT_NR 10 - -#define DECLARE_TYPE(Tag, Type, Size) \ - typedef struct Tag \ - { \ - buf_t buf_header; \ - char buf_data[Size]; \ - } Type - -#if BUF_USEMALLOC -#define DECLARE_STORAGE(Type, Ident, Nitems) \ - PRIVATE Type *Ident - -#define ALLOC_STORAGE(Ident, Nitems, Label) \ - do \ - { \ - printf("buf.c: malloc %d %s\n", Nitems, Label); \ - Ident= malloc(sizeof(*Ident) * Nitems); \ - if (!Ident) \ - ip_panic(( "unable to alloc %s", Label )); \ - } while(0) -#else -#define DECLARE_STORAGE(Type, Ident, Nitems) \ - PRIVATE Type Ident[Nitems] - -#define ALLOC_STORAGE(Ident, Nitems, Label) \ - (void)0 -#endif - -#if BUF512_NR -DECLARE_TYPE(buf512, buf512_t, 512); -static acc_t *buf512_freelist; -DECLARE_STORAGE(buf512_t, buffers512, BUF512_NR); -static void bf_512free ARGS(( acc_t *acc )); -#endif -#if BUF2K_NR -DECLARE_TYPE(buf2K, buf2K_t, (2*1024)); -static acc_t *buf2K_freelist; -DECLARE_STORAGE(buf2K_t, buffers2K, BUF2K_NR); -static void bf_2Kfree ARGS(( acc_t *acc )); -#endif -#if BUF32K_NR -DECLARE_TYPE(buf32K, buf32K_t, (32*1024)); -static acc_t *buf32K_freelist; -DECLARE_STORAGE(buf32K_t, buffers32K, BUF32K_NR); -static void bf_32Kfree ARGS(( acc_t *acc )); -#endif - -static acc_t *acc_freelist; -DECLARE_STORAGE(acc_t, accessors, ACC_NR); - -static bf_freereq_t freereq[CLIENT_NR]; -static size_t bf_buf_gran; - -size_t bf_free_bufsize; -acc_t *bf_temporary_acc; -acc_t *bf_linkcheck_acc; - -#ifdef BUF_CONSISTENCY_CHECK -int inet_buf_debug; -unsigned buf_generation; -static bf_checkreq_t checkreq[CLIENT_NR]; -#endif - -#ifndef BUF_TRACK_ALLOC_FREE -static acc_t *bf_small_memreq ARGS(( size_t size )); -#else -static acc_t *_bf_small_memreq ARGS(( char *clnt_file, int clnt_line, - size_t size )); -#define bf_small_memreq(a) _bf_small_memreq(clnt_file, clnt_line, a) -#endif -static void free_accs ARGS(( void )); -#ifdef BUF_CONSISTENCY_CHECK -static void count_free_bufs ARGS(( acc_t *list )); -static int report_buffer ARGS(( buf_t *buf, char *label, int i )); -#endif - -void bf_init() -{ - int i; - size_t buf_s; - acc_t *acc; - - bf_buf_gran= BUF_S; - buf_s= 0; - - for (i=0;iacc_next; \ - acc->acc_linkC= 0; \ - \ - memset(&Ident[i], '\0', sizeof(Ident[i])); \ - Ident[i].buf_header.buf_linkC= 0; \ - Ident[i].buf_header.buf_free= Freefunc; \ - Ident[i].buf_header.buf_size= \ - sizeof(Ident[i].buf_data); \ - Ident[i].buf_header.buf_data_p= \ - Ident[i].buf_data; \ - \ - acc->acc_buffer= &Ident[i].buf_header; \ - acc->acc_next= Freelist; \ - Freelist= acc; \ - } \ - if (sizeof(Ident[0].buf_data) < bf_buf_gran) \ - bf_buf_gran= sizeof(Ident[0].buf_data); \ - if (sizeof(Ident[0].buf_data) > buf_s) \ - buf_s= sizeof(Ident[0].buf_data); \ - } while(0) - -#if BUF512_NR - INIT_BUFFERS(buffers512, BUF512_NR, buf512_freelist, bf_512free); -#endif -#if BUF2K_NR - INIT_BUFFERS(buffers2K, BUF2K_NR, buf2K_freelist, bf_2Kfree); -#endif -#if BUF32K_NR - INIT_BUFFERS(buffers32K, BUF32K_NR, buf32K_freelist, bf_32Kfree); -#endif - -#undef INIT_BUFFERS - - assert (buf_s == BUF_S); -} - -#ifndef BUF_CONSISTENCY_CHECK -void bf_logon(func) -bf_freereq_t func; -#else -void bf_logon(func, checkfunc) -bf_freereq_t func; -bf_checkreq_t checkfunc; -#endif -{ - int i; - - for (i=0;i0); - - head= NULL; - tail= NULL; - while (size) - { - new_acc= NULL; - - /* Note the tricky dangling else... */ -#define ALLOC_BUF(Freelist, Bufsize) \ - if (Freelist && (Bufsize == BUF_S || size <= Bufsize)) \ - { \ - new_acc= Freelist; \ - Freelist= new_acc->acc_next; \ - \ - assert(new_acc->acc_linkC == 0); \ - new_acc->acc_linkC= 1; \ - buf= new_acc->acc_buffer; \ - assert(buf->buf_linkC == 0); \ - buf->buf_linkC= 1; \ - } \ - else - - /* Sort attempts by buffer size */ -#if BUF512_NR - ALLOC_BUF(buf512_freelist, 512) -#endif -#if BUF2K_NR - ALLOC_BUF(buf2K_freelist, 2*1024) -#endif -#if BUF32K_NR - ALLOC_BUF(buf32K_freelist, 32*1024) -#endif -#undef ALLOC_BUF - { - DBLOCK(2, printf("freeing buffers\n")); - - bf_free_bufsize= 0; - for (i=0; bf_free_bufsizeacc_next) j++; - printf("# of free 512-bytes buffer is now %d\n", j); } -#endif - } -#if DEBUG && 0 - { printf("last level was level %d\n", i-1); } -#endif - if (bf_free_bufsizeacc_alloc_file= clnt_file; - new_acc->acc_alloc_line= clnt_line; - buf->buf_alloc_file= clnt_file; - buf->buf_alloc_line= clnt_line; -#endif - - if (!head) - head= new_acc; - else - tail->acc_next= new_acc; - tail= new_acc; - - count= tail->acc_buffer->buf_size; - if (count > size) - count= size; - - tail->acc_offset= 0; - tail->acc_length= count; - size -= count; - } - tail->acc_next= NULL; - - return head; -} - -/* -bf_small_memreq -*/ - -#ifndef BUF_TRACK_ALLOC_FREE -static acc_t *bf_small_memreq(size) -#else -static acc_t *_bf_small_memreq(clnt_file, clnt_line, size) -char *clnt_file; -int clnt_line; -#endif -size_t size; -{ - return bf_memreq(size); -} - -#ifndef BUF_TRACK_ALLOC_FREE -void bf_afree(acc) -#else -void _bf_afree(clnt_file, clnt_line, acc) -char *clnt_file; -int clnt_line; -#endif -acc_t *acc; -{ - acc_t *next_acc; - buf_t *buf; - - while (acc) - { -#if defined(bf_afree) - DIFBLOCK(1, (acc->acc_linkC <= 0), - printf("clnt_file= %s, clnt_line= %d\n", - clnt_file, clnt_line)); -#endif - assert (acc->acc_linkC>0); - if (--acc->acc_linkC > 0) - break; - -#ifdef BUF_TRACK_ALLOC_FREE - acc->acc_free_file= clnt_file; - acc->acc_free_line= clnt_line; -#endif - buf= acc->acc_buffer; - assert (buf); - -#if defined(bf_afree) - DIFBLOCK(1, (buf->buf_linkC == 0), - printf("clnt_file= %s, clnt_line= %d\n", - clnt_file, clnt_line)); -#endif - assert (buf->buf_linkC>0); - if (--buf->buf_linkC > 0) - { - acc->acc_buffer= NULL; - next_acc= acc->acc_next; - acc->acc_next= acc_freelist; - acc_freelist= acc; -#ifdef BUF_CONSISTENCY_CHECK - if (inet_buf_debug) - { - acc->acc_offset= 0xdeadbeaf; - acc->acc_length= 0xdeadbeaf; - acc->acc_buffer= (buf_t *)0xdeadbeaf; - acc->acc_ext_link= (acc_t *)0xdeadbeaf; - } -#endif - acc= next_acc; - continue; - } - - bf_free_bufsize += buf->buf_size; -#ifdef BUF_TRACK_ALLOC_FREE - buf->buf_free_file= clnt_file; - buf->buf_free_line= clnt_line; -#endif - next_acc= acc->acc_next; - buf->buf_free(acc); - acc= next_acc; - continue; - } -} - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_dupacc(acc_ptr) -#else -acc_t *_bf_dupacc(clnt_file, clnt_line, acc_ptr) -char *clnt_file; -int clnt_line; -#endif -register acc_t *acc_ptr; -{ - register acc_t *new_acc; - - if (!acc_freelist) - { - free_accs(); - if (!acc_freelist) - ip_panic(( "buf.c: out of accessors" )); - } - new_acc= acc_freelist; - acc_freelist= new_acc->acc_next; - - *new_acc= *acc_ptr; - if (acc_ptr->acc_next) - acc_ptr->acc_next->acc_linkC++; - if (acc_ptr->acc_buffer) - acc_ptr->acc_buffer->buf_linkC++; - new_acc->acc_linkC= 1; -#ifdef BUF_TRACK_ALLOC_FREE - new_acc->acc_alloc_file= clnt_file; - new_acc->acc_alloc_line= clnt_line; -#endif - return new_acc; -} - -size_t bf_bufsize(acc_ptr) -register acc_t *acc_ptr; -{ - register size_t size; - -assert(acc_ptr); - - size=0; - - while (acc_ptr) - { -assert(acc_ptr >= accessors && acc_ptr <= &accessors[ACC_NR-1]); - size += acc_ptr->acc_length; - acc_ptr= acc_ptr->acc_next; - } - return size; -} - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_packIffLess(pack, min_len) -#else -acc_t *_bf_packIffLess(clnt_file, clnt_line, pack, min_len) -char *clnt_file; -int clnt_line; -#endif -acc_t *pack; -int min_len; -{ - if (!pack || pack->acc_length >= min_len) - return pack; - -#if DEBUG -#ifdef bf_packIffLess - { where(); printf("calling bf_pack because of %s %d: %d\n", bf_pack_file, - bf_pack_line, min_len); } -#endif -#endif - return bf_pack(pack); -} - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_pack(old_acc) -#else -acc_t *_bf_pack(clnt_file, clnt_line, old_acc) -char *clnt_file; -int clnt_line; -#endif -acc_t *old_acc; -{ - acc_t *new_acc, *acc_ptr_old, *acc_ptr_new; - size_t size, offset_old, offset_new, block_size, block_size_old; - - /* Check if old acc is good enough. */ - if (!old_acc || (!old_acc->acc_next && old_acc->acc_linkC == 1 && - old_acc->acc_buffer->buf_linkC == 1)) - { - return old_acc; - } - - size= bf_bufsize(old_acc); - assert(size > 0); - new_acc= bf_memreq(size); - acc_ptr_old= old_acc; - acc_ptr_new= new_acc; - offset_old= 0; - offset_new= 0; - while (size) - { - assert (acc_ptr_old); - if (offset_old == acc_ptr_old->acc_length) - { - offset_old= 0; - acc_ptr_old= acc_ptr_old->acc_next; - continue; - } - assert (offset_old < acc_ptr_old->acc_length); - block_size_old= acc_ptr_old->acc_length - offset_old; - assert (acc_ptr_new); - if (offset_new == acc_ptr_new->acc_length) - { - offset_new= 0; - acc_ptr_new= acc_ptr_new->acc_next; - continue; - } - assert (offset_new < acc_ptr_new->acc_length); - block_size= acc_ptr_new->acc_length - offset_new; - if (block_size > block_size_old) - block_size= block_size_old; - memcpy(ptr2acc_data(acc_ptr_new)+offset_new, - ptr2acc_data(acc_ptr_old)+offset_old, block_size); - offset_new += block_size; - offset_old += block_size; - size -= block_size; - } - bf_afree(old_acc); - return new_acc; -} - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_cut (data, offset, length) -#else -acc_t *_bf_cut (clnt_file, clnt_line, data, offset, length) -char *clnt_file; -int clnt_line; -#endif -register acc_t *data; -register unsigned offset; -register unsigned length; -{ - register acc_t *head, *tail; - - if (!data && !offset && !length) - return NULL; -#ifdef BUF_TRACK_ALLOC_FREE - assert(data || - (printf("from %s, %d: %u, %u\n", - clnt_file, clnt_line, offset, length), 0)); -#else - assert(data); -#endif - - assert(data); - - if (!length) - { - head= bf_dupacc(data); - bf_afree(head->acc_next); - head->acc_next= NULL; - head->acc_length= 0; - return head; - } - while (data && offset>=data->acc_length) - { - offset -= data->acc_length; - data= data->acc_next; - } - - assert (data); - - head= bf_dupacc(data); - bf_afree(head->acc_next); - head->acc_next= NULL; - head->acc_offset += offset; - head->acc_length -= offset; - if (length >= head->acc_length) - length -= head->acc_length; - else - { - head->acc_length= length; - length= 0; - } - tail= head; - data= data->acc_next; - while (data && length && length>=data->acc_length) - { - tail->acc_next= bf_dupacc(data); - tail= tail->acc_next; - bf_afree(tail->acc_next); - tail->acc_next= NULL; - data= data->acc_next; - length -= tail->acc_length; - } - if (length) - { -#ifdef bf_cut - assert (data || - (printf("bf_cut called from %s:%d\n", - clnt_file, clnt_line), 0)); -#else - assert (data); -#endif - tail->acc_next= bf_dupacc(data); - tail= tail->acc_next; - bf_afree(tail->acc_next); - tail->acc_next= NULL; - tail->acc_length= length; - } - return head; -} - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_delhead (data, offset) -#else -acc_t *_bf_delhead (clnt_file, clnt_line, data, offset) -char *clnt_file; -int clnt_line; -#endif -register acc_t *data; -register unsigned offset; -{ - acc_t *new_acc; - - assert(data); - - /* Find the acc we need to modify. */ - new_acc= data; - while(offset >= new_acc->acc_length) - { - offset -= new_acc->acc_length; - new_acc= new_acc->acc_next; -#ifdef BUF_TRACK_ALLOC_FREE - assert(new_acc || (printf("called from %s, %d\n", - clnt_file, clnt_line),0)); -#else - assert(new_acc); -#endif - } - - /* Discard the old acc(s) */ - if (new_acc != data) - { - new_acc->acc_linkC++; - bf_afree(data); - data= new_acc; - } - - /* Make sure that acc_linkC == 1 */ - if (data->acc_linkC != 1) - { - new_acc= bf_dupacc(data); - bf_afree(data); - data= new_acc; - } - - /* Delete the last bit by modifying acc_offset and acc_length */ - data->acc_offset += offset; - data->acc_length -= offset; - return data; -} - -/* -bf_append -*/ - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_append(data_first, data_second) -#else -acc_t *_bf_append(clnt_file, clnt_line, data_first, data_second) -char *clnt_file; -int clnt_line; -#endif -acc_t *data_first; -acc_t *data_second; -{ - acc_t *head, *tail, *new_acc, *acc_ptr_new, tmp_acc, *curr; - char *src_ptr, *dst_ptr; - size_t size, offset_old, offset_new, block_size_old, block_size; - - if (!data_first) - return data_second; - if (!data_second) - return data_first; - - head= NULL; - tail= NULL; - while (data_first) - { - if (data_first->acc_linkC == 1) - curr= data_first; - else - { - curr= bf_dupacc(data_first); - assert (curr->acc_linkC == 1); - bf_afree(data_first); - } - data_first= curr->acc_next; - if (!curr->acc_length) - { - curr->acc_next= NULL; - bf_afree(curr); - continue; - } - if (!head) - head= curr; - else - tail->acc_next= curr; - tail= curr; - } - if (!head) - return data_second; - tail->acc_next= NULL; - - while (data_second && !data_second->acc_length) - { - curr= data_second; - data_second= data_second->acc_next; - if (data_second) - data_second->acc_linkC++; - bf_afree(curr); - } - if (!data_second) - return head; - - if (tail->acc_length + data_second->acc_length > - tail->acc_buffer->buf_size) - { - tail->acc_next= data_second; - return head; - } - - if (tail->acc_buffer->buf_size == bf_buf_gran && - tail->acc_buffer->buf_linkC == 1) - { - if (tail->acc_offset) - { - memmove(tail->acc_buffer->buf_data_p, - ptr2acc_data(tail), tail->acc_length); - tail->acc_offset= 0; - } - dst_ptr= ptr2acc_data(tail) + tail->acc_length; - src_ptr= ptr2acc_data(data_second); - memcpy(dst_ptr, src_ptr, data_second->acc_length); - tail->acc_length += data_second->acc_length; - tail->acc_next= data_second->acc_next; - if (data_second->acc_next) - data_second->acc_next->acc_linkC++; - bf_afree(data_second); - return head; - } - - new_acc= bf_small_memreq(tail->acc_length+data_second->acc_length); - acc_ptr_new= new_acc; - offset_old= 0; - offset_new= 0; - size= tail->acc_length; - while (size) - { -assert (acc_ptr_new); - if (offset_new == acc_ptr_new->acc_length) - { - offset_new= 0; - acc_ptr_new= acc_ptr_new->acc_next; - continue; - } -assert (offset_new < acc_ptr_new->acc_length); -assert (offset_old < tail->acc_length); - block_size_old= tail->acc_length - offset_old; - block_size= acc_ptr_new->acc_length - offset_new; - if (block_size > block_size_old) - block_size= block_size_old; - memcpy(ptr2acc_data(acc_ptr_new)+offset_new, - ptr2acc_data(tail)+offset_old, block_size); - offset_new += block_size; - offset_old += block_size; - size -= block_size; - } - offset_old= 0; - size= data_second->acc_length; - while (size) - { -assert (acc_ptr_new); - if (offset_new == acc_ptr_new->acc_length) - { - offset_new= 0; - acc_ptr_new= acc_ptr_new->acc_next; - continue; - } -assert (offset_new < acc_ptr_new->acc_length); -assert (offset_old < data_second->acc_length); - block_size_old= data_second->acc_length - offset_old; - block_size= acc_ptr_new->acc_length - offset_new; - if (block_size > block_size_old) - block_size= block_size_old; - memcpy(ptr2acc_data(acc_ptr_new)+offset_new, - ptr2acc_data(data_second)+offset_old, block_size); - offset_new += block_size; - offset_old += block_size; - size -= block_size; - } - tmp_acc= *tail; - *tail= *new_acc; - *new_acc= tmp_acc; - - bf_afree(new_acc); - while (tail->acc_next) - tail= tail->acc_next; - - tail->acc_next= data_second->acc_next; - if (data_second->acc_next) - data_second->acc_next->acc_linkC++; - bf_afree(data_second); - return head; -} - -#if BUF512_NR -static void bf_512free(acc) -acc_t *acc; -{ -#ifdef BUF_CONSISTENCY_CHECK - if (inet_buf_debug) - memset(acc->acc_buffer->buf_data_p, 0xa5, 512); -#endif - acc->acc_next= buf512_freelist; - buf512_freelist= acc; -} -#endif -#if BUF2K_NR -static void bf_2Kfree(acc) -acc_t *acc; -{ -#ifdef BUF_CONSISTENCY_CHECK - if (inet_buf_debug) - memset(acc->acc_buffer->buf_data_p, 0xa5, 2*1024); -#endif - acc->acc_next= buf2K_freelist; - buf2K_freelist= acc; -} -#endif -#if BUF32K_NR -static void bf_32Kfree(acc) -acc_t *acc; -{ -#ifdef BUF_CONSISTENCY_CHECK - if (inet_buf_debug) - memset(acc->acc_buffer->buf_data_p, 0xa5, 32*1024); -#endif - acc->acc_next= buf32K_freelist; - buf32K_freelist= acc; -} -#endif - -#ifdef BUF_CONSISTENCY_CHECK -int bf_consistency_check() -{ - acc_t *acc; - int silent; - int error; - int i; - - buf_generation++; - - for (i=0; iacc_next) - { - if (acc->acc_generation == buf_generation-1) - { - acc->acc_generation= buf_generation; - acc->acc_check_linkC= 0; - } - else - { - assert(acc->acc_generation == buf_generation && - acc->acc_check_linkC > 0); - acc->acc_check_linkC= -acc->acc_check_linkC; - } - } - -#if BUF512_NR - count_free_bufs(buf512_freelist); -#endif -#if BUF2K_NR - count_free_bufs(buf2K_freelist); -#endif -#if BUF32K_NR - count_free_bufs(buf32K_freelist); -#endif - - error= 0; - - /* Report about accessors */ - silent= 0; - for (i=0, acc= accessors; iacc_generation != buf_generation) - { - error++; - assert(acc->acc_generation == buf_generation-1); - acc->acc_generation= buf_generation; - if (!silent) - { - printf( -"acc[%d] (%p) has been lost with count %d, last allocated at %s, %d\n", - i, acc, acc->acc_linkC, acc->acc_alloc_file, acc->acc_alloc_line); -#if 0 - silent= 1; -#endif - } - continue; - } - if (acc->acc_check_linkC == acc->acc_linkC) - continue; - error++; - if (acc->acc_check_linkC < 0) - { - if (!silent) - { - printf( -"acc[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n", - i, acc->acc_alloc_file, acc->acc_alloc_line, - acc->acc_free_file, acc->acc_free_line); - } - acc->acc_check_linkC= -acc->acc_check_linkC; - if (acc->acc_check_linkC == acc->acc_linkC) - { - silent= 1; - continue; - } - } - if (!silent) - { - printf( -"# of tracked links (%d) for acc[%d] don't match with stored link count %d\n", - acc->acc_check_linkC, i, acc->acc_linkC); - printf("acc[%d] was allocated at %s, %d\n", - i, acc->acc_alloc_file, acc->acc_alloc_line); - silent=1; - } - } - - /* Report about buffers */ -#if BUF512_NR - { - for (i= 0; iacc_next) - { - if (acc->acc_generation != buf_generation-1) - { - assert(acc->acc_generation == buf_generation && - acc->acc_check_linkC > 0); - acc->acc_check_linkC= -acc->acc_check_linkC; - continue; - } - acc->acc_generation= buf_generation; - acc->acc_check_linkC= 0; - - buf= acc->acc_buffer; - if (buf->buf_generation == buf_generation-1) - { - buf->buf_generation= buf_generation; - buf->buf_check_linkC= 0; - continue; - } - assert(buf->buf_generation == buf_generation && - buf->buf_check_linkC > 0); - buf->buf_check_linkC= -buf->buf_check_linkC; - } -} - -static int report_buffer(buf, label, i) -buf_t *buf; -char *label; -int i; -{ - if (buf->buf_generation != buf_generation) - { - assert(buf->buf_generation == buf_generation-1); - buf->buf_generation= buf_generation; - printf( -"%s[%d] (%p) has been lost with count %d, last allocated at %s, %d\n", - label, i, buf, - buf->buf_linkC, buf->buf_alloc_file, - buf->buf_alloc_line); - return 1; - } - if (buf->buf_check_linkC == buf->buf_linkC) - return 0; - if (buf->buf_check_linkC < 0) - { - printf( -"%s[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n", - label, i, buf->buf_alloc_file, buf->buf_alloc_line, - buf->buf_free_file, buf->buf_free_line); - buf->buf_check_linkC= -buf->buf_check_linkC; - if (buf->buf_check_linkC == buf->buf_linkC) - return 1; - } - printf( -"# of tracked links (%d) for %s[%d] don't match with stored link count %d\n", - buf->buf_check_linkC, label, i, buf->buf_linkC); - printf("%s[%d] was allocated at %s, %d\n", - label, i, buf->buf_alloc_file, buf->buf_alloc_line); - return 1; -} - -void bf_check_acc(acc) -acc_t *acc; -{ - buf_t *buf; - - while(acc != NULL) - { - if (acc->acc_generation == buf_generation) - { - assert(acc->acc_check_linkC > 0); - acc->acc_check_linkC++; - return; - } - assert(acc->acc_generation == buf_generation-1); - acc->acc_generation= buf_generation; - acc->acc_check_linkC= 1; - - buf= acc->acc_buffer; - if (buf->buf_generation == buf_generation) - { - assert(buf->buf_check_linkC > 0); - buf->buf_check_linkC++; - } - else - { - assert(buf->buf_generation == buf_generation-1); - buf->buf_generation= buf_generation; - buf->buf_check_linkC= 1; - } - - acc= acc->acc_next; - } -} - -void _bf_mark_1acc(clnt_file, clnt_line, acc) -char *clnt_file; -int clnt_line; -acc_t *acc; -{ - acc->acc_alloc_file= clnt_file; - acc->acc_alloc_line= clnt_line; -} - -void _bf_mark_acc(clnt_file, clnt_line, acc) -char *clnt_file; -int clnt_line; -acc_t *acc; -{ - buf_t *buf; - - for (; acc; acc= acc->acc_next) - { - acc->acc_alloc_file= clnt_file; - acc->acc_alloc_line= clnt_line; - buf= acc->acc_buffer; - buf->buf_alloc_file= clnt_file; - buf->buf_alloc_line= clnt_line; - } -} -#endif - -int bf_linkcheck(acc) -acc_t *acc; -{ - int i; - - buf_t *buffer; - for (i= 0; iacc_next) - { - if (acc->acc_linkC <= 0) - { - printf("wrong acc_linkC (%d) for acc %p\n", - acc->acc_linkC, acc); - return 0; - } - if (acc->acc_offset < 0) - { - printf("wrong acc_offset (%d) for acc %p\n", - acc->acc_offset, acc); - return 0; - } - if (acc->acc_length < 0) - { - printf("wrong acc_length (%d) for acc %p\n", - acc->acc_length, acc); - return 0; - } - buffer= acc->acc_buffer; - if (buffer == NULL) - { - printf("no buffer for acc %p\n", acc); - return 0; - } - if (buffer->buf_linkC <= 0) - { - printf( - "wrong buf_linkC (%d) for buffer %p, from acc %p\n", - buffer->buf_linkC, buffer, acc); - return 0; - } - if (acc->acc_offset + acc->acc_length > buffer->buf_size) - { - printf("%d + %d > %zu for buffer %p, and acc %p\n", - acc->acc_offset, acc->acc_length, - buffer->buf_size, buffer, acc); - return 0; - } - } - if (acc != NULL) - { - printf("loop\n"); - return 0; - } - return 1; -} - -static void free_accs() -{ - int i, j; - - DBLOCK(1, printf("free_accs\n")); - -assert(bf_linkcheck(bf_linkcheck_acc)); - for (i=0; !acc_freelist && iacc_length >= size) - { - ptr= ptr2acc_data(acc); - if (((unsigned)ptr & (alignment-1)) == 0) - return acc; - } - buf_size= bf_bufsize(acc); -#ifdef bf_align - assert((size != 0 && buf_size != 0) || - (printf("bf_align(..., %d, %d) from %s, %d\n", - size, alignment, clnt_file, clnt_line),0)); -#else - assert(size != 0 && buf_size != 0); -#endif - if (buf_size <= size) - { - acc= bf_pack(acc); - return acc; - } - head= bf_cut(acc, 0, size); - tail= bf_cut(acc, size, buf_size-size); - bf_afree(acc); - head= bf_pack(head); - assert(head->acc_next == NULL); - head->acc_next= tail; - return head; -} - -#if 0 -int chk_acc(acc) -acc_t *acc; -{ - int acc_nr; - - if (!acc) - return 1; - if (acc < accessors || acc >= &accessors[ACC_NR]) - return 0; - acc_nr= acc-accessors; - return acc == &accessors[acc_nr]; -} -#endif - -/* - * $PchId: buf.c,v 1.19 2003/09/10 08:54:23 philip Exp $ - */ diff --git a/minix/net/inet/clock.c b/minix/net/inet/clock.c deleted file mode 100644 index 1db6b4d82..000000000 --- a/minix/net/inet/clock.c +++ /dev/null @@ -1,190 +0,0 @@ -/* -clock.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "proto.h" -#include "generic/assert.h" -#include "generic/buf.h" -#include "generic/clock.h" - -THIS_FILE - -int clck_call_expire; - -static clock_t curr_time; -static clock_t prev_time; -static minix_timer_t *timer_chain; -static time_t next_timeout; - -static void clck_fast_release(minix_timer_t *timer); -static void set_timer(void); - -void clck_init() -{ - clck_call_expire= 0; - curr_time= 0; - prev_time= 0; - next_timeout= 0; - timer_chain= 0; -} - -time_t get_time() -{ - if (!curr_time) - { - curr_time = getticks(); - assert(curr_time >= prev_time); /* XXX */ - } - return curr_time; -} - -void set_time (tim) -clock_t tim; -{ - if (!curr_time && tim >= prev_time) - { - /* Some code assumes that no time elapses while it is - * running. - */ - curr_time= tim; - } - else if (!curr_time) - { - DBLOCK(0x20, printf("set_time: new time %u < prev_time %u\n", - tim, prev_time)); - } -} - -void reset_time() -{ - prev_time= curr_time; - curr_time= 0; -} - -void clck_timer(timer, timeout, func, fd) -minix_timer_t *timer; -time_t timeout; -timer_func_t func; -int fd; -{ - minix_timer_t *timer_index; - - if (timer->tim_active) - clck_fast_release(timer); - assert(!timer->tim_active); - - timer->tim_next= 0; - timer->tim_func= func; - timer->tim_ref= fd; - timer->tim_time= timeout; - timer->tim_active= 1; - - if (!timer_chain) - timer_chain= timer; - else if (timeout < timer_chain->tim_time) - { - timer->tim_next= timer_chain; - timer_chain= timer; - } - else - { - timer_index= timer_chain; - while (timer_index->tim_next && - timer_index->tim_next->tim_time < timeout) - timer_index= timer_index->tim_next; - timer->tim_next= timer_index->tim_next; - timer_index->tim_next= timer; - } - if (next_timeout == 0 || timer_chain->tim_time < next_timeout) - set_timer(); -} - -void clck_tick (mess) -message *mess; -{ - next_timeout= 0; - set_timer(); -} - -static void clck_fast_release (timer) -minix_timer_t *timer; -{ - minix_timer_t *timer_index; - - if (!timer->tim_active) - return; - - if (timer == timer_chain) - timer_chain= timer_chain->tim_next; - else - { - timer_index= timer_chain; - while (timer_index && timer_index->tim_next != timer) - timer_index= timer_index->tim_next; - assert(timer_index); - timer_index->tim_next= timer->tim_next; - } - timer->tim_active= 0; -} - -static void set_timer() -{ - time_t new_time; - time_t now; - - if (!timer_chain) - return; - - now= get_time(); - new_time= timer_chain->tim_time; - if (new_time <= now) - { - clck_call_expire= 1; - return; - } - - if (next_timeout == 0 || new_time < next_timeout) - { - next_timeout= new_time; - new_time -= now; - - if (sys_setalarm(new_time, 0) != OK) - ip_panic(("can't set timer")); - } -} - -void clck_untimer (timer) -minix_timer_t *timer; -{ - clck_fast_release (timer); - set_timer(); -} - -void clck_expire_timers() -{ - time_t now; - minix_timer_t *timer_index; - - clck_call_expire= 0; - - if (timer_chain == NULL) - return; - - now= get_time(); - while (timer_chain && timer_chain->tim_time<=now) - { - assert(timer_chain->tim_active); - timer_chain->tim_active= 0; - timer_index= timer_chain; - timer_chain= timer_chain->tim_next; - (*timer_index->tim_func)(timer_index->tim_ref, timer_index); - } - set_timer(); -} - -/* - * $PchId: clock.c,v 1.10 2005/06/28 14:23:40 philip Exp $ - */ diff --git a/minix/net/inet/const.h b/minix/net/inet/const.h deleted file mode 100644 index 4c4e7609d..000000000 --- a/minix/net/inet/const.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -inet/const.h - -Created: Dec 30, 1991 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__CONST_H -#define INET__CONST_H - -#ifndef DEBUG -#define DEBUG 0 -#endif - -#ifndef NDEBUG -#define NDEBUG 0 -#endif - -#define CLOCK_GRAN 1 /* in HZ */ - -#define where() printf("%s, %d: ", __FILE__, __LINE__) - -#define NW_SUSPEND SUSPEND -#define NW_WOULDBLOCK EWOULDBLOCK -#define NW_OK OK - -#define BUF_S 512 - -#endif /* INET__CONST_H */ - -/* - * $PchId: const.h,v 1.7 2000/08/12 09:21:44 philip Exp $ - */ diff --git a/minix/net/inet/generic/arp.c b/minix/net/inet/generic/arp.c deleted file mode 100644 index 38593b553..000000000 --- a/minix/net/inet/generic/arp.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* -arp.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "type.h" - -#include "arp.h" -#include "assert.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "eth.h" -#include "io.h" - -THIS_FILE - -#define ARP_CACHE_NR 256 -#define AP_REQ_NR 32 - -#define ARP_HASH_NR 256 -#define ARP_HASH_MASK 0xff -#define ARP_HASH_WIDTH 4 - -#define MAX_ARP_RETRIES 5 -#define ARP_TIMEOUT (HZ/2+1) /* .5 seconds */ -#ifndef ARP_EXP_TIME -#define ARP_EXP_TIME (20L*60L*HZ) /* 20 minutes */ -#endif -#define ARP_NOTRCH_EXP_TIME (30*HZ) /* 30 seconds */ -#define ARP_INUSE_OFFSET (60*HZ) /* an entry in the cache can be deleted - if its not used for 1 minute */ - -typedef struct arp46 -{ - ether_addr_t a46_dstaddr; - ether_addr_t a46_srcaddr; - ether_type_t a46_ethtype; - union ixfer_arp46_u - { - struct - { - u16_t a_hdr, a_pro; - u8_t a_hln, a_pln; - u16_t a_op; - ether_addr_t a_sha; - u8_t a_spa[4]; - ether_addr_t a_tha; - u8_t a_tpa[4]; - } a46_data; - char a46_dummy[ETH_MIN_PACK_SIZE-ETH_HDR_SIZE]; - } a46_data; -} arp46_t; - -#define a46_hdr a46_data.a46_data.a_hdr -#define a46_pro a46_data.a46_data.a_pro -#define a46_hln a46_data.a46_data.a_hln -#define a46_pln a46_data.a46_data.a_pln -#define a46_op a46_data.a46_data.a_op -#define a46_sha a46_data.a46_data.a_sha -#define a46_spa a46_data.a46_data.a_spa -#define a46_tha a46_data.a46_data.a_tha -#define a46_tpa a46_data.a46_data.a_tpa - -typedef struct arp_port -{ - int ap_flags; - int ap_state; - int ap_eth_port; - int ap_ip_port; - int ap_eth_fd; - - ether_addr_t ap_ethaddr; /* Ethernet address of this port */ - ipaddr_t ap_ipaddr; /* IP address of this port */ - - struct arp_req - { - minix_timer_t ar_timer; - int ar_entry; - int ar_req_count; - } ap_req[AP_REQ_NR]; - - arp_func_t ap_arp_func; - - acc_t *ap_sendpkt; - acc_t *ap_sendlist; - acc_t *ap_reclist; - event_t ap_event; -} arp_port_t; - -#define APF_EMPTY 0x00 -#define APF_ARP_RD_IP 0x01 -#define APF_ARP_RD_SP 0x02 -#define APF_ARP_WR_IP 0x04 -#define APF_ARP_WR_SP 0x08 -#define APF_INADDR_SET 0x10 -#define APF_SUSPEND 0x20 - -#define APS_INITIAL 1 -#define APS_GETADDR 2 -#define APS_ARPSTART 3 -#define APS_ARPPROTO 4 -#define APS_ARPMAIN 5 -#define APS_ERROR 6 - -typedef struct arp_cache -{ - int ac_flags; - int ac_state; - ether_addr_t ac_ethaddr; - ipaddr_t ac_ipaddr; - arp_port_t *ac_port; - time_t ac_expire; - time_t ac_lastuse; -} arp_cache_t; - -#define ACF_EMPTY 0 -#define ACF_PERM 1 -#define ACF_PUB 2 - -#define ACS_UNUSED 0 -#define ACS_INCOMPLETE 1 -#define ACS_VALID 2 -#define ACS_UNREACHABLE 3 - -static struct arp_hash_ent -{ - arp_cache_t *ahe_row[ARP_HASH_WIDTH]; -} arp_hash[ARP_HASH_NR]; - -static arp_port_t *arp_port_table; -static arp_cache_t *arp_cache; -static int arp_cache_nr; - -static acc_t *arp_getdata ARGS(( int fd, size_t offset, - size_t count, int for_ioctl )); -static int arp_putdata ARGS(( int fd, size_t offset, - acc_t *data, int for_ioctl )); -static void arp_main ARGS(( arp_port_t *arp_port )); -static void arp_timeout ARGS(( int ref, minix_timer_t *timer )); -static void setup_write ARGS(( arp_port_t *arp_port )); -static void setup_read ARGS(( arp_port_t *arp_port )); -static void do_reclist ARGS(( event_t *ev, ev_arg_t ev_arg )); -static void process_arp_pkt ARGS(( arp_port_t *arp_port, acc_t *data )); -static void client_reply ARGS(( arp_port_t *arp_port, - ipaddr_t ipaddr, ether_addr_t *ethaddr )); -static arp_cache_t *find_cache_ent ARGS(( arp_port_t *arp_port, - ipaddr_t ipaddr )); -static arp_cache_t *alloc_cache_ent ARGS(( int flags )); -static void arp_buffree ARGS(( int priority )); -#ifdef BUF_CONSISTENCY_CHECK -static void arp_bufcheck ARGS(( void )); -#endif - -void arp_prep() -{ - arp_port_table= alloc(eth_conf_nr * sizeof(arp_port_table[0])); - - arp_cache_nr= ARP_CACHE_NR; - if (arp_cache_nr < (eth_conf_nr+1)*AP_REQ_NR) - { - arp_cache_nr= (eth_conf_nr+1)*AP_REQ_NR; - printf("arp: using %d cache entries instead of %d\n", - arp_cache_nr, ARP_CACHE_NR); - } - arp_cache= alloc(arp_cache_nr * sizeof(arp_cache[0])); -} - -void arp_init() -{ - arp_port_t *arp_port; - arp_cache_t *cache; - int i; - - assert (BUF_S >= sizeof(struct nwio_ethstat)); - assert (BUF_S >= sizeof(struct nwio_ethopt)); - assert (BUF_S >= sizeof(arp46_t)); - - for (i=0, arp_port= arp_port_table; iap_state= APS_ERROR; /* Mark all ports as - * unavailable */ - } - - cache= arp_cache; - for (i=0; iac_state= ACS_UNUSED; - cache->ac_flags= ACF_EMPTY; - cache->ac_expire= 0; - cache->ac_lastuse= 0; - } - -#ifndef BUF_CONSISTENCY_CHECK - bf_logon(arp_buffree); -#else - bf_logon(arp_buffree, arp_bufcheck); -#endif -} - -static void arp_main(arp_port) -arp_port_t *arp_port; -{ - int result; - - switch (arp_port->ap_state) - { - case APS_INITIAL: - arp_port->ap_eth_fd= eth_open(arp_port->ap_eth_port, - arp_port->ap_eth_port, arp_getdata, arp_putdata, - 0 /* no put_pkt */, 0 /* no select_res */); - - if (arp_port->ap_eth_fd<0) - { - DBLOCK(1, printf("arp[%d]: unable to open eth[%d]\n", - arp_port-arp_port_table, - arp_port->ap_eth_port)); - return; - } - - arp_port->ap_state= APS_GETADDR; - - result= eth_ioctl (arp_port->ap_eth_fd, NWIOGETHSTAT); - - if ( result == NW_SUSPEND) - { - arp_port->ap_flags |= APF_SUSPEND; - return; - } - assert(result == NW_OK); - - /* fall through */ - case APS_GETADDR: - /* Wait for IP address */ - if (!(arp_port->ap_flags & APF_INADDR_SET)) - return; - - /* fall through */ - case APS_ARPSTART: - arp_port->ap_state= APS_ARPPROTO; - - result= eth_ioctl (arp_port->ap_eth_fd, NWIOSETHOPT); - - if (result==NW_SUSPEND) - { - arp_port->ap_flags |= APF_SUSPEND; - return; - } - assert(result == NW_OK); - - /* fall through */ - case APS_ARPPROTO: - arp_port->ap_state= APS_ARPMAIN; - setup_write(arp_port); - setup_read(arp_port); - return; - - default: - ip_panic(( - "arp_main(&arp_port_table[%d]) called but ap_state=0x%x\n", - arp_port->ap_eth_port, arp_port->ap_state )); - } -} - -static acc_t *arp_getdata (fd, offset, count, for_ioctl) -int fd; -size_t offset; -size_t count; -int for_ioctl; -{ - arp_port_t *arp_port; - acc_t *data; - int result; - - arp_port= &arp_port_table[fd]; - - switch (arp_port->ap_state) - { - case APS_ARPPROTO: - if (!count) - { - result= (int)offset; - if (result<0) - { - arp_port->ap_state= APS_ERROR; - break; - } - if (arp_port->ap_flags & APF_SUSPEND) - { - arp_port->ap_flags &= ~APF_SUSPEND; - arp_main(arp_port); - } - return NW_OK; - } - assert ((!offset) && (count == sizeof(struct nwio_ethopt))); - { - struct nwio_ethopt *ethopt; - acc_t *acc; - - acc= bf_memreq(sizeof(*ethopt)); - ethopt= (struct nwio_ethopt *)ptr2acc_data(acc); - ethopt->nweo_flags= NWEO_COPY|NWEO_EN_BROAD| - NWEO_TYPESPEC; - ethopt->nweo_type= HTONS(ETH_ARP_PROTO); - return acc; - } - case APS_ARPMAIN: - assert (arp_port->ap_flags & APF_ARP_WR_IP); - if (!count) - { - data= arp_port->ap_sendpkt; - arp_port->ap_sendpkt= NULL; - assert(data); - bf_afree(data); data= NULL; - - result= (int)offset; - if (result<0) - { - DIFBLOCK(1, (result != NW_SUSPEND), - printf( - "arp[%d]: write error on port %d: error %d\n", - fd, arp_port->ap_eth_fd, result)); - - arp_port->ap_state= APS_ERROR; - break; - } - arp_port->ap_flags &= ~APF_ARP_WR_IP; - if (arp_port->ap_flags & APF_ARP_WR_SP) - setup_write(arp_port); - return NW_OK; - } - assert (offset+count <= sizeof(arp46_t)); - data= arp_port->ap_sendpkt; - assert(data); - data= bf_cut(data, offset, count); - - return data; - default: - printf("arp_getdata(%d, 0x%d, 0x%d) called but ap_state=0x%x\n", - fd, offset, count, arp_port->ap_state); - break; - } - return 0; -} - -static int arp_putdata (fd, offset, data, for_ioctl) -int fd; -size_t offset; -acc_t *data; -int for_ioctl; -{ - arp_port_t *arp_port; - int result; - struct nwio_ethstat *ethstat; - ev_arg_t ev_arg; - acc_t *tmpacc; - - arp_port= &arp_port_table[fd]; - - if (arp_port->ap_flags & APF_ARP_RD_IP) - { - if (!data) - { - result= (int)offset; - if (result<0) - { - DIFBLOCK(1, (result != NW_SUSPEND), printf( - "arp[%d]: read error on port %d: error %d\n", - fd, arp_port->ap_eth_fd, result)); - - return NW_OK; - } - if (arp_port->ap_flags & APF_ARP_RD_SP) - { - arp_port->ap_flags &= ~(APF_ARP_RD_IP| - APF_ARP_RD_SP); - setup_read(arp_port); - } - else - arp_port->ap_flags &= ~(APF_ARP_RD_IP| - APF_ARP_RD_SP); - return NW_OK; - } - assert (!offset); - /* Warning: the above assertion is illegal; puts and gets of - data can be brokenup in any piece the server likes. However - we assume that the server is eth.c and it transfers only - whole packets. - */ - data= bf_packIffLess(data, sizeof(arp46_t)); - if (data->acc_length >= sizeof(arp46_t)) - { - if (!arp_port->ap_reclist) - { - ev_arg.ev_ptr= arp_port; - ev_enqueue(&arp_port->ap_event, do_reclist, - ev_arg); - } - if (data->acc_linkC != 1) - { - tmpacc= bf_dupacc(data); - bf_afree(data); - data= tmpacc; - tmpacc= NULL; - } - data->acc_ext_link= arp_port->ap_reclist; - arp_port->ap_reclist= data; - } - else - bf_afree(data); - return NW_OK; - } - switch (arp_port->ap_state) - { - case APS_GETADDR: - if (!data) - { - result= (int)offset; - if (result<0) - { - arp_port->ap_state= APS_ERROR; - break; - } - if (arp_port->ap_flags & APF_SUSPEND) - { - arp_port->ap_flags &= ~APF_SUSPEND; - arp_main(arp_port); - } - return NW_OK; - } - compare (bf_bufsize(data), ==, sizeof(*ethstat)); - data= bf_packIffLess(data, sizeof(*ethstat)); - compare (data->acc_length, ==, sizeof(*ethstat)); - ethstat= (struct nwio_ethstat *)ptr2acc_data(data); - arp_port->ap_ethaddr= ethstat->nwes_addr; - bf_afree(data); - return NW_OK; - default: - printf("arp_putdata(%d, 0x%d, 0x%lx) called but ap_state=0x%x\n", - fd, offset, (unsigned long)data, arp_port->ap_state); - break; - } - return EGENERIC; -} - -static void setup_read(arp_port) -arp_port_t *arp_port; -{ - int result; - - while (!(arp_port->ap_flags & APF_ARP_RD_IP)) - { - arp_port->ap_flags |= APF_ARP_RD_IP; - result= eth_read (arp_port->ap_eth_fd, ETH_MAX_PACK_SIZE); - if (result == NW_SUSPEND) - { - arp_port->ap_flags |= APF_ARP_RD_SP; - return; - } - DIFBLOCK(1, (result != NW_OK), - printf("arp[%d]: eth_read(..,%d)=%d\n", - arp_port-arp_port_table, ETH_MAX_PACK_SIZE, result)); - } -} - -static void setup_write(arp_port) -arp_port_t *arp_port; -{ - int result; - acc_t *data; - - for(;;) - { - data= arp_port->ap_sendlist; - if (!data) - break; - arp_port->ap_sendlist= data->acc_ext_link; - - if (arp_port->ap_ipaddr == HTONL(0x00000000)) - { - /* Interface is down */ - printf( - "arp[%d]: not sending ARP packet, interface is down\n", - arp_port-arp_port_table); - bf_afree(data); data= NULL; - continue; - } - - assert(!arp_port->ap_sendpkt); - arp_port->ap_sendpkt= data; data= NULL; - - arp_port->ap_flags= (arp_port->ap_flags & ~APF_ARP_WR_SP) | - APF_ARP_WR_IP; - result= eth_write(arp_port->ap_eth_fd, sizeof(arp46_t)); - if (result == NW_SUSPEND) - { - arp_port->ap_flags |= APF_ARP_WR_SP; - break; - } - if (result<0) - { - DIFBLOCK(1, (result != NW_SUSPEND), - printf("arp[%d]: eth_write(..,%d)=%d\n", - arp_port-arp_port_table, sizeof(arp46_t), - result)); - return; - } - } -} - -static void do_reclist(ev, ev_arg) -event_t *ev; -ev_arg_t ev_arg; -{ - arp_port_t *arp_port; - acc_t *data; - - arp_port= ev_arg.ev_ptr; - assert(ev == &arp_port->ap_event); - - while (data= arp_port->ap_reclist, data != NULL) - { - arp_port->ap_reclist= data->acc_ext_link; - process_arp_pkt(arp_port, data); - bf_afree(data); - } -} - -static void process_arp_pkt (arp_port, data) -arp_port_t *arp_port; -acc_t *data; -{ - int i, entry, do_reply; - arp46_t *arp; - u16_t *p; - arp_cache_t *ce, *cache; - struct arp_req *reqp; - time_t curr_time; - ipaddr_t spa, tpa; - - curr_time= get_time(); - - arp= (arp46_t *)ptr2acc_data(data); - memcpy(&spa, arp->a46_spa, sizeof(ipaddr_t)); - memcpy(&tpa, arp->a46_tpa, sizeof(ipaddr_t)); - - if (arp->a46_hdr != HTONS(ARP_ETHERNET) || - arp->a46_hln != 6 || - arp->a46_pro != HTONS(ETH_IP_PROTO) || - arp->a46_pln != 4) - return; - if (arp_port->ap_ipaddr == HTONL(0x00000000)) - { - /* Interface is down */ -#if DEBUG - printf("arp[%d]: dropping ARP packet, interface is down\n", - arp_port-arp_port_table); -#endif - return; - } - - ce= find_cache_ent(arp_port, spa); - cache= NULL; /* lint */ - - do_reply= 0; - if (arp->a46_op != HTONS(ARP_REQUEST)) - ; /* No need to reply */ - else if (tpa == arp_port->ap_ipaddr) - do_reply= 1; - else - { - /* Look for a published entry */ - cache= find_cache_ent(arp_port, tpa); - if (cache) - { - if (cache->ac_flags & ACF_PUB) - { - /* Published entry */ - do_reply= 1; - } - else - { - /* Nothing to do */ - cache= NULL; - } - } - } - - if (ce == NULL) - { - if (!do_reply) - return; - - DBLOCK(0x10, printf("arp[%d]: allocating entry for ", - arp_port-arp_port_table); - writeIpAddr(spa); printf("\n")); - - ce= alloc_cache_ent(ACF_EMPTY); - ce->ac_flags= ACF_EMPTY; - ce->ac_state= ACS_VALID; - ce->ac_ethaddr= arp->a46_sha; - ce->ac_ipaddr= spa; - ce->ac_port= arp_port; - ce->ac_expire= curr_time+ARP_EXP_TIME; - ce->ac_lastuse= curr_time-ARP_INUSE_OFFSET; /* never used */ - } - - if (ce->ac_state == ACS_INCOMPLETE || ce->ac_state == ACS_UNREACHABLE) - { - ce->ac_ethaddr= arp->a46_sha; - if (ce->ac_state == ACS_INCOMPLETE) - { - /* Find request entry */ - entry= ce-arp_cache; - for (i= 0, reqp= arp_port->ap_req; iar_entry == entry) - break; - } - assert(i < AP_REQ_NR); - clck_untimer(&reqp->ar_timer); - reqp->ar_entry= -1; - - ce->ac_state= ACS_VALID; - client_reply(arp_port, spa, &arp->a46_sha); - } - else - ce->ac_state= ACS_VALID; - } - - /* Update fields in the arp cache. */ - if (memcmp(&ce->ac_ethaddr, &arp->a46_sha, - sizeof(ce->ac_ethaddr)) != 0) - { - printf("arp[%d]: ethernet address for IP address ", - arp_port-arp_port_table); - writeIpAddr(spa); - printf(" changed from "); - writeEtherAddr(&ce->ac_ethaddr); - printf(" to "); - writeEtherAddr(&arp->a46_sha); - printf("\n"); - ce->ac_ethaddr= arp->a46_sha; - } - ce->ac_expire= curr_time+ARP_EXP_TIME; - - if (do_reply) - { - data= bf_memreq(sizeof(arp46_t)); - arp= (arp46_t *)ptr2acc_data(data); - - /* Clear padding */ - assert(sizeof(arp->a46_data.a46_dummy) % sizeof(*p) == 0); - for (i= 0, p= (u16_t *)arp->a46_data.a46_dummy; - i < sizeof(arp->a46_data.a46_dummy)/sizeof(*p); - i++, p++) - { - *p= 0xdead; - } - - arp->a46_dstaddr= ce->ac_ethaddr; - arp->a46_hdr= HTONS(ARP_ETHERNET); - arp->a46_pro= HTONS(ETH_IP_PROTO); - arp->a46_hln= 6; - arp->a46_pln= 4; - - arp->a46_op= htons(ARP_REPLY); - if (tpa == arp_port->ap_ipaddr) - { - arp->a46_sha= arp_port->ap_ethaddr; - } - else - { - assert(cache); - arp->a46_sha= cache->ac_ethaddr; - } - memcpy (arp->a46_spa, &tpa, sizeof(ipaddr_t)); - arp->a46_tha= ce->ac_ethaddr; - memcpy (arp->a46_tpa, &ce->ac_ipaddr, sizeof(ipaddr_t)); - - assert(data->acc_linkC == 1); - data->acc_ext_link= arp_port->ap_sendlist; - arp_port->ap_sendlist= data; data= NULL; - - if (!(arp_port->ap_flags & APF_ARP_WR_IP)) - setup_write(arp_port); - } -} - -static void client_reply (arp_port, ipaddr, ethaddr) -arp_port_t *arp_port; -ipaddr_t ipaddr; -ether_addr_t *ethaddr; -{ - (*arp_port->ap_arp_func)(arp_port->ap_ip_port, ipaddr, ethaddr); -} - -static arp_cache_t *find_cache_ent (arp_port, ipaddr) -arp_port_t *arp_port; -ipaddr_t ipaddr; -{ - arp_cache_t *ce; - int i; - unsigned hash; - - hash= (ipaddr >> 24) ^ (ipaddr >> 16) ^ (ipaddr >> 8) ^ ipaddr; - hash &= ARP_HASH_MASK; - - ce= arp_hash[hash].ahe_row[0]; - if (ce && ce->ac_ipaddr == ipaddr && ce->ac_port == arp_port && - ce->ac_state != ACS_UNUSED) - { - return ce; - } - for (i= 1; iac_ipaddr != ipaddr || ce->ac_port != arp_port - || ce->ac_state == ACS_UNUSED) - { - continue; - } - arp_hash[hash].ahe_row[i]= arp_hash[hash].ahe_row[0]; - arp_hash[hash].ahe_row[0]= ce; - return ce; - } - - for (i=0, ce= arp_cache; iac_state != ACS_UNUSED && - ce->ac_port == arp_port && - ce->ac_ipaddr == ipaddr) - { - for (i= ARP_HASH_WIDTH-1; i>0; i--) - { - arp_hash[hash].ahe_row[i]= - arp_hash[hash].ahe_row[i-1]; - } - assert(i == 0); - arp_hash[hash].ahe_row[0]= ce; - return ce; - } - } - return NULL; -} - -static arp_cache_t *alloc_cache_ent(flags) -int flags; -{ - arp_cache_t *cache, *old; - int i; - - old= NULL; - for (i=0, cache= arp_cache; iac_state == ACS_UNUSED) - { - old= cache; - break; - } - if (cache->ac_state == ACS_INCOMPLETE) - continue; - if (cache->ac_flags & ACF_PERM) - continue; - if (!old || cache->ac_lastuse < old->ac_lastuse) - old= cache; - } - assert(old); - - if (!flags) - return old; - - /* Get next permanent entry */ - for (i=0, cache= arp_cache; iac_state == ACS_UNUSED) - break; - if (cache->ac_flags & ACF_PERM) - continue; - break; - } - if (i >= arp_cache_nr/2) - return NULL; /* Too many entries */ - if (cache != old) - { - assert(old > cache); - *old= *cache; - old= cache; - } - - if (!(flags & ACF_PUB)) - return old; - - /* Get first nonpublished entry */ - for (i=0, cache= arp_cache; iac_state == ACS_UNUSED) - break; - if (cache->ac_flags & ACF_PUB) - continue; - break; - } - if (cache != old) - { - assert(old > cache); - *old= *cache; - old= cache; - } - return old; -} - -void arp_set_ipaddr (eth_port, ipaddr) -int eth_port; -ipaddr_t ipaddr; -{ - arp_port_t *arp_port; - - if (eth_port < 0 || eth_port >= eth_conf_nr) - return; - arp_port= &arp_port_table[eth_port]; - - arp_port->ap_ipaddr= ipaddr; - arp_port->ap_flags |= APF_INADDR_SET; - arp_port->ap_flags &= ~APF_SUSPEND; - if (arp_port->ap_state == APS_GETADDR) - arp_main(arp_port); -} - -int arp_set_cb(eth_port, ip_port, arp_func) -int eth_port; -int ip_port; -arp_func_t arp_func; -{ - int i; - arp_port_t *arp_port; - - assert(eth_port >= 0); - if (eth_port >= eth_conf_nr) - return ENXIO; - - arp_port= &arp_port_table[eth_port]; - arp_port->ap_eth_port= eth_port; - arp_port->ap_ip_port= ip_port; - arp_port->ap_state= APS_INITIAL; - arp_port->ap_flags= APF_EMPTY; - arp_port->ap_arp_func= arp_func; - arp_port->ap_sendpkt= NULL; - arp_port->ap_sendlist= NULL; - arp_port->ap_reclist= NULL; - for (i= 0; iap_req[i].ar_entry= -1; - arp_port->ap_req[i].ar_timer.tim_active= 0; - } - - ev_init(&arp_port->ap_event); - - arp_main(arp_port); - - return NW_OK; -} - -int arp_ip_eth (eth_port, ipaddr, ethaddr) -int eth_port; -ipaddr_t ipaddr; -ether_addr_t *ethaddr; -{ - int i, ref; - arp_port_t *arp_port; - struct arp_req *reqp; - arp_cache_t *ce; - time_t curr_time; - - assert(eth_port >= 0 && eth_port < eth_conf_nr); - arp_port= &arp_port_table[eth_port]; - assert(arp_port->ap_state == APS_ARPMAIN || - (printf("arp[%d]: ap_state= %d\n", arp_port-arp_port_table, - arp_port->ap_state), 0)); - - curr_time= get_time(); - - ce= find_cache_ent (arp_port, ipaddr); - if (ce && ce->ac_expire < curr_time) - { - assert(ce->ac_state != ACS_INCOMPLETE); - - /* Check whether there is enough space for an ARP - * request or not. - */ - for (i= 0, reqp= arp_port->ap_req; iar_entry < 0) - break; - } - if (i < AP_REQ_NR) - { - /* Okay, expire this entry. */ - ce->ac_state= ACS_UNUSED; - ce= NULL; - } - else - { - /* Continue using this entry for a while */ - printf("arp[%d]: Overloaded! Keeping entry for ", - arp_port-arp_port_table); - writeIpAddr(ipaddr); - printf("\n"); - ce->ac_expire= curr_time+ARP_NOTRCH_EXP_TIME; - } - } - if (ce) - { - /* Found an entry. This entry should be valid, unreachable - * or incomplete. - */ - ce->ac_lastuse= curr_time; - if (ce->ac_state == ACS_VALID) - { - *ethaddr= ce->ac_ethaddr; - return NW_OK; - } - if (ce->ac_state == ACS_UNREACHABLE) - return EHOSTUNREACH; - assert(ce->ac_state == ACS_INCOMPLETE); - - return NW_SUSPEND; - } - - /* Find an empty slot for an ARP request */ - for (i= 0, reqp= arp_port->ap_req; iar_entry < 0) - break; - } - if (i >= AP_REQ_NR) - { - /* We should be able to report that this ARP request - * cannot be accepted. At the moment we just return SUSPEND. - */ - return NW_SUSPEND; - } - ref= (eth_port*AP_REQ_NR + i); - - ce= alloc_cache_ent(ACF_EMPTY); - ce->ac_flags= 0; - ce->ac_state= ACS_INCOMPLETE; - ce->ac_ipaddr= ipaddr; - ce->ac_port= arp_port; - ce->ac_expire= curr_time+ARP_EXP_TIME; - ce->ac_lastuse= curr_time; - - reqp->ar_entry= ce-arp_cache; - reqp->ar_req_count= -1; - - /* Send the first packet by expiring the timer */ - clck_timer(&reqp->ar_timer, 1, arp_timeout, ref); - - return NW_SUSPEND; -} - -int arp_ioctl (eth_port, fd, req, get_userdata, put_userdata) -int eth_port; -int fd; -ioreq_t req; -get_userdata_t get_userdata; -put_userdata_t put_userdata; -{ - arp_port_t *arp_port; - arp_cache_t *ce, *cache; - acc_t *data; - nwio_arp_t *arp_iop; - int entno, result, ac_flags; - u32_t flags; - ipaddr_t ipaddr; - time_t curr_time; - - assert(eth_port >= 0 && eth_port < eth_conf_nr); - arp_port= &arp_port_table[eth_port]; - assert(arp_port->ap_state == APS_ARPMAIN || - (printf("arp[%d]: ap_state= %d\n", arp_port-arp_port_table, - arp_port->ap_state), 0)); - - switch(req) - { - case NWIOARPGIP: - data= (*get_userdata)(fd, 0, sizeof(*arp_iop), TRUE); - if (data == NULL) - return EFAULT; - data= bf_packIffLess(data, sizeof(*arp_iop)); - arp_iop= (nwio_arp_t *)ptr2acc_data(data); - ipaddr= arp_iop->nwa_ipaddr; - ce= NULL; /* lint */ - for (entno= 0; entno < arp_cache_nr; entno++) - { - ce= &arp_cache[entno]; - if (ce->ac_state == ACS_UNUSED || - ce->ac_port != arp_port) - { - continue; - } - if (ce->ac_ipaddr == ipaddr) - break; - } - if (entno == arp_cache_nr) - { - /* Also report the address of this interface */ - if (ipaddr != arp_port->ap_ipaddr) - { - bf_afree(data); - return ENOENT; - } - arp_iop->nwa_entno= arp_cache_nr; - arp_iop->nwa_ipaddr= ipaddr; - arp_iop->nwa_ethaddr= arp_port->ap_ethaddr; - arp_iop->nwa_flags= NWAF_PERM | NWAF_PUB; - } - else - { - arp_iop->nwa_entno= entno+1; - arp_iop->nwa_ipaddr= ce->ac_ipaddr; - arp_iop->nwa_ethaddr= ce->ac_ethaddr; - arp_iop->nwa_flags= 0; - if (ce->ac_state == ACS_INCOMPLETE) - arp_iop->nwa_flags |= NWAF_INCOMPLETE; - if (ce->ac_state == ACS_UNREACHABLE) - arp_iop->nwa_flags |= NWAF_DEAD; - if (ce->ac_flags & ACF_PERM) - arp_iop->nwa_flags |= NWAF_PERM; - if (ce->ac_flags & ACF_PUB) - arp_iop->nwa_flags |= NWAF_PUB; - } - - result= (*put_userdata)(fd, 0, data, TRUE); - return result; - - case NWIOARPGNEXT: - data= (*get_userdata)(fd, 0, sizeof(*arp_iop), TRUE); - if (data == NULL) - return EFAULT; - data= bf_packIffLess(data, sizeof(*arp_iop)); - arp_iop= (nwio_arp_t *)ptr2acc_data(data); - entno= arp_iop->nwa_entno; - if (entno < 0) - entno= 0; - ce= NULL; /* lint */ - for (; entno < arp_cache_nr; entno++) - { - ce= &arp_cache[entno]; - if (ce->ac_state == ACS_UNUSED || - ce->ac_port != arp_port) - { - continue; - } - break; - } - if (entno == arp_cache_nr) - { - bf_afree(data); - return ENOENT; - } - arp_iop->nwa_entno= entno+1; - arp_iop->nwa_ipaddr= ce->ac_ipaddr; - arp_iop->nwa_ethaddr= ce->ac_ethaddr; - arp_iop->nwa_flags= 0; - if (ce->ac_state == ACS_INCOMPLETE) - arp_iop->nwa_flags |= NWAF_INCOMPLETE; - if (ce->ac_state == ACS_UNREACHABLE) - arp_iop->nwa_flags |= NWAF_DEAD; - if (ce->ac_flags & ACF_PERM) - arp_iop->nwa_flags |= NWAF_PERM; - if (ce->ac_flags & ACF_PUB) - arp_iop->nwa_flags |= NWAF_PUB; - - result= (*put_userdata)(fd, 0, data, TRUE); - return result; - - case NWIOARPSIP: - data= (*get_userdata)(fd, 0, sizeof(*arp_iop), TRUE); - if (data == NULL) - return EFAULT; - data= bf_packIffLess(data, sizeof(*arp_iop)); - arp_iop= (nwio_arp_t *)ptr2acc_data(data); - ipaddr= arp_iop->nwa_ipaddr; - if (find_cache_ent(arp_port, ipaddr)) - { - bf_afree(data); - return EEXIST; - } - - flags= arp_iop->nwa_flags; - ac_flags= ACF_EMPTY; - if (flags & NWAF_PERM) - ac_flags |= ACF_PERM; - if (flags & NWAF_PUB) - ac_flags |= ACF_PUB|ACF_PERM; - - /* Allocate a cache entry */ - ce= alloc_cache_ent(ac_flags); - if (ce == NULL) - { - bf_afree(data); - return ENOMEM; - } - - ce->ac_flags= ac_flags; - ce->ac_state= ACS_VALID; - ce->ac_ethaddr= arp_iop->nwa_ethaddr; - ce->ac_ipaddr= arp_iop->nwa_ipaddr; - ce->ac_port= arp_port; - - curr_time= get_time(); - ce->ac_expire= curr_time+ARP_EXP_TIME; - ce->ac_lastuse= curr_time; - - bf_afree(data); - return 0; - - case NWIOARPDIP: - data= (*get_userdata)(fd, 0, sizeof(*arp_iop), TRUE); - if (data == NULL) - return EFAULT; - data= bf_packIffLess(data, sizeof(*arp_iop)); - arp_iop= (nwio_arp_t *)ptr2acc_data(data); - ipaddr= arp_iop->nwa_ipaddr; - bf_afree(data); data= NULL; - ce= find_cache_ent(arp_port, ipaddr); - if (!ce) - return ENOENT; - if (ce->ac_state == ACS_INCOMPLETE) - return EINVAL; - - ac_flags= ce->ac_flags; - if (ac_flags & ACF_PUB) - { - /* Make sure entry is at the end of published - * entries. - */ - for (entno= 0, cache= arp_cache; - entnoac_state == ACS_UNUSED) - break; - if (cache->ac_flags & ACF_PUB) - continue; - break; - } - assert(cache > arp_cache); - cache--; - if (cache != ce) - { - assert(cache > ce); - *ce= *cache; - ce= cache; - } - } - if (ac_flags & ACF_PERM) - { - /* Make sure entry is at the end of permanent - * entries. - */ - for (entno= 0, cache= arp_cache; - entnoac_state == ACS_UNUSED) - break; - if (cache->ac_flags & ACF_PERM) - continue; - break; - } - assert(cache > arp_cache); - cache--; - if (cache != ce) - { - assert(cache > ce); - *ce= *cache; - ce= cache; - } - } - - /* Clear entry */ - ce->ac_state= ACS_UNUSED; - - return 0; - - default: - ip_panic(("arp_ioctl: unknown request 0x%lx", - (unsigned long)req)); - } - return 0; -} - -static void arp_timeout (ref, timer) -int ref; -minix_timer_t *timer; -{ - int i, port, reqind, acind; - arp_port_t *arp_port; - arp_cache_t *ce; - struct arp_req *reqp; - time_t curr_time; - acc_t *data; - arp46_t *arp; - u16_t *p; - - port= ref / AP_REQ_NR; - reqind= ref % AP_REQ_NR; - - assert(port >= 0 && port ap_req[reqind]; - assert (timer == &reqp->ar_timer); - - acind= reqp->ar_entry; - - assert(acind >= 0 && acind < arp_cache_nr); - ce= &arp_cache[acind]; - - assert(ce->ac_port == arp_port); - assert(ce->ac_state == ACS_INCOMPLETE); - - if (++reqp->ar_req_count >= MAX_ARP_RETRIES) - { - curr_time= get_time(); - ce->ac_state= ACS_UNREACHABLE; - ce->ac_expire= curr_time+ ARP_NOTRCH_EXP_TIME; - ce->ac_lastuse= curr_time; - - clck_untimer(&reqp->ar_timer); - reqp->ar_entry= -1; - client_reply(arp_port, ce->ac_ipaddr, NULL); - return; - } - - data= bf_memreq(sizeof(arp46_t)); - arp= (arp46_t *)ptr2acc_data(data); - - /* Clear padding */ - assert(sizeof(arp->a46_data.a46_dummy) % sizeof(*p) == 0); - for (i= 0, p= (u16_t *)arp->a46_data.a46_dummy; - i < sizeof(arp->a46_data.a46_dummy)/sizeof(*p); - i++, p++) - { - *p= 0xdead; - } - - arp->a46_dstaddr.ea_addr[0]= 0xff; - arp->a46_dstaddr.ea_addr[1]= 0xff; - arp->a46_dstaddr.ea_addr[2]= 0xff; - arp->a46_dstaddr.ea_addr[3]= 0xff; - arp->a46_dstaddr.ea_addr[4]= 0xff; - arp->a46_dstaddr.ea_addr[5]= 0xff; - arp->a46_hdr= HTONS(ARP_ETHERNET); - arp->a46_pro= HTONS(ETH_IP_PROTO); - arp->a46_hln= 6; - arp->a46_pln= 4; - arp->a46_op= HTONS(ARP_REQUEST); - arp->a46_sha= arp_port->ap_ethaddr; - memcpy (arp->a46_spa, &arp_port->ap_ipaddr, sizeof(ipaddr_t)); - memset(&arp->a46_tha, '\0', sizeof(ether_addr_t)); - memcpy (arp->a46_tpa, &ce->ac_ipaddr, sizeof(ipaddr_t)); - - assert(data->acc_linkC == 1); - data->acc_ext_link= arp_port->ap_sendlist; - arp_port->ap_sendlist= data; data= NULL; - - if (!(arp_port->ap_flags & APF_ARP_WR_IP)) - setup_write(arp_port); - - clck_timer(&reqp->ar_timer, get_time() + ARP_TIMEOUT, - arp_timeout, ref); -} - -static void arp_buffree(priority) -int priority; -{ - int i; - acc_t *pack, *next_pack; - arp_port_t *arp_port; - - for (i= 0, arp_port= arp_port_table; iap_reclist; - while(next_pack && next_pack->acc_ext_link) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - if (next_pack) - { - if (ev_in_queue(&arp_port->ap_event)) - { - DBLOCK(1, printf( - "not freeing ap_reclist, ap_event enqueued\n")); - } - else - { - bf_afree(next_pack); - next_pack= NULL; - } - } - arp_port->ap_reclist= next_pack; - } - if (priority == ARP_PRI_SEND) - { - next_pack= arp_port->ap_sendlist; - while(next_pack && next_pack->acc_ext_link) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - if (next_pack) - { - if (ev_in_queue(&arp_port->ap_event)) - { - DBLOCK(1, printf( - "not freeing ap_sendlist, ap_event enqueued\n")); - } - else - { - bf_afree(next_pack); - next_pack= NULL; - } - } - arp_port->ap_sendlist= next_pack; - } - } -} - -#ifdef BUF_CONSISTENCY_CHECK -static void arp_bufcheck() -{ - int i; - arp_port_t *arp_port; - acc_t *pack; - - for (i= 0, arp_port= arp_port_table; iap_reclist; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - for (pack= arp_port->ap_sendlist; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - } -} -#endif /* BUF_CONSISTENCY_CHECK */ - -/* - * $PchId: arp.c,v 1.22 2005/06/28 14:15:06 philip Exp $ - */ diff --git a/minix/net/inet/generic/arp.h b/minix/net/inet/generic/arp.h deleted file mode 100644 index 1edfe5394..000000000 --- a/minix/net/inet/generic/arp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -arp.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef ARP_H -#define ARP_H - -#define ARP_ETHERNET 1 - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -/* Prototypes */ -typedef void (*arp_func_t) ARGS(( int fd, ipaddr_t ipaddr, - ether_addr_t *ethaddr )); - -void arp_prep ARGS(( void )); -void arp_init ARGS(( void )); -void arp_set_ipaddr ARGS(( int eth_port, ipaddr_t ipaddr )); -int arp_set_cb ARGS(( int eth_port, int ip_port, arp_func_t arp_func )); -int arp_ip_eth ARGS(( int eth_port, ipaddr_t ipaddr, ether_addr_t *ethaddr )); - -int arp_ioctl ARGS(( int eth_port, int fd, ioreq_t req, - get_userdata_t get_userdata, put_userdata_t put_userdata )); - -#endif /* ARP_H */ - -/* - * $PchId: arp.h,v 1.7 2001/04/19 18:58:17 philip Exp $ - */ diff --git a/minix/net/inet/generic/assert.h b/minix/net/inet/generic/assert.h deleted file mode 100644 index 7c5418d22..000000000 --- a/minix/net/inet/generic/assert.h +++ /dev/null @@ -1,30 +0,0 @@ - -#include - -/* -assert.h - -Copyright 1995 Philip Homburg -*/ -#ifndef INET_ASSERT_H -#define INET_ASSERT_H - -#if !NDEBUG - -void bad_assertion(char *file, int line, char *what) _NORETURN; -void bad_compare(char *file, int line, int lhs, char *what, int rhs) _NORETURN; - -#define compare(a,t,b) assert((a) t (b)) - -#else /* NDEBUG */ - -#define compare(a,t,b) 0 - -#endif /* NDEBUG */ - -#endif /* INET_ASSERT_H */ - - -/* - * $PchId: assert.h,v 1.8 2002/03/18 21:50:32 philip Exp $ - */ diff --git a/minix/net/inet/generic/buf.h b/minix/net/inet/generic/buf.h deleted file mode 100644 index 49a0838b4..000000000 --- a/minix/net/inet/generic/buf.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -buf.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef BUF_H -#define BUF_H - -/* Note: BUF_S should be defined in const.h */ - -#define MAX_BUFREQ_PRI 10 - -#define ARP_PRI_REC 3 -#define ARP_PRI_SEND 3 - -#define ETH_PRI_PORTBUFS 3 -#define ETH_PRI_FDBUFS_EXTRA 5 -#define ETH_PRI_FDBUFS 6 - -#define IP_PRI_PORTBUFS 3 -#define IP_PRI_ASSBUFS 4 -#define IP_PRI_FDBUFS_EXTRA 5 -#define IP_PRI_FDBUFS 6 - -#define ICMP_PRI_QUEUE 1 - -#define TCP_PRI_FRAG2SEND 4 -#define TCP_PRI_CONN_EXTRA 5 -#define TCP_PRI_CONNwoUSER 7 -#define TCP_PRI_CONN_INUSE 9 - -#define UDP_PRI_FDBUFS_EXTRA 5 -#define UDP_PRI_FDBUFS 6 - -#define PSIP_PRI_EXP_PROMISC 2 - -struct acc; -typedef void (*buffree_t) ARGS(( struct acc *acc )); -typedef void (*bf_freereq_t) ARGS(( int priority )); - -#ifdef BUF_CONSISTENCY_CHECK -typedef void (*bf_checkreq_t) ARGS(( void )); -#endif - -typedef struct buf -{ - int buf_linkC; - buffree_t buf_free; - size_t buf_size; - char *buf_data_p; - -#ifdef BUF_TRACK_ALLOC_FREE - char *buf_alloc_file; - int buf_alloc_line; - char *buf_free_file; - int buf_free_line; -#endif -#ifdef BUF_CONSISTENCY_CHECK - unsigned buf_generation; - int buf_check_linkC; -#endif -} buf_t; - -typedef struct acc -{ - int acc_linkC; - int acc_offset, acc_length; - buf_t *acc_buffer; - struct acc *acc_next, *acc_ext_link; - -#ifdef BUF_TRACK_ALLOC_FREE - char *acc_alloc_file; - int acc_alloc_line; - char *acc_free_file; - int acc_free_line; -#endif -#ifdef BUF_CONSISTENCY_CHECK - unsigned acc_generation; - int acc_check_linkC; -#endif -} acc_t; - -extern acc_t *bf_temporary_acc; -extern acc_t *bf_linkcheck_acc; - -/* For debugging... */ - -#ifdef BUF_TRACK_ALLOC_FREE - -#ifndef BUF_IMPLEMENTATION - -#define bf_memreq(a) _bf_memreq(this_file, __LINE__, a) -#define bf_cut(a,b,c) _bf_cut(this_file, __LINE__, a, b, c) -#define bf_delhead(a,b) _bf_delhead(this_file, __LINE__, a, b) -#define bf_packIffLess(a,b) _bf_packIffLess(this_file, __LINE__, \ - a, b) -#define bf_afree(a) _bf_afree(this_file, __LINE__, a) -#define bf_pack(a) _bf_pack(this_file, __LINE__, a) -#define bf_append(a,b) _bf_append(this_file, __LINE__, a, b) -#define bf_dupacc(a) _bf_dupacc(this_file, __LINE__, a) -#if 0 -#define bf_mark_1acc(a) _bf_mark_1acc(this_file, __LINE__, a) -#define bf_mark_acc(a) _bf_mark_acc(this_file, __LINE__, a) -#endif -#define bf_align(a,s,al) _bf_align(this_file, __LINE__, a, s, al) - -#else /* BUF_IMPLEMENTATION */ - -#define bf_afree(a) _bf_afree(clnt_file, clnt_line, a) -#define bf_pack(a) _bf_pack(clnt_file, clnt_line, a) -#define bf_memreq(a) _bf_memreq(clnt_file, clnt_line, a) -#define bf_dupacc(a) _bf_dupacc(clnt_file, clnt_line, a) -#define bf_cut(a,b,c) _bf_cut(clnt_file, clnt_line, a, b, c) -#define bf_delhead(a,b) _bf_delhead(clnt_file, clnt_line, a, b) -#define bf_align(a,s,al) _bf_align(clnt_file, clnt_line, a, s, al) - -#endif /* !BUF_IMPLEMENTATION */ - -#else - -#define bf_mark_1acc(acc) ((void)0) -#define bf_mark_acc(acc) ((void)0) - -#endif /* BUF_TRACK_ALLOC_FREE */ - -/* Prototypes */ - -void bf_init ARGS(( void )); -#ifndef BUF_CONSISTENCY_CHECK -void bf_logon ARGS(( bf_freereq_t func )); -#else -void bf_logon ARGS(( bf_freereq_t func, bf_checkreq_t checkfunc )); -#endif - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_memreq ARGS(( size_t size)); -#else -acc_t *_bf_memreq ARGS(( char *clnt_file, int clnt_line, - size_t size)); -#endif -/* the result is an acc with linkC == 1 */ - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_dupacc ARGS(( acc_t *acc )); -#else -acc_t *_bf_dupacc ARGS(( char *clnt_file, int clnt_line, - acc_t *acc )); -#endif -/* the result is an acc with linkC == 1 identical to the given one */ - -#ifndef BUF_TRACK_ALLOC_FREE -void bf_afree ARGS(( acc_t *acc)); -#else -void _bf_afree ARGS(( char *clnt_file, int clnt_line, - acc_t *acc)); -#endif -/* this reduces the linkC off the given acc with one */ - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_pack ARGS(( acc_t *pack)); -#else -acc_t *_bf_pack ARGS(( char *clnt_file, int clnt_line, - acc_t *pack)); -#endif -/* this gives a packed copy of the given acc, the linkC of the given acc is - reduced by one, the linkC of the result == 1 */ - -#ifndef BUF_TRACK_ALLOC_FREE -acc_t *bf_packIffLess ARGS(( acc_t *pack, int min_len )); -#else -acc_t *_bf_packIffLess ARGS(( char *clnt_file, int clnt_line, - acc_t *pack, int min_len )); -#endif -/* this performs a bf_pack iff pack->acc_lengthacc_buffer-> \ - buf_data_p[((acc_t *)(a))->acc_offset]) - -#define bf_chkbuf(buf) ((buf)? (compare((buf)->acc_linkC,>,0), \ - compare((buf)->acc_buffer, !=, 0), \ - compare((buf)->acc_buffer->buf_linkC,>,0)) : (void)0) - -#ifdef BUF_CONSISTENCY_CHECK -int bf_consistency_check ARGS(( void )); -void bf_check_acc ARGS(( acc_t *acc )); -void _bf_mark_1acc ARGS(( char *clnt_file, int clnt_line, acc_t *acc )); -void _bf_mark_acc ARGS(( char *clnt_file, int clnt_line, acc_t *acc )); -#endif - -#endif /* BUF_H */ - -/* - * $PchId: buf.h,v 1.13 2003/09/10 08:52:09 philip Exp $ - */ diff --git a/minix/net/inet/generic/clock.h b/minix/net/inet/generic/clock.h deleted file mode 100644 index 61d4232ed..000000000 --- a/minix/net/inet/generic/clock.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -clock.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef CLOCK_H -#define CLOCK_H - -struct minix_timer; - -typedef void (*timer_func_t) ARGS(( int fd, struct minix_timer *timer )); - -typedef struct minix_timer -{ - struct minix_timer *tim_next; - timer_func_t tim_func; - int tim_ref; - time_t tim_time; - int tim_active; -} minix_timer_t; - -extern int clck_call_expire; /* Call clck_expire_timer from the mainloop */ - -void clck_init ARGS(( void )); -void set_time ARGS(( clock_t time )); -time_t get_time ARGS(( void )); -void reset_time ARGS(( void )); -/* set a timer to go off at the time specified by timeout */ -void clck_timer ARGS(( minix_timer_t *timer, time_t timeout, timer_func_t func, - int fd )); -void clck_untimer ARGS(( minix_timer_t *timer )); -void clck_expire_timers ARGS(( void )); - -#endif /* CLOCK_H */ - -/* - * $PchId: clock.h,v 1.5 1995/11/21 06:45:27 philip Exp $ - */ diff --git a/minix/net/inet/generic/eth.c b/minix/net/inet/generic/eth.c deleted file mode 100644 index 4b8e228a2..000000000 --- a/minix/net/inet/generic/eth.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* -eth.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "osdep_eth.h" -#include "type.h" - -#include "assert.h" -#include "buf.h" -#include "eth.h" -#include "eth_int.h" -#include "sr.h" - -THIS_FILE - -#define ETH_FD_NR (4*IP_PORT_MAX) -#define EXPIRE_TIME 60*HZ /* seconds */ - -typedef struct eth_fd -{ - int ef_flags; - nwio_ethopt_t ef_ethopt; - eth_port_t *ef_port; - struct eth_fd *ef_type_next; - struct eth_fd *ef_send_next; - int ef_srfd; - acc_t *ef_rdbuf_head; - acc_t *ef_rdbuf_tail; - get_userdata_t ef_get_userdata; - put_userdata_t ef_put_userdata; - put_pkt_t ef_put_pkt; - select_res_t ef_select_res; - time_t ef_exp_time; - size_t ef_write_count; - ioreq_t ef_ioctl_req; -} eth_fd_t; - -#define EFF_FLAGS 0xf -# define EFF_EMPTY 0x0 -# define EFF_INUSE 0x1 -# define EFF_BUSY 0xE -# define EFF_READ_IP 0x2 -# define EFF_WRITE_IP 0x4 -# define EFF_IOCTL_IP 0x8 -# define EFF_OPTSET 0x10 -# define EFF_SEL_READ 0x20 - -/* Note that the vh_type field is normally considered part of the ethernet - * header. - */ -typedef struct -{ - u16_t vh_type; - u16_t vh_vlan; -} vlan_hdr_t; - -static int eth_checkopt ARGS(( eth_fd_t *eth_fd )); -static void hash_fd ARGS(( eth_fd_t *eth_fd )); -static void unhash_fd ARGS(( eth_fd_t *eth_fd )); -static void eth_buffree ARGS(( int priority )); -#ifdef BUF_CONSISTENCY_CHECK -static void eth_bufcheck ARGS(( void )); -#endif -static int eth_sel_read ARGS(( eth_fd_t * )); -static void packet2user ARGS(( eth_fd_t *fd, acc_t *pack, time_t exp_time )); -static void reply_thr_get ARGS(( eth_fd_t *eth_fd, - size_t result, int for_ioctl )); -static void reply_thr_put ARGS(( eth_fd_t *eth_fd, - size_t result, int for_ioctl )); -static void do_rec_conf ARGS(( eth_port_t *eth_port )); -static u32_t compute_rec_conf ARGS(( eth_port_t *eth_port )); -static acc_t *insert_vlan_hdr ARGS(( eth_port_t *eth_port, acc_t *pack )); - -eth_port_t *eth_port_table; -int no_ethWritePort= 0; - -static eth_fd_t eth_fd_table[ETH_FD_NR]; -static ether_addr_t broadcast= { { 255, 255, 255, 255, 255, 255 } }; - -void eth_prep() -{ - eth_port_table= alloc(eth_conf_nr * sizeof(eth_port_table[0])); -} - -void eth_init() -{ - int i, j; - - assert (BUF_S >= sizeof(nwio_ethopt_t)); - assert (BUF_S >= ETH_HDR_SIZE); /* these are in fact static assertions, - thus a good compiler doesn't - generate any code for this */ - - - for (i=0; ietp_flags & EPF_ENABLED)) - return EGENERIC; - - for (i=0; i=ETH_FD_NR) - { - DBLOCK(1, printf("out of fds\n")); - return EAGAIN; - } - - eth_fd= ð_fd_table[i]; - - eth_fd->ef_flags= EFF_INUSE; - eth_fd->ef_ethopt.nweo_flags=NWEO_DEFAULT; - eth_fd->ef_port= eth_port; - eth_fd->ef_srfd= srfd; - assert(eth_fd->ef_rdbuf_head == NULL); - eth_fd->ef_get_userdata= get_userdata; - eth_fd->ef_put_userdata= put_userdata; - eth_fd->ef_put_pkt= put_pkt; - eth_fd->ef_select_res= select_res; - - return i; -} - -int eth_ioctl(fd, req) -int fd; -ioreq_t req; -{ - acc_t *data; - eth_fd_t *eth_fd; - eth_port_t *eth_port; - - DBLOCK(0x20, printf("eth_ioctl (%d, 0x%lx)\n", fd, (unsigned long)req)); - eth_fd= ð_fd_table[fd]; - eth_port= eth_fd->ef_port; - - assert (eth_fd->ef_flags & EFF_INUSE); - - switch (req) - { - case NWIOSETHOPT: - { - nwio_ethopt_t *ethopt; - nwio_ethopt_t oldopt, newopt; - int result; - u32_t new_en_flags, new_di_flags, - old_en_flags, old_di_flags; - - data= (*eth_fd->ef_get_userdata)(eth_fd-> - ef_srfd, 0, sizeof(nwio_ethopt_t), TRUE); - - ethopt= (nwio_ethopt_t *)ptr2acc_data(data); - oldopt= eth_fd->ef_ethopt; - newopt= *ethopt; - - old_en_flags= oldopt.nweo_flags & 0xffff; - old_di_flags= (oldopt.nweo_flags >> 16) & 0xffff; - new_en_flags= newopt.nweo_flags & 0xffff; - new_di_flags= (newopt.nweo_flags >> 16) & 0xffff; - if (new_en_flags & new_di_flags) - { - bf_afree(data); - reply_thr_get (eth_fd, EBADMODE, TRUE); - return NW_OK; - } - - /* NWEO_ACC_MASK */ - if (new_di_flags & NWEO_ACC_MASK) - { - bf_afree(data); - reply_thr_get (eth_fd, EBADMODE, TRUE); - return NW_OK; - } - /* you can't disable access modes */ - - if (!(new_en_flags & NWEO_ACC_MASK)) - new_en_flags |= (old_en_flags & NWEO_ACC_MASK); - - - /* NWEO_LOC_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_LOC_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_LOC_MASK); - new_di_flags |= (old_di_flags & NWEO_LOC_MASK); - } - - /* NWEO_BROAD_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_BROAD_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_BROAD_MASK); - new_di_flags |= (old_di_flags & NWEO_BROAD_MASK); - } - - /* NWEO_MULTI_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_MULTI_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_MULTI_MASK); - new_di_flags |= (old_di_flags & NWEO_MULTI_MASK); - newopt.nweo_multi= oldopt.nweo_multi; - } - - /* NWEO_PROMISC_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_PROMISC_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_PROMISC_MASK); - new_di_flags |= (old_di_flags & NWEO_PROMISC_MASK); - } - - /* NWEO_REM_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_REM_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_REM_MASK); - new_di_flags |= (old_di_flags & NWEO_REM_MASK); - newopt.nweo_rem= oldopt.nweo_rem; - } - - /* NWEO_TYPE_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_TYPE_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_TYPE_MASK); - new_di_flags |= (old_di_flags & NWEO_TYPE_MASK); - newopt.nweo_type= oldopt.nweo_type; - } - - /* NWEO_RW_MASK */ - if (!((new_en_flags | new_di_flags) & NWEO_RW_MASK)) - { - new_en_flags |= (old_en_flags & NWEO_RW_MASK); - new_di_flags |= (old_di_flags & NWEO_RW_MASK); - } - - if (eth_fd->ef_flags & EFF_OPTSET) - unhash_fd(eth_fd); - - newopt.nweo_flags= ((unsigned long)new_di_flags << 16) | - new_en_flags; - eth_fd->ef_ethopt= newopt; - - result= eth_checkopt(eth_fd); - - if (result<0) - eth_fd->ef_ethopt= oldopt; - else - { - unsigned long opt_flags; - unsigned changes; - opt_flags= oldopt.nweo_flags ^ - eth_fd->ef_ethopt.nweo_flags; - changes= ((opt_flags >> 16) | opt_flags) & - 0xffff; - if (changes & (NWEO_BROAD_MASK | - NWEO_MULTI_MASK | NWEO_PROMISC_MASK)) - { - do_rec_conf(eth_port); - } - } - - if (eth_fd->ef_flags & EFF_OPTSET) - hash_fd(eth_fd); - - bf_afree(data); - reply_thr_get (eth_fd, result, TRUE); - return NW_OK; - } - - case NWIOGETHOPT: - { - nwio_ethopt_t *ethopt; - acc_t *acc; - int result; - - acc= bf_memreq(sizeof(nwio_ethopt_t)); - - ethopt= (nwio_ethopt_t *)ptr2acc_data(acc); - - *ethopt= eth_fd->ef_ethopt; - - result= (*eth_fd->ef_put_userdata)(eth_fd-> - ef_srfd, 0, acc, TRUE); - if (result >= 0) - reply_thr_put(eth_fd, NW_OK, TRUE); - return result; - } - case NWIOGETHSTAT: - { - nwio_ethstat_t *ethstat; - acc_t *acc; - int result; - - assert (sizeof(nwio_ethstat_t) <= BUF_S); - - eth_port= eth_fd->ef_port; - if (!(eth_port->etp_flags & EPF_ENABLED)) - { - reply_thr_put(eth_fd, EGENERIC, TRUE); - return NW_OK; - } - - if (!(eth_port->etp_flags & EPF_GOT_ADDR)) - { -#if 0 - printf( - "eth_ioctl: suspending NWIOGETHSTAT ioctl\n"); -#endif - - eth_fd->ef_ioctl_req= req; - assert(!(eth_fd->ef_flags & EFF_IOCTL_IP)); - eth_fd->ef_flags |= EFF_IOCTL_IP; - return NW_SUSPEND; - } - - if (eth_port->etp_getstat) - { - printf( - "eth_ioctl: pending eth_get_stat request, suspending caller\n"); - assert(!(eth_fd->ef_flags & EFF_IOCTL_IP)); - eth_fd->ef_flags |= EFF_IOCTL_IP; - return NW_SUSPEND; - } - - acc= bf_memreq(sizeof(nwio_ethstat_t)); - compare (bf_bufsize(acc), ==, sizeof(*ethstat)); - - ethstat= (nwio_ethstat_t *)ptr2acc_data(acc); - ethstat->nwes_addr= eth_port->etp_ethaddr; - - if (!eth_port->etp_vlan) - { - result= eth_get_stat(eth_port, - ðstat->nwes_stat); - if (result == SUSPEND) - { -#if 0 - printf( - "eth_ioctl: eth_get_stat returned SUSPEND\n"); -#endif - eth_fd->ef_ioctl_req= req; - assert(!(eth_fd->ef_flags & - EFF_IOCTL_IP)); - eth_fd->ef_flags |= EFF_IOCTL_IP; -#if 0 -printf("eth_ioctl: setting etp_getstat in port %d to %p\n", - eth_port-eth_port_table, acc); -#endif - eth_port->etp_getstat= acc; - acc= NULL; - return NW_SUSPEND; - } - if (result != NW_OK) - { - bf_afree(acc); - reply_thr_put(eth_fd, result, TRUE); - return NW_OK; - } - } - else - { - /* No statistics */ - memset(ðstat->nwes_stat, '\0', - sizeof(ethstat->nwes_stat)); - } - - result= (*eth_fd->ef_put_userdata)(eth_fd-> - ef_srfd, 0, acc, TRUE); - if (result >= 0) - reply_thr_put(eth_fd, NW_OK, TRUE); - return result; - } - default: - break; - } - reply_thr_put(eth_fd, ENOTTY, TRUE); - return NW_OK; -} - -int eth_write(fd, count) -int fd; -size_t count; -{ - eth_fd_t *eth_fd; - eth_port_t *eth_port, *rep; - acc_t *user_data; - int r; - - eth_fd= ð_fd_table[fd]; - eth_port= eth_fd->ef_port; - - if (!(eth_fd->ef_flags & EFF_OPTSET)) - { - reply_thr_get (eth_fd, EBADMODE, FALSE); - return NW_OK; - } - - assert (!(eth_fd->ef_flags & EFF_WRITE_IP)); - - eth_fd->ef_write_count= count; - if (eth_fd->ef_ethopt.nweo_flags & NWEO_RWDATONLY) - count += ETH_HDR_SIZE; - - if (countETH_MAX_PACK_SIZE) - { - DBLOCK(1, printf("illegal packetsize (%d)\n",count)); - reply_thr_get (eth_fd, EPACKSIZE, FALSE); - return NW_OK; - } - eth_fd->ef_flags |= EFF_WRITE_IP; - - /* Enqueue at the real ethernet port */ - rep= eth_port->etp_vlan_port; - if (!rep) - rep= eth_port; - if (rep->etp_wr_pack) - { - eth_fd->ef_send_next= NULL; - if (rep->etp_sendq_head) - rep->etp_sendq_tail->ef_send_next= eth_fd; - else - rep->etp_sendq_head= eth_fd; - rep->etp_sendq_tail= eth_fd; - return NW_SUSPEND; - } - - user_data= (*eth_fd->ef_get_userdata)(eth_fd->ef_srfd, 0, - eth_fd->ef_write_count, FALSE); - if (!user_data) - { - eth_fd->ef_flags &= ~EFF_WRITE_IP; - reply_thr_get (eth_fd, EFAULT, FALSE); - return NW_OK; - } - r= eth_send(fd, user_data, eth_fd->ef_write_count); - assert(r == NW_OK); - - eth_fd->ef_flags &= ~EFF_WRITE_IP; - reply_thr_get(eth_fd, eth_fd->ef_write_count, FALSE); - return NW_OK; -} - -int eth_send(fd, data, data_len) -int fd; -acc_t *data; -size_t data_len; -{ - eth_fd_t *eth_fd; - eth_port_t *eth_port, *rep; - eth_hdr_t *eth_hdr; - acc_t *eth_pack; - unsigned long nweo_flags; - size_t count; - ev_arg_t ev_arg; - - eth_fd= ð_fd_table[fd]; - eth_port= eth_fd->ef_port; - - if (!(eth_fd->ef_flags & EFF_OPTSET)) - return EBADMODE; - - count= data_len; - if (eth_fd->ef_ethopt.nweo_flags & NWEO_RWDATONLY) - count += ETH_HDR_SIZE; - - if (countETH_MAX_PACK_SIZE) - { - DBLOCK(1, printf("illegal packetsize (%d)\n",count)); - return EPACKSIZE; - } - rep= eth_port->etp_vlan_port; - if (!rep) - rep= eth_port; - - if (rep->etp_wr_pack) - return NW_WOULDBLOCK; - - nweo_flags= eth_fd->ef_ethopt.nweo_flags; - if (nweo_flags & NWEO_RWDATONLY) - { - eth_pack= bf_memreq(ETH_HDR_SIZE); - eth_pack->acc_next= data; - } - else - eth_pack= bf_packIffLess(data, ETH_HDR_SIZE); - - eth_hdr= (eth_hdr_t *)ptr2acc_data(eth_pack); - - if (nweo_flags & NWEO_REMSPEC) - eth_hdr->eh_dst= eth_fd->ef_ethopt.nweo_rem; - - if (!(eth_port->etp_flags & EPF_GOT_ADDR)) - { - /* No device, discard packet */ - bf_afree(eth_pack); - return NW_OK; - } - - if (!(nweo_flags & NWEO_EN_PROMISC)) - eth_hdr->eh_src= eth_port->etp_ethaddr; - - if (nweo_flags & NWEO_TYPESPEC) - eth_hdr->eh_proto= eth_fd->ef_ethopt.nweo_type; - - if (eth_addrcmp(eth_hdr->eh_dst, eth_port->etp_ethaddr) == 0) - { - /* Local loopback. */ - eth_port->etp_wr_pack= eth_pack; - ev_arg.ev_ptr= eth_port; - ev_enqueue(ð_port->etp_sendev, eth_loop_ev, ev_arg); - return NW_OK; - } - - if (rep != eth_port) - { - eth_pack= insert_vlan_hdr(eth_port, eth_pack); - if (!eth_pack) - { - /* Packet is silently discarded */ - return NW_OK; - } - } - - eth_write_port(rep, eth_pack); - return NW_OK; -} - -int eth_read (fd, count) -int fd; -size_t count; -{ - eth_fd_t *eth_fd; - acc_t *pack; - - eth_fd= ð_fd_table[fd]; - if (!(eth_fd->ef_flags & EFF_OPTSET)) - { - reply_thr_put(eth_fd, EBADMODE, FALSE); - return NW_OK; - } - if (count < ETH_MAX_PACK_SIZE) - { - reply_thr_put(eth_fd, EPACKSIZE, FALSE); - return NW_OK; - } - - assert(!(eth_fd->ef_flags & EFF_READ_IP)); - eth_fd->ef_flags |= EFF_READ_IP; - - while (eth_fd->ef_rdbuf_head) - { - pack= eth_fd->ef_rdbuf_head; - eth_fd->ef_rdbuf_head= pack->acc_ext_link; - if (get_time() <= eth_fd->ef_exp_time) - { - packet2user(eth_fd, pack, eth_fd->ef_exp_time); - if (!(eth_fd->ef_flags & EFF_READ_IP)) - return NW_OK; - } - else - bf_afree(pack); - } - return NW_SUSPEND; -} - -int eth_cancel(fd, which_operation) -int fd; -int which_operation; -{ - eth_fd_t *eth_fd, *prev, *loc_fd; - eth_port_t *eth_port; - - DBLOCK(2, printf("eth_cancel (%d)\n", fd)); - eth_fd= ð_fd_table[fd]; - - switch (which_operation) - { - case SR_CANCEL_READ: - assert (eth_fd->ef_flags & EFF_READ_IP); - eth_fd->ef_flags &= ~EFF_READ_IP; - reply_thr_put(eth_fd, EINTR, FALSE); - break; - case SR_CANCEL_WRITE: - assert (eth_fd->ef_flags & EFF_WRITE_IP); - eth_fd->ef_flags &= ~EFF_WRITE_IP; - - /* Remove fd from send queue */ - eth_port= eth_fd->ef_port; - if (eth_port->etp_vlan_port) - eth_port= eth_port->etp_vlan_port; - for (prev= 0, loc_fd= eth_port->etp_sendq_head; loc_fd != NULL; - prev= loc_fd, loc_fd= loc_fd->ef_send_next) - { - if (loc_fd == eth_fd) - break; - } - assert(loc_fd == eth_fd); - if (prev == NULL) - eth_port->etp_sendq_head= loc_fd->ef_send_next; - else - prev->ef_send_next= loc_fd->ef_send_next; - if (loc_fd->ef_send_next == NULL) - eth_port->etp_sendq_tail= prev; - - reply_thr_get(eth_fd, EINTR, FALSE); - break; - case SR_CANCEL_IOCTL: - assert (eth_fd->ef_flags & EFF_IOCTL_IP); - eth_fd->ef_flags &= ~EFF_IOCTL_IP; - reply_thr_get(eth_fd, EINTR, TRUE); - break; - default: - ip_panic(( "got unknown cancel request" )); - } - return NW_OK; -} - -int eth_select(fd, operations) -int fd; -unsigned operations; -{ - unsigned resops; - eth_fd_t *eth_fd; - - eth_fd= ð_fd_table[fd]; - assert (eth_fd->ef_flags & EFF_INUSE); - - resops= 0; - - if (operations & SR_SELECT_READ) - { - if (eth_sel_read(eth_fd)) - resops |= SR_SELECT_READ; - else if (!(operations & SR_SELECT_POLL)) - eth_fd->ef_flags |= EFF_SEL_READ; - } - if (operations & SR_SELECT_WRITE) - { - /* Should handle special case when the interface is down */ - resops |= SR_SELECT_WRITE; - } - if (operations & SR_SELECT_EXCEPTION) - { - /* Nothing */ - } - return resops; -} - -void eth_close(fd) -int fd; -{ - eth_fd_t *eth_fd; - eth_port_t *eth_port; - acc_t *pack; - - eth_fd= ð_fd_table[fd]; - - assert ((eth_fd->ef_flags & EFF_INUSE) && - !(eth_fd->ef_flags & EFF_BUSY)); - - if (eth_fd->ef_flags & EFF_OPTSET) - unhash_fd(eth_fd); - while (eth_fd->ef_rdbuf_head != NULL) - { - pack= eth_fd->ef_rdbuf_head; - eth_fd->ef_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - eth_fd->ef_flags= EFF_EMPTY; - - eth_port= eth_fd->ef_port; - do_rec_conf(eth_port); -} - -void eth_loop_ev(ev, ev_arg) -event_t *ev; -ev_arg_t ev_arg; -{ - acc_t *pack; - eth_port_t *eth_port; - - eth_port= ev_arg.ev_ptr; - assert(ev == ð_port->etp_sendev); - - pack= eth_port->etp_wr_pack; - - assert(!no_ethWritePort); - no_ethWritePort= 1; - eth_arrive(eth_port, pack, bf_bufsize(pack)); - assert(no_ethWritePort); - no_ethWritePort= 0; - - eth_port->etp_wr_pack= NULL; - eth_restart_write(eth_port); -} - -static int eth_checkopt (eth_fd) -eth_fd_t *eth_fd; -{ -/* bug: we don't check access modes yet */ - - unsigned long flags; - unsigned int en_di_flags; - acc_t *pack; - - flags= eth_fd->ef_ethopt.nweo_flags; - en_di_flags= (flags >>16) | (flags & 0xffff); - - if ((en_di_flags & NWEO_ACC_MASK) && - (en_di_flags & NWEO_LOC_MASK) && - (en_di_flags & NWEO_BROAD_MASK) && - (en_di_flags & NWEO_MULTI_MASK) && - (en_di_flags & NWEO_PROMISC_MASK) && - (en_di_flags & NWEO_REM_MASK) && - (en_di_flags & NWEO_TYPE_MASK) && - (en_di_flags & NWEO_RW_MASK)) - { - eth_fd->ef_flags |= EFF_OPTSET; - } - else - eth_fd->ef_flags &= ~EFF_OPTSET; - - while (eth_fd->ef_rdbuf_head != NULL) - { - pack= eth_fd->ef_rdbuf_head; - eth_fd->ef_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - - return NW_OK; -} - -static void hash_fd(eth_fd) -eth_fd_t *eth_fd; -{ - eth_port_t *eth_port; - int hash; - - eth_port= eth_fd->ef_port; - if (eth_fd->ef_ethopt.nweo_flags & NWEO_TYPEANY) - { - eth_fd->ef_type_next= eth_port->etp_type_any; - eth_port->etp_type_any= eth_fd; - } - else - { - hash= eth_fd->ef_ethopt.nweo_type; - hash ^= (hash >> 8); - hash &= (ETH_TYPE_HASH_NR-1); - - eth_fd->ef_type_next= eth_port->etp_type[hash]; - eth_port->etp_type[hash]= eth_fd; - } -} - -static void unhash_fd(eth_fd) -eth_fd_t *eth_fd; -{ - eth_port_t *eth_port; - eth_fd_t *prev, *curr, **eth_fd_p; - int hash; - - eth_port= eth_fd->ef_port; - if (eth_fd->ef_ethopt.nweo_flags & NWEO_TYPEANY) - { - eth_fd_p= ð_port->etp_type_any; - } - else - { - hash= eth_fd->ef_ethopt.nweo_type; - hash ^= (hash >> 8); - hash &= (ETH_TYPE_HASH_NR-1); - - eth_fd_p= ð_port->etp_type[hash]; - } - for (prev= NULL, curr= *eth_fd_p; curr; - prev= curr, curr= curr->ef_type_next) - { - if (curr == eth_fd) - break; - } - assert(curr); - if (prev) - prev->ef_type_next= curr->ef_type_next; - else - *eth_fd_p= curr->ef_type_next; -} - -void eth_restart_write(eth_port) -eth_port_t *eth_port; -{ - eth_fd_t *eth_fd; - int r; - - assert(eth_port->etp_wr_pack == NULL); - while (eth_fd= eth_port->etp_sendq_head, eth_fd != NULL) - { - if (eth_port->etp_wr_pack) - return; - eth_port->etp_sendq_head= eth_fd->ef_send_next; - - assert(eth_fd->ef_flags & EFF_WRITE_IP); - eth_fd->ef_flags &= ~EFF_WRITE_IP; - r= eth_write(eth_fd-eth_fd_table, eth_fd->ef_write_count); - assert(r == NW_OK); - } -} - -void eth_arrive (eth_port, pack, pack_size) -eth_port_t *eth_port; -acc_t *pack; -size_t pack_size; -{ - - eth_hdr_t *eth_hdr; - ether_addr_t *dst_addr; - int pack_stat; - ether_type_t type; - eth_fd_t *eth_fd, *first_fd, *share_fd; - int hash, i; - u16_t vlan, temp; - time_t exp_time; - acc_t *vlan_pack, *hdr_acc, *tmp_acc; - eth_port_t *vp; - vlan_hdr_t vh; - u32_t *p; - - exp_time= get_time() + EXPIRE_TIME; - - pack= bf_packIffLess(pack, ETH_HDR_SIZE); - - eth_hdr= (eth_hdr_t*)ptr2acc_data(pack); - dst_addr= ð_hdr->eh_dst; - - DIFBLOCK(0x20, dst_addr->ea_addr[0] != 0xFF && - (dst_addr->ea_addr[0] & 0x1), - printf("got multicast packet\n")); - - if (dst_addr->ea_addr[0] & 0x1) - { - /* multi cast or broadcast */ - if (eth_addrcmp(*dst_addr, broadcast) == 0) - pack_stat= NWEO_EN_BROAD; - else - pack_stat= NWEO_EN_MULTI; - } - else - { - assert(eth_port->etp_flags & EPF_GOT_ADDR); - if (eth_addrcmp (*dst_addr, eth_port->etp_ethaddr) == 0) - pack_stat= NWEO_EN_LOC; - else - pack_stat= NWEO_EN_PROMISC; - } - type= eth_hdr->eh_proto; - hash= type; - hash ^= (hash >> 8); - hash &= (ETH_TYPE_HASH_NR-1); - - if (type == HTONS(ETH_VLAN_PROTO)) - { - /* VLAN packet. Extract original ethernet packet */ - - vlan_pack= pack; - vlan_pack->acc_linkC++; - hdr_acc= bf_cut(vlan_pack, 0, 2*sizeof(ether_addr_t)); - vlan_pack= bf_delhead(vlan_pack, 2*sizeof(ether_addr_t)); - vlan_pack= bf_packIffLess(vlan_pack, sizeof(vh)); - vh= *(vlan_hdr_t *)ptr2acc_data(vlan_pack); - vlan_pack= bf_delhead(vlan_pack, sizeof(vh)); - hdr_acc= bf_append(hdr_acc, vlan_pack); - vlan_pack= hdr_acc; hdr_acc= NULL; - if (bf_bufsize(vlan_pack) < ETH_MIN_PACK_SIZE) - { - tmp_acc= bf_memreq(sizeof(vh)); - - /* Clear padding */ - assert(sizeof(vh) <= sizeof(*p)); - p= (u32_t *)ptr2acc_data(tmp_acc); - *p= 0xdeadbeef; - - vlan_pack= bf_append(vlan_pack, tmp_acc); - tmp_acc= NULL; - } - vlan= ntohs(vh.vh_vlan); - if (vlan & ETH_TCI_CFI) - { - /* No support for extended address formats */ - bf_afree(vlan_pack); vlan_pack= NULL; - } - vlan &= ETH_TCI_VLAN_MASK; - } - else - { - /* No VLAN processing */ - vlan_pack= NULL; - vlan= 0; /* lint */ - } - - first_fd= NULL; - for (i= 0; i<2; i++) - { - share_fd= NULL; - - eth_fd= (i == 0) ? eth_port->etp_type_any : - eth_port->etp_type[hash]; - for (; eth_fd; eth_fd= eth_fd->ef_type_next) - { - if (i && eth_fd->ef_ethopt.nweo_type != type) - continue; - if (!(eth_fd->ef_ethopt.nweo_flags & pack_stat)) - continue; - if (eth_fd->ef_ethopt.nweo_flags & NWEO_REMSPEC && - eth_addrcmp(eth_hdr->eh_src, - eth_fd->ef_ethopt.nweo_rem) != 0) - { - continue; - } - if ((eth_fd->ef_ethopt.nweo_flags & NWEO_ACC_MASK) == - NWEO_SHARED) - { - if (!share_fd) - { - share_fd= eth_fd; - continue; - } - if (!eth_fd->ef_rdbuf_head) - share_fd= eth_fd; - continue; - } - if (!first_fd) - { - first_fd= eth_fd; - continue; - } - pack->acc_linkC++; - packet2user(eth_fd, pack, exp_time); - } - if (share_fd) - { - pack->acc_linkC++; - packet2user(share_fd, pack, exp_time); - } - } - if (first_fd) - { - if (first_fd->ef_put_pkt && - (first_fd->ef_flags & EFF_READ_IP) && - !(first_fd->ef_ethopt.nweo_flags & NWEO_RWDATONLY)) - { - (*first_fd->ef_put_pkt)(first_fd->ef_srfd, pack, - pack_size); - } - else - packet2user(first_fd, pack, exp_time); - } - else - { - if (pack_stat == NWEO_EN_LOC) - { - DBLOCK(0x01, - printf("eth_arrive: dropping packet for proto 0x%x\n", - ntohs(type))); - } - else - { - DBLOCK(0x20, printf("dropping packet for proto 0x%x\n", - ntohs(type))); - } - bf_afree(pack); - } - if (vlan_pack) - { - hash= ETH_HASH_VLAN(vlan, temp); - for (vp= eth_port->etp_vlan_tab[hash]; vp; - vp= vp->etp_vlan_next) - { - if (vp->etp_vlan == vlan) - break; - } - if (vp) - { - eth_arrive(vp, vlan_pack, pack_size-sizeof(vh)); - vlan_pack= NULL; - } - else - { - /* No device for VLAN */ - bf_afree(vlan_pack); - vlan_pack= NULL; - } - } -} - -void eth_reg_vlan(eth_port, vlan_port) -eth_port_t *eth_port; -eth_port_t *vlan_port; -{ - u16_t t, vlan; - int h; - - vlan= vlan_port->etp_vlan; - h= ETH_HASH_VLAN(vlan, t); - vlan_port->etp_vlan_next= eth_port->etp_vlan_tab[h]; - eth_port->etp_vlan_tab[h]= vlan_port; -} - -void eth_restart_ioctl(eth_port) -eth_port_t *eth_port; -{ - int i, r; - eth_fd_t *eth_fd; - acc_t *acc; - -#if 0 - printf("in eth_restart_ioctl\n"); -#endif - - /* eth_restart_ioctl is called on too occasions: when a device - * driver registers with inet and when a eth_get_stat call has - * completed. We assume the second option when etp_getstat is - * not equal to zero at the start of the call. - */ - acc= eth_port->etp_getstat; - - for (i= 0, eth_fd= eth_fd_table; ief_flags & EFF_INUSE)) - continue; - if (eth_fd->ef_port != eth_port) - continue; - if (!(eth_fd->ef_flags & EFF_IOCTL_IP)) - continue; - if (eth_fd->ef_ioctl_req != NWIOGETHSTAT) - continue; - -#if 0 -printf("eth_restart_ioctl: etp_getstat in port %d is %p\n", - eth_port-eth_port_table, acc); -#endif - - if (acc != NULL) - { -#if 0 - printf("eth_restart_ioctl: completed getstat\n"); -#endif - acc->acc_linkC++; - r= (*eth_fd->ef_put_userdata)(eth_fd->ef_srfd, 0, - acc, TRUE); - if (r >= 0) - reply_thr_put(eth_fd, NW_OK, TRUE); - eth_fd->ef_flags &= ~EFF_IOCTL_IP; - continue; - } - - { static int count; if (++count > 5) ip_panic(("too many restarts")); } - - eth_fd->ef_flags &= ~EFF_IOCTL_IP; - eth_ioctl(i, eth_fd->ef_ioctl_req); - } - - if (acc != NULL) - { -#if 0 -printf("eth_restart_ioctl: clearing etp_getstat in port %d\n", - eth_port-eth_port_table); -#endif - assert(acc == eth_port->etp_getstat); - - bf_afree(acc); - eth_port->etp_getstat= NULL; - } -} - -static int eth_sel_read (eth_fd) -eth_fd_t *eth_fd; -{ - acc_t *tmp_acc, *next_acc; - - if (!(eth_fd->ef_flags & EFF_OPTSET)) - return 1; /* Read will not block */ - - if (eth_fd->ef_rdbuf_head) - { - if (get_time() <= eth_fd->ef_exp_time) - return 1; - - tmp_acc= eth_fd->ef_rdbuf_head; - while (tmp_acc) - { - next_acc= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - tmp_acc= next_acc; - } - eth_fd->ef_rdbuf_head= NULL; - } - return 0; -} - -static void packet2user (eth_fd, pack, exp_time) -eth_fd_t *eth_fd; -acc_t *pack; -time_t exp_time; -{ - int result; - acc_t *tmp_pack; - size_t size; - - assert (eth_fd->ef_flags & EFF_INUSE); - if (!(eth_fd->ef_flags & EFF_READ_IP)) - { - if (pack->acc_linkC != 1) - { - tmp_pack= bf_dupacc(pack); - bf_afree(pack); - pack= tmp_pack; - tmp_pack= NULL; - } - pack->acc_ext_link= NULL; - if (eth_fd->ef_rdbuf_head == NULL) - { - eth_fd->ef_rdbuf_head= pack; - eth_fd->ef_exp_time= exp_time; - } - else - eth_fd->ef_rdbuf_tail->acc_ext_link= pack; - eth_fd->ef_rdbuf_tail= pack; - - if (eth_fd->ef_flags & EFF_SEL_READ) - { - eth_fd->ef_flags &= ~EFF_SEL_READ; - if (eth_fd->ef_select_res) - eth_fd->ef_select_res(eth_fd->ef_srfd, SR_SELECT_READ); - else - printf("packet2user: no select_res\n"); - } - return; - } - - if (eth_fd->ef_ethopt.nweo_flags & NWEO_RWDATONLY) - pack= bf_delhead(pack, ETH_HDR_SIZE); - - size= bf_bufsize(pack); - - if (eth_fd->ef_put_pkt) - { - (*eth_fd->ef_put_pkt)(eth_fd->ef_srfd, pack, size); - return; - } - - eth_fd->ef_flags &= ~EFF_READ_IP; - result= (*eth_fd->ef_put_userdata)(eth_fd->ef_srfd, (size_t)0, pack, - FALSE); - if (result >=0) - reply_thr_put(eth_fd, size, FALSE); - else - reply_thr_put(eth_fd, result, FALSE); -} - -static void eth_buffree (priority) -int priority; -{ - int i; - eth_fd_t *eth_fd; - acc_t *pack; - - if (priority == ETH_PRI_FDBUFS_EXTRA) - { - for (i= 0, eth_fd= eth_fd_table; ief_rdbuf_head && - eth_fd->ef_rdbuf_head->acc_ext_link) - { - pack= eth_fd->ef_rdbuf_head; - eth_fd->ef_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - } - } - if (priority == ETH_PRI_FDBUFS) - { - for (i= 0, eth_fd= eth_fd_table; ief_rdbuf_head) - { - pack= eth_fd->ef_rdbuf_head; - eth_fd->ef_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - } - } -} - -#ifdef BUF_CONSISTENCY_CHECK -static void eth_bufcheck() -{ - int i; - eth_fd_t *eth_fd; - acc_t *pack; - - for (i= 0; ief_rdbuf_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - } -} -#endif - -static void do_rec_conf(eth_port) -eth_port_t *eth_port; -{ - int i; - u32_t flags; - eth_port_t *vp; - - assert(eth_port); - - if (eth_port->etp_vlan) - { - /* Configure underlying device */ - eth_port= eth_port->etp_vlan_port; - } - flags= compute_rec_conf(eth_port); - for (i= 0; ietp_vlan_tab[i]; vp; vp= vp->etp_vlan_next) - flags |= compute_rec_conf(vp); - } - eth_set_rec_conf(eth_port, flags); -} - -static u32_t compute_rec_conf(eth_port) -eth_port_t *eth_port; -{ - eth_fd_t *eth_fd; - u32_t flags; - int i; - - flags= NWEO_NOFLAGS; - for (i=0, eth_fd= eth_fd_table; ief_flags & (EFF_INUSE|EFF_OPTSET)) != - (EFF_INUSE|EFF_OPTSET)) - { - continue; - } - if (eth_fd->ef_port != eth_port) - continue; - flags |= eth_fd->ef_ethopt.nweo_flags; - } - return flags; -} - -static void reply_thr_get (eth_fd, result, for_ioctl) -eth_fd_t *eth_fd; -size_t result; -int for_ioctl; -{ - acc_t *data; - - data= (*eth_fd->ef_get_userdata)(eth_fd->ef_srfd, result, 0, for_ioctl); - assert (!data); -} - -static void reply_thr_put (eth_fd, result, for_ioctl) -eth_fd_t *eth_fd; -size_t result; -int for_ioctl; -{ - int error; - - error= (*eth_fd->ef_put_userdata)(eth_fd->ef_srfd, result, (acc_t *)0, - for_ioctl); - assert(error == NW_OK); -} - -static acc_t *insert_vlan_hdr(eth_port, pack) -eth_port_t *eth_port; -acc_t *pack; -{ - acc_t *head_acc, *vh_acc; - u16_t type, vlan; - vlan_hdr_t *vp; - - head_acc= bf_cut(pack, 0, 2*sizeof(ether_addr_t)); - pack= bf_delhead(pack, 2*sizeof(ether_addr_t)); - pack= bf_packIffLess(pack, sizeof(type)); - type= *(u16_t *)ptr2acc_data(pack); - if (type == HTONS(ETH_VLAN_PROTO)) - { - /* Packeted is already tagged. Should update vlan number. - * For now, just discard packet. - */ - printf("insert_vlan_hdr: discarding vlan packet\n"); - bf_afree(head_acc); head_acc= NULL; - bf_afree(pack); pack= NULL; - return NULL; - } - vlan= eth_port->etp_vlan; /* priority and CFI are zero */ - - vh_acc= bf_memreq(sizeof(vlan_hdr_t)); - vp= (vlan_hdr_t *)ptr2acc_data(vh_acc); - vp->vh_type= HTONS(ETH_VLAN_PROTO); - vp->vh_vlan= htons(vlan); - - head_acc= bf_append(head_acc, vh_acc); vh_acc= NULL; - head_acc= bf_append(head_acc, pack); pack= NULL; - pack= head_acc; head_acc= NULL; - return pack; -} - -/* - * $PchId: eth.c,v 1.23 2005/06/28 14:15:58 philip Exp $ - */ diff --git a/minix/net/inet/generic/eth.h b/minix/net/inet/generic/eth.h deleted file mode 100644 index 8c0be61da..000000000 --- a/minix/net/inet/generic/eth.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -eth.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef ETH_H -#define ETH_H - -#define NWEO_DEFAULT (NWEO_EN_LOC | NWEO_DI_BROAD | NWEO_DI_MULTI | \ - NWEO_DI_PROMISC | NWEO_REMANY | NWEO_RWDATALL) - -#define eth_addrcmp(a,b) (memcmp((void *)&a, (void *)&b, \ - sizeof(a))) - -/* Forward declatations */ - -struct acc; - -/* prototypes */ - -void eth_prep ARGS(( void )); -void eth_init ARGS(( void )); -int eth_open ARGS(( int port, int srfd, - get_userdata_t get_userdata, put_userdata_t put_userdata, - put_pkt_t put_pkt, select_res_t sel_res )); -int eth_ioctl ARGS(( int fd, ioreq_t req)); -int eth_read ARGS(( int port, size_t count )); -int eth_write ARGS(( int port, size_t count )); -int eth_cancel ARGS(( int fd, int which_operation )); -int eth_select ARGS(( int fd, unsigned operations )); -void eth_close ARGS(( int fd )); -int eth_send ARGS(( int port, struct acc *data, size_t data_len )); - -#endif /* ETH_H */ - -/* - * $PchId: eth.h,v 1.8 2005/06/28 14:16:10 philip Exp $ - */ diff --git a/minix/net/inet/generic/eth_int.h b/minix/net/inet/generic/eth_int.h deleted file mode 100644 index b8354dbb7..000000000 --- a/minix/net/inet/generic/eth_int.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -eth_int.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef ETH_INT_H -#define ETH_INT_H - -#define ETH_TYPE_HASH_NR 16 -#define ETH_VLAN_HASH_NR 16 - -/* Assume that the arguments are a local variable */ -#define ETH_HASH_VLAN(v,t) \ - ((t)= (((v) >> 8) ^ (v)), \ - (t)= (((t) >> 4) ^ (t)), \ - (t) & (ETH_VLAN_HASH_NR-1)) - -typedef struct eth_port -{ - int etp_flags; - ether_addr_t etp_ethaddr; - acc_t *etp_wr_pack, *etp_rd_pack; - acc_t *etp_getstat; - struct eth_fd *etp_sendq_head; - struct eth_fd *etp_sendq_tail; - struct eth_fd *etp_type_any; - struct eth_fd *etp_type[ETH_TYPE_HASH_NR]; - event_t etp_sendev; - - /* VLAN support */ - u16_t etp_vlan; - struct eth_port *etp_vlan_port; - struct eth_port *etp_vlan_tab[ETH_VLAN_HASH_NR]; - struct eth_port *etp_vlan_next; - - osdep_eth_port_t etp_osdep; -} eth_port_t; - -#define EPF_EMPTY 0x0 -#define EPF_ENABLED 0x1 -#define EPF_GOT_ADDR 0x2 /* Got ethernet address from device */ -#define EPF_READ_IP 0x20 -#define EPF_READ_SP 0x40 - -extern eth_port_t *eth_port_table; - -extern int no_ethWritePort; /* debug, consistency check */ - -void osdep_eth_init ARGS(( void )); -int eth_get_stat ARGS(( eth_port_t *eth_port, eth_stat_t *eth_stat )); -void eth_write_port ARGS(( eth_port_t *eth_port, acc_t *pack )); -void eth_arrive ARGS(( eth_port_t *port, acc_t *pack, size_t pack_size )); -void eth_set_rec_conf ARGS(( eth_port_t *eth_port, u32_t flags )); -void eth_restart_write ARGS(( eth_port_t *eth_port )); -void eth_loop_ev ARGS(( event_t *ev, ev_arg_t ev_arg )); -void eth_reg_vlan ARGS(( eth_port_t *eth_port, eth_port_t *vlan_port )); -void eth_restart_ioctl ARGS(( eth_port_t *eth_port )); - -#endif /* ETH_INT_H */ - -/* - * $PchId: eth_int.h,v 1.9 2001/04/23 08:04:06 philip Exp $ - */ diff --git a/minix/net/inet/generic/event.c b/minix/net/inet/generic/event.c deleted file mode 100644 index e59d97706..000000000 --- a/minix/net/inet/generic/event.c +++ /dev/null @@ -1,69 +0,0 @@ -/* -inet/generic/event.c - -Created: April 1995 by Philip Homburg - -Implementation of an event queue. - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "assert.h" -#include "event.h" - -THIS_FILE - -event_t *ev_head; -static event_t *ev_tail; - -void ev_init(ev) -event_t *ev; -{ - ev->ev_func= 0; - ev->ev_next= NULL; -} - -void ev_enqueue(ev, func, ev_arg) -event_t *ev; -ev_func_t func; -ev_arg_t ev_arg; -{ - assert(ev->ev_func == 0); - ev->ev_func= func; - ev->ev_arg= ev_arg; - ev->ev_next= NULL; - if (ev_head == NULL) - ev_head= ev; - else - ev_tail->ev_next= ev; - ev_tail= ev; -} - -void ev_process() -{ - ev_func_t func; - event_t *curr; - - while (ev_head) - { - curr= ev_head; - ev_head= curr->ev_next; - func= curr->ev_func; - curr->ev_func= 0; - - assert(func != 0); - func(curr, curr->ev_arg); - } -} - -int ev_in_queue(ev) -event_t *ev; -{ - return ev->ev_func != 0; -} - - -/* - * $PchId: event.c,v 1.6 2004/08/03 16:23:32 philip Exp $ - */ diff --git a/minix/net/inet/generic/event.h b/minix/net/inet/generic/event.h deleted file mode 100644 index f5afed7fa..000000000 --- a/minix/net/inet/generic/event.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -inet/generic/event.h - -Created: April 1995 by Philip Homburg - -Header file for an event mechanism. - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__GENERIC__EVENT_H -#define INET__GENERIC__EVENT_H - -struct event; - -typedef struct ev_arg -{ - void *ev_ptr; -} ev_arg_t; - -typedef void (*ev_func_t) ARGS(( struct event *ev, ev_arg_t eva )); - -typedef struct event -{ - ev_func_t ev_func; - ev_arg_t ev_arg; - struct event *ev_next; -} event_t; - -extern event_t *ev_head; - -void ev_init ARGS(( event_t *ev )); -void ev_enqueue ARGS(( event_t *ev, ev_func_t func, ev_arg_t ev_arg )); -void ev_process ARGS(( void )); -int ev_in_queue ARGS(( event_t *ev )); - -#endif /* INET__GENERIC__EVENT_H */ - -/* - * $PchId: event.h,v 1.5 2004/08/03 16:23:49 philip Exp $ - */ diff --git a/minix/net/inet/generic/icmp.c b/minix/net/inet/generic/icmp.c deleted file mode 100644 index edb97a39a..000000000 --- a/minix/net/inet/generic/icmp.c +++ /dev/null @@ -1,1227 +0,0 @@ -/* -icmp.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "event.h" -#include "type.h" - -#include "assert.h" -#include "clock.h" -#include "icmp.h" -#include "icmp_lib.h" -#include "io.h" -#include "ip.h" -#include "ip_int.h" -#include "ipr.h" - -THIS_FILE - -typedef struct icmp_port -{ - int icp_flags; - int icp_state; - int icp_ipport; - int icp_ipfd; - unsigned icp_rate_count; - unsigned icp_rate_report; - time_t icp_rate_lasttime; - acc_t *icp_head_queue; - acc_t *icp_tail_queue; - acc_t *icp_write_pack; - event_t icp_event; -} icmp_port_t; - -#define ICPF_EMPTY 0x0 -#define ICPF_SUSPEND 0x1 -#define ICPF_READ_IP 0x2 -#define ICPF_READ_SP 0x4 -#define ICPF_WRITE_IP 0x8 -#define ICPF_WRITE_SP 0x10 - -#define ICPS_BEGIN 0 -#define ICPS_IPOPT 1 -#define ICPS_MAIN 2 -#define ICPS_ERROR 3 - -static icmp_port_t *icmp_port_table; - -static void icmp_main ARGS(( icmp_port_t *icmp_port )); -static acc_t *icmp_getdata ARGS(( int port, size_t offset, - size_t count, int for_ioctl )); -static int icmp_putdata ARGS(( int port, size_t offset, - acc_t *data, int for_ioctl )); -static void icmp_read ARGS(( icmp_port_t *icmp_port )); -static void process_data ARGS(( icmp_port_t *icmp_port, - acc_t *data )); -static u16_t icmp_pack_oneCsum ARGS(( acc_t *ip_pack )); -static void icmp_echo_request ARGS(( icmp_port_t *icmp_port, - acc_t *ip_pack, int ip_hdr_len, ip_hdr_t *ip_hdr, - acc_t *icmp_pack, int icmp_len, icmp_hdr_t *icmp_hdr )); -static void icmp_dst_unreach ARGS(( icmp_port_t *icmp_port, - acc_t *ip_pack, int ip_hdr_len, ip_hdr_t *ip_hdr, - acc_t *icmp_pack, int icmp_len, icmp_hdr_t *icmp_hdr )); -static void icmp_time_exceeded ARGS(( icmp_port_t *icmp_port, - acc_t *ip_pack, int ip_hdr_len, ip_hdr_t *ip_hdr, - acc_t *icmp_pack, int icmp_len, icmp_hdr_t *icmp_hdr )); -static void icmp_router_advertisement ARGS(( icmp_port_t *icmp_port, - acc_t *icmp_pack, int icmp_len, icmp_hdr_t *icmp_hdr )); -static void icmp_redirect ARGS(( icmp_port_t *icmp_port, - ip_hdr_t *ip_hdr, acc_t *icmp_pack, int icmp_len, - icmp_hdr_t *icmp_hdr )); -static acc_t *make_repl_ip ARGS(( ip_hdr_t *ip_hdr, - int ip_len )); -static void enqueue_pack ARGS(( icmp_port_t *icmp_port, - acc_t *reply_ip_hdr )); -static int icmp_rate_limit ARGS(( icmp_port_t *icmp_port, - acc_t *reply_ip_hdr )); -static void icmp_write ARGS(( event_t *ev, ev_arg_t ev_arg )); -static void icmp_buffree ARGS(( int priority )); -static acc_t *icmp_err_pack ARGS(( acc_t *pack, icmp_hdr_t **icmp_hdr_pp )); -#ifdef BUF_CONSISTENCY_CHECK -static void icmp_bufcheck ARGS(( void )); -#endif - -void icmp_prep() -{ - icmp_port_table= alloc(ip_conf_nr * sizeof(icmp_port_table[0])); -} - -void icmp_init() -{ - int i; - icmp_port_t *icmp_port; - - assert (BUF_S >= sizeof (nwio_ipopt_t)); - - for (i= 0, icmp_port= icmp_port_table; iicp_flags= ICPF_EMPTY; - icmp_port->icp_state= ICPS_BEGIN; - icmp_port->icp_ipport= i; - icmp_port->icp_rate_count= 0; - icmp_port->icp_rate_report= ICMP_MAX_RATE; - icmp_port->icp_rate_lasttime= 0; - ev_init(&icmp_port->icp_event); - } - -#ifndef BUF_CONSISTENCY_CHECK - bf_logon(icmp_buffree); -#else - bf_logon(icmp_buffree, icmp_bufcheck); -#endif - - for (i= 0, icmp_port= icmp_port_table; iicp_state) - { - case ICPS_BEGIN: - icmp_port->icp_head_queue= 0; - icmp_port->icp_ipfd= ip_open(icmp_port->icp_ipport, - icmp_port->icp_ipport, icmp_getdata, icmp_putdata, - 0 /* no put_pkt */, 0 /* no select_res */); - if (icmp_port->icp_ipfd<0) - { - DBLOCK(1, printf("unable to open ip_port %d\n", - icmp_port->icp_ipport)); - break; - } - icmp_port->icp_state= ICPS_IPOPT; - icmp_port->icp_flags &= ~ICPF_SUSPEND; - result= ip_ioctl (icmp_port->icp_ipfd, NWIOSIPOPT); - if (result == NW_SUSPEND) - { - icmp_port->icp_flags |= ICPF_SUSPEND; - break; - } - assert(result == NW_OK); - - /* falls through */ - case ICPS_IPOPT: - icmp_port->icp_state= ICPS_MAIN; - icmp_port->icp_flags &= ~ICPF_SUSPEND; - icmp_read(icmp_port); - break; - default: - DBLOCK(1, printf("unknown state %d\n", - icmp_port->icp_state)); - break; - } -} - -static acc_t *icmp_getdata(port, offset, count, for_ioctl) -int port; -size_t offset, count; -int for_ioctl; -{ - icmp_port_t *icmp_port; - nwio_ipopt_t *ipopt; - acc_t *data; - int result; - ev_arg_t ev_arg; - - icmp_port= &icmp_port_table[port]; - - if (icmp_port->icp_flags & ICPF_WRITE_IP) - { - if (!count) - { - bf_afree(icmp_port->icp_write_pack); - icmp_port->icp_write_pack= 0; - - result= (int)offset; - if (result<0) - { - DBLOCK(1, printf("got write error %d\n", - result)); - } - if (icmp_port->icp_flags & ICPF_WRITE_SP) - { - icmp_port->icp_flags &= ~ICPF_WRITE_SP; - ev_arg.ev_ptr= icmp_port; - ev_enqueue(&icmp_port->icp_event, icmp_write, - ev_arg); - } - return NW_OK; - } - return bf_cut(icmp_port->icp_write_pack, offset, count); - } - switch (icmp_port->icp_state) - { - case ICPS_IPOPT: - if (!count) - { - result= (int)offset; - assert(result == NW_OK); - if (result < 0) - { - icmp_port->icp_state= ICPS_ERROR; - break; - } - if (icmp_port->icp_flags & ICPF_SUSPEND) - icmp_main(icmp_port); - return NW_OK; - } - - data= bf_memreq (sizeof (*ipopt)); - ipopt= (nwio_ipopt_t *)ptr2acc_data(data); - ipopt->nwio_flags= NWIO_COPY | NWIO_EN_LOC | - NWIO_EN_BROAD | - NWIO_REMANY | NWIO_PROTOSPEC | - NWIO_HDR_O_ANY | NWIO_RWDATALL; - ipopt->nwio_proto= IPPROTO_ICMP; - return data; - default: - break; - } - DBLOCK(1, printf("unknown state %d\n", icmp_port->icp_state)); - return NULL; -} - -static int icmp_putdata(port, offset, data, for_ioctl) -int port; -size_t offset; -acc_t *data; -int for_ioctl; -{ - icmp_port_t *icmp_port; - int result; - - icmp_port= &icmp_port_table[port]; - - if (icmp_port->icp_flags & ICPF_READ_IP) - { - if (!data) - { - result= (int)offset; - if (result<0) - { - DBLOCK(1, printf("got read error %d\n", - result)); - } - if (icmp_port->icp_flags & ICPF_READ_SP) - { - icmp_port->icp_flags &= - ~(ICPF_READ_IP|ICPF_READ_SP); - icmp_read (icmp_port); - } - return NW_OK; - } - process_data(icmp_port, data); - return NW_OK; - } - switch (icmp_port->icp_state) - { - default: - DBLOCK(1, printf("unknown state %d\n", - icmp_port->icp_state)); - return 0; - } -} - -static void icmp_read(icmp_port) -icmp_port_t *icmp_port; -{ - int result; - - for (;;) - { - icmp_port->icp_flags |= ICPF_READ_IP; - icmp_port->icp_flags &= ~ICPF_READ_SP; - - result= ip_read(icmp_port->icp_ipfd, ICMP_MAX_DATAGRAM); - if (result == NW_SUSPEND) - { - icmp_port->icp_flags |= ICPF_READ_SP; - return; - } - } -} - -void icmp_snd_time_exceeded(port_nr, pack, code) -int port_nr; -acc_t *pack; -int code; -{ - icmp_hdr_t *icmp_hdr; - icmp_port_t *icmp_port; - - if (port_nr >= 0 && port_nr < ip_conf_nr) - icmp_port= &icmp_port_table[port_nr]; - else - { - printf("icmp_snd_time_exceeded: strange port %d\n", port_nr); - bf_afree(pack); - return; - } - pack= icmp_err_pack(pack, &icmp_hdr); - if (pack == NULL) - return; - icmp_hdr->ih_type= ICMP_TYPE_TIME_EXCEEDED; - icmp_hdr->ih_code= code; - icmp_hdr->ih_chksum= ~oneC_sum(~icmp_hdr->ih_chksum, - (u16_t *)&icmp_hdr->ih_type, 2); - enqueue_pack(icmp_port, pack); -} - -void icmp_snd_redirect(port_nr, pack, code, gw) -int port_nr; -acc_t *pack; -int code; -ipaddr_t gw; -{ - icmp_hdr_t *icmp_hdr; - icmp_port_t *icmp_port; - - if (port_nr >= 0 && port_nr < ip_conf_nr) - icmp_port= &icmp_port_table[port_nr]; - else - { - printf("icmp_snd_redirect: strange port %d\n", port_nr); - bf_afree(pack); - return; - } - pack= icmp_err_pack(pack, &icmp_hdr); - if (pack == NULL) - return; - icmp_hdr->ih_type= ICMP_TYPE_REDIRECT; - icmp_hdr->ih_code= code; - icmp_hdr->ih_hun.ihh_gateway= gw; - icmp_hdr->ih_chksum= ~oneC_sum(~icmp_hdr->ih_chksum, - (u16_t *)&icmp_hdr->ih_type, 2); - icmp_hdr->ih_chksum= ~oneC_sum(~icmp_hdr->ih_chksum, - (u16_t *)&icmp_hdr->ih_hun.ihh_gateway, 4); - enqueue_pack(icmp_port, pack); -} - -void icmp_snd_unreachable(port_nr, pack, code) -int port_nr; -acc_t *pack; -int code; -{ - icmp_hdr_t *icmp_hdr; - icmp_port_t *icmp_port; - - if (port_nr >= 0 && port_nr < ip_conf_nr) - icmp_port= &icmp_port_table[port_nr]; - else - { - printf("icmp_snd_unreachable: strange port %d\n", port_nr); - bf_afree(pack); - return; - } - pack= icmp_err_pack(pack, &icmp_hdr); - if (pack == NULL) - return; - icmp_hdr->ih_type= ICMP_TYPE_DST_UNRCH; - icmp_hdr->ih_code= code; - icmp_hdr->ih_chksum= ~oneC_sum(~icmp_hdr->ih_chksum, - (u16_t *)&icmp_hdr->ih_type, 2); - enqueue_pack(icmp_port, pack); -} - -void icmp_snd_mtu( - int port_nr, - acc_t *pack, - u16_t mtu -) -{ - icmp_hdr_t *icmp_hdr; - icmp_port_t *icmp_port; - - if (port_nr >= 0 && port_nr < ip_conf_nr) - icmp_port= &icmp_port_table[port_nr]; - else - { - printf("icmp_snd_mtu: strange port %d\n", port_nr); - bf_afree(pack); - return; - } - - pack= icmp_err_pack(pack, &icmp_hdr); - if (pack == NULL) - return; - icmp_hdr->ih_type= ICMP_TYPE_DST_UNRCH; - icmp_hdr->ih_code= ICMP_FRAGM_AND_DF; - icmp_hdr->ih_hun.ihh_mtu.im_mtu= htons(mtu); - icmp_hdr->ih_chksum= ~oneC_sum(~icmp_hdr->ih_chksum, - (u16_t *)&icmp_hdr->ih_type, 2); - icmp_hdr->ih_chksum= ~oneC_sum(~icmp_hdr->ih_chksum, - (u16_t *)&icmp_hdr->ih_hun.ihh_mtu.im_mtu, 2); - enqueue_pack(icmp_port, pack); -} - -static void process_data(icmp_port, data) -icmp_port_t *icmp_port; -acc_t *data; -{ - ip_hdr_t *ip_hdr; - icmp_hdr_t *icmp_hdr; - acc_t *icmp_data; - int ip_hdr_len; - size_t pack_len; - - /* Align entire packet */ - data= bf_align(data, BUF_S, 4); - - data= bf_packIffLess(data, IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(data); - DIFBLOCK(0x10, (ip_hdr->ih_dst & HTONL(0xf0000000)) == HTONL(0xe0000000), - printf("got multicast packet\n")); - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - - if (ip_hdr_len>IP_MIN_HDR_SIZE) - { - data= bf_packIffLess(data, ip_hdr_len); - ip_hdr= (ip_hdr_t *)ptr2acc_data(data); - } - - pack_len= bf_bufsize(data); - pack_len -= ip_hdr_len; - if (pack_len < ICMP_MIN_HDR_SIZE) - { - if (pack_len == 0 && ip_hdr->ih_proto == 0) - { - /* IP layer reports new ip address, which can be - * ignored. - */ - } - else - DBLOCK(1, printf("got an incomplete icmp packet\n")); - bf_afree(data); - return; - } - - icmp_data= bf_cut(data, ip_hdr_len, pack_len); - - icmp_data= bf_packIffLess (icmp_data, ICMP_MIN_HDR_SIZE); - icmp_hdr= (icmp_hdr_t *)ptr2acc_data(icmp_data); - - if ((u16_t)~icmp_pack_oneCsum(icmp_data)) - { - DBLOCK(1, printf( - "got packet with bad checksum (= 0x%x, 0x%x)\n", - icmp_hdr->ih_chksum, - (u16_t)~icmp_pack_oneCsum(icmp_data))); - bf_afree(data); - bf_afree(icmp_data); - return; - } - - switch (icmp_hdr->ih_type) - { - case ICMP_TYPE_ECHO_REPL: - break; - case ICMP_TYPE_DST_UNRCH: - icmp_dst_unreach (icmp_port, data, ip_hdr_len, ip_hdr, - icmp_data, pack_len, icmp_hdr); - break; - case ICMP_TYPE_SRC_QUENCH: - /* Ignore src quench ICMPs */ - DBLOCK(2, printf("ignoring SRC QUENCH ICMP.\n")); - break; - case ICMP_TYPE_REDIRECT: - icmp_redirect (icmp_port, ip_hdr, icmp_data, pack_len, - icmp_hdr); - break; - case ICMP_TYPE_ECHO_REQ: - icmp_echo_request(icmp_port, data, ip_hdr_len, ip_hdr, - icmp_data, pack_len, icmp_hdr); - return; - case ICMP_TYPE_ROUTER_ADVER: - icmp_router_advertisement(icmp_port, icmp_data, pack_len, - icmp_hdr); - break; - case ICMP_TYPE_ROUTE_SOL: - break; /* Should be handled by a routing deamon. */ - case ICMP_TYPE_TIME_EXCEEDED: - icmp_time_exceeded (icmp_port, data, ip_hdr_len, ip_hdr, - icmp_data, pack_len, icmp_hdr); - break; - default: - DBLOCK(1, printf("got an unknown icmp (%d) from ", - icmp_hdr->ih_type); - writeIpAddr(ip_hdr->ih_src); printf("\n")); - break; - } - bf_afree(data); - bf_afree(icmp_data); -} - -static void icmp_echo_request(icmp_port, ip_data, ip_len, ip_hdr, - icmp_data, icmp_len, icmp_hdr) -icmp_port_t *icmp_port; -acc_t *ip_data, *icmp_data; -int ip_len, icmp_len; -ip_hdr_t *ip_hdr; -icmp_hdr_t *icmp_hdr; -{ - acc_t *repl_ip_hdr, *repl_icmp; - ipaddr_t tmpaddr, locaddr, netmask; - icmp_hdr_t *repl_icmp_hdr; - i32_t tmp_chksum; - ip_port_t *ip_port; - - if (icmp_hdr->ih_code != 0) - { - DBLOCK(1, - printf("got an icmp echo request with unknown code (%d)\n", - icmp_hdr->ih_code)); - bf_afree(ip_data); - bf_afree(icmp_data); - return; - } - if (icmp_len < ICMP_MIN_HDR_SIZE + sizeof(icmp_id_seq_t)) - { - DBLOCK(1, printf("got an incomplete icmp echo request\n")); - bf_afree(ip_data); - bf_afree(icmp_data); - return; - } - tmpaddr= ntohl(ip_hdr->ih_dst); - if ((tmpaddr & 0xe0000000) == 0xe0000000 && - tmpaddr != 0xffffffff) - { - /* Respond only to the all hosts multicast address until - * a decent listening service has been implemented - */ - if (tmpaddr != 0xe0000001) - { - bf_afree(ip_data); - bf_afree(icmp_data); - return; - } - } - - /* Limit subnet broadcasts to the local net */ - ip_port= &ip_port_table[icmp_port->icp_ipport]; - locaddr= ip_port->ip_ipaddr; - netmask= ip_port->ip_subnetmask; - if (ip_hdr->ih_dst == (locaddr | ~netmask) && - (ip_port->ip_flags & IPF_SUBNET_BCAST) && - ((ip_hdr->ih_src ^ locaddr) & netmask) != 0) - { - /* Directed broadcast */ - bf_afree(ip_data); - bf_afree(icmp_data); - return; - } - - repl_ip_hdr= make_repl_ip(ip_hdr, ip_len); - repl_icmp= bf_memreq (ICMP_MIN_HDR_SIZE); - repl_icmp_hdr= (icmp_hdr_t *)ptr2acc_data(repl_icmp); - repl_icmp_hdr->ih_type= ICMP_TYPE_ECHO_REPL; - repl_icmp_hdr->ih_code= 0; - - DBLOCK(2, - printf("ih_chksum= 0x%x, ih_type= 0x%x, repl->ih_type= 0x%x\n", - icmp_hdr->ih_chksum, *(u16_t *)&icmp_hdr->ih_type, - *(u16_t *)&repl_icmp_hdr->ih_type)); - tmp_chksum= (~icmp_hdr->ih_chksum & 0xffff) - - (i32_t)*(u16_t *)&icmp_hdr->ih_type+ - *(u16_t *)&repl_icmp_hdr->ih_type; - tmp_chksum= (tmp_chksum >> 16) + (tmp_chksum & 0xffff); - tmp_chksum= (tmp_chksum >> 16) + (tmp_chksum & 0xffff); - repl_icmp_hdr->ih_chksum= ~tmp_chksum; - DBLOCK(2, printf("sending chksum 0x%x\n", repl_icmp_hdr->ih_chksum)); - - repl_ip_hdr->acc_next= repl_icmp; - repl_icmp->acc_next= bf_cut (icmp_data, ICMP_MIN_HDR_SIZE, - icmp_len - ICMP_MIN_HDR_SIZE); - - bf_afree(ip_data); - bf_afree(icmp_data); - - enqueue_pack(icmp_port, repl_ip_hdr); -} - -static u16_t icmp_pack_oneCsum(icmp_pack) -acc_t *icmp_pack; -{ - u16_t prev; - int odd_byte; - char *data_ptr; - int length; - char byte_buf[2]; - - prev= 0; - - odd_byte= FALSE; - for (; icmp_pack; icmp_pack= icmp_pack->acc_next) - { - data_ptr= ptr2acc_data(icmp_pack); - length= icmp_pack->acc_length; - - if (!length) - continue; - if (odd_byte) - { - byte_buf[1]= *data_ptr; - prev= oneC_sum(prev, (u16_t *)byte_buf, 2); - data_ptr++; - length--; - odd_byte= FALSE; - } - if (length & 1) - { - odd_byte= TRUE; - length--; - byte_buf[0]= data_ptr[length]; - } - if (!length) - continue; - prev= oneC_sum (prev, (u16_t *)data_ptr, length); - } - if (odd_byte) - prev= oneC_sum (prev, (u16_t *)byte_buf, 1); - return prev; -} - -static acc_t *make_repl_ip(ip_hdr, ip_len) -ip_hdr_t *ip_hdr; -int ip_len; -{ - ip_hdr_t *repl_ip_hdr; - acc_t *repl; - int repl_hdr_len; - - if (ip_len>IP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("ip_hdr options NOT supported (yet?)\n")); - ip_len= IP_MIN_HDR_SIZE; - } - - repl_hdr_len= IP_MIN_HDR_SIZE; - - repl= bf_memreq(repl_hdr_len); - - repl_ip_hdr= (ip_hdr_t *)ptr2acc_data(repl); - - repl_ip_hdr->ih_vers_ihl= repl_hdr_len >> 2; - repl_ip_hdr->ih_tos= ip_hdr->ih_tos; - repl_ip_hdr->ih_ttl= ICMP_DEF_TTL; - repl_ip_hdr->ih_proto= IPPROTO_ICMP; - repl_ip_hdr->ih_dst= ip_hdr->ih_src; - repl_ip_hdr->ih_flags_fragoff= 0; - - return repl; -} - -static void enqueue_pack(icmp_port, reply_ip_hdr) -icmp_port_t *icmp_port; -acc_t *reply_ip_hdr; -{ - int r; - ev_arg_t ev_arg; - - /* Check rate */ - if (icmp_port->icp_rate_count >= ICMP_MAX_RATE) - { - /* Something is going wrong; check policy */ - r= icmp_rate_limit(icmp_port, reply_ip_hdr); - if (r == -1) - { - bf_afree(reply_ip_hdr); - return; - } - - /* OK, continue */ - } - icmp_port->icp_rate_count++; - - reply_ip_hdr->acc_ext_link= 0; - - if (icmp_port->icp_head_queue) - { - icmp_port->icp_tail_queue->acc_ext_link= - reply_ip_hdr; - } - else - { - icmp_port->icp_head_queue= reply_ip_hdr; - } - reply_ip_hdr->acc_ext_link= NULL; - icmp_port->icp_tail_queue= reply_ip_hdr; - - if (!(icmp_port->icp_flags & ICPF_WRITE_IP)) - { - icmp_port->icp_flags |= ICPF_WRITE_IP; - ev_arg.ev_ptr= icmp_port; - ev_enqueue(&icmp_port->icp_event, icmp_write, ev_arg); - } -} - -static int icmp_rate_limit(icmp_port, reply_ip_hdr) -icmp_port_t *icmp_port; -acc_t *reply_ip_hdr; -{ - time_t t; - acc_t *pack; - ip_hdr_t *ip_hdr; - icmp_hdr_t *icmp_hdr; - int hdrlen, icmp_hdr_len, type; - - /* Check the time first */ - t= get_time(); - if (t >= icmp_port->icp_rate_lasttime + ICMP_RATE_INTERVAL) - { - icmp_port->icp_rate_lasttime= t; - icmp_port->icp_rate_count= 0; - return 0; - } - - icmp_port->icp_rate_count++; - - /* Adjust report limit if necessary */ - if (icmp_port->icp_rate_count > - icmp_port->icp_rate_report+ICMP_RATE_WARN) - { - icmp_port->icp_rate_report *= 2; - return -1; - } - - /* Do we need to report */ - if (icmp_port->icp_rate_count < icmp_port->icp_rate_report) - return -1; - - pack= bf_dupacc(reply_ip_hdr); - pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - printf("icmp[%d]: dropping ICMP packet #%d to ", - icmp_port->icp_ipport, icmp_port->icp_rate_count); - writeIpAddr(ip_hdr->ih_dst); - hdrlen= (ip_hdr->ih_vers_ihl & IH_IHL_MASK)*4; - pack= bf_packIffLess(pack, hdrlen+ICMP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - icmp_hdr= (icmp_hdr_t *)(ptr2acc_data(pack)+hdrlen); - type= icmp_hdr->ih_type; - printf(" type %d, code %d\n", type, icmp_hdr->ih_code); - switch(type) - { - case ICMP_TYPE_DST_UNRCH: - case ICMP_TYPE_SRC_QUENCH: - case ICMP_TYPE_REDIRECT: - case ICMP_TYPE_TIME_EXCEEDED: - case ICMP_TYPE_PARAM_PROBLEM: - icmp_hdr_len= offsetof(struct icmp_hdr, ih_dun); - pack= bf_packIffLess(pack, - hdrlen+icmp_hdr_len+IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)(ptr2acc_data(pack)+hdrlen+icmp_hdr_len); - icmp_hdr= (icmp_hdr_t *)(ptr2acc_data(pack)+hdrlen); - printf("\tinfo %08x, original dst ", - ntohs(icmp_hdr->ih_hun.ihh_unused)); - writeIpAddr(ip_hdr->ih_dst); - printf(", proto %d, length %u\n", - ip_hdr->ih_proto, ntohs(ip_hdr->ih_length)); - break; - default: - break; - } - bf_afree(pack); pack= NULL; - - return -1; -} - -static void icmp_write(ev, ev_arg) -event_t *ev; -ev_arg_t ev_arg; -{ - int result; - icmp_port_t *icmp_port; - acc_t *data; - - icmp_port= ev_arg.ev_ptr; - assert(ev == &icmp_port->icp_event); - - assert (icmp_port->icp_flags & ICPF_WRITE_IP); - assert (!(icmp_port->icp_flags & ICPF_WRITE_SP)); - - while (icmp_port->icp_head_queue != NULL) - { - data= icmp_port->icp_head_queue; - icmp_port->icp_head_queue= data->acc_ext_link; - - result= ip_send(icmp_port->icp_ipfd, data, - bf_bufsize(data)); - if (result != NW_WOULDBLOCK) - { - if (result == NW_OK) - continue; - DBLOCK(1, printf("icmp_write: error %d\n", result);); - continue; - } - - assert(icmp_port->icp_write_pack == NULL); - icmp_port->icp_write_pack= data; - - result= ip_write(icmp_port->icp_ipfd, - bf_bufsize(icmp_port->icp_write_pack)); - if (result == NW_SUSPEND) - { - icmp_port->icp_flags |= ICPF_WRITE_SP; - return; - } - } - icmp_port->icp_flags &= ~ICPF_WRITE_IP; -} - -static void icmp_buffree(priority) -int priority; -{ - acc_t *tmp_acc; - int i; - icmp_port_t *icmp_port; - - if (priority == ICMP_PRI_QUEUE) - { - for (i=0, icmp_port= icmp_port_table; iicp_head_queue) - { - tmp_acc= icmp_port->icp_head_queue; - icmp_port->icp_head_queue= - tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - } - } - } -} - -#ifdef BUF_CONSISTENCY_CHECK -static void icmp_bufcheck() -{ - int i; - icmp_port_t *icmp_port; - acc_t *pack; - - for (i= 0, icmp_port= icmp_port_table; iicp_head_queue; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - bf_check_acc(icmp_port->icp_write_pack); - } -} -#endif - -static void icmp_dst_unreach(icmp_port, ip_pack, ip_hdr_len, ip_hdr, icmp_pack, - icmp_len, icmp_hdr) -icmp_port_t *icmp_port; -acc_t *ip_pack; -int ip_hdr_len; -ip_hdr_t *ip_hdr; -acc_t *icmp_pack; -int icmp_len; -icmp_hdr_t *icmp_hdr; -{ - acc_t *old_ip_pack; - ip_hdr_t *old_ip_hdr; - int ip_port_nr; - ipaddr_t dst, mask; - size_t old_pack_size; - u16_t new_mtu; - - if (icmp_len < 8 + IP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("dest unrch with wrong size\n")); - return; - } - old_ip_pack= bf_cut (icmp_pack, 8, icmp_len-8); - old_ip_pack= bf_packIffLess(old_ip_pack, IP_MIN_HDR_SIZE); - old_ip_hdr= (ip_hdr_t *)ptr2acc_data(old_ip_pack); - - if (old_ip_hdr->ih_src != ip_hdr->ih_dst) - { - DBLOCK(1, printf("dest unrch based on wrong packet\n")); - bf_afree(old_ip_pack); - return; - } - - ip_port_nr= icmp_port->icp_ipport; - - switch(icmp_hdr->ih_code) - { - case ICMP_NET_UNRCH: - dst= old_ip_hdr->ih_dst; - mask= ip_get_netmask(dst); - ipr_destunrch (ip_port_nr, dst & mask, mask, - IPR_UNRCH_TIMEOUT); - break; - case ICMP_HOST_UNRCH: - ipr_destunrch (ip_port_nr, old_ip_hdr->ih_dst, (ipaddr_t)-1, - IPR_UNRCH_TIMEOUT); - break; - case ICMP_PORT_UNRCH: - /* At the moment we don't do anything with this information. - * It should be handed to the appropriate transport layer. - */ - break; - case ICMP_FRAGM_AND_DF: - - DBLOCK(1, printf("icmp_dst_unreach: got mtu icmp from "); - writeIpAddr(ip_hdr->ih_src); - printf("; original destination: "); - writeIpAddr(old_ip_hdr->ih_dst); - printf("; protocol: %d\n", - old_ip_hdr->ih_proto)); - old_pack_size= ntohs(old_ip_hdr->ih_length); - if (!old_pack_size) - break; - new_mtu= ntohs(icmp_hdr->ih_hun.ihh_mtu.im_mtu); - if (!new_mtu || new_mtu > old_pack_size) - new_mtu= old_pack_size-1; - ipr_mtu(ip_port_nr, old_ip_hdr->ih_dst, new_mtu, - IPR_MTU_TIMEOUT); - break; - - default: - DBLOCK(1, printf("icmp_dst_unreach: got strange code %d from ", - icmp_hdr->ih_code); - writeIpAddr(ip_hdr->ih_src); - printf("; original destination: "); - writeIpAddr(old_ip_hdr->ih_dst); - printf("; protocol: %d\n", - old_ip_hdr->ih_proto)); - break; - } - bf_afree(old_ip_pack); -} - -static void icmp_time_exceeded(icmp_port, ip_pack, ip_hdr_len, ip_hdr, - icmp_pack, icmp_len, icmp_hdr) -icmp_port_t *icmp_port; -acc_t *ip_pack; -int ip_hdr_len; -ip_hdr_t *ip_hdr; -acc_t *icmp_pack; -int icmp_len; -icmp_hdr_t *icmp_hdr; -{ - acc_t *old_ip_pack; - ip_hdr_t *old_ip_hdr; - int ip_port_nr; - - if (icmp_len < 8 + IP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("time exceeded with wrong size\n")); - return; - } - old_ip_pack= bf_cut (icmp_pack, 8, icmp_len-8); - old_ip_pack= bf_packIffLess(old_ip_pack, IP_MIN_HDR_SIZE); - old_ip_hdr= (ip_hdr_t *)ptr2acc_data(old_ip_pack); - - if (old_ip_hdr->ih_src != ip_hdr->ih_dst) - { - DBLOCK(1, printf("time exceeded based on wrong packet\n")); - bf_afree(old_ip_pack); - return; - } - - ip_port_nr= icmp_port->icp_ipport; - - switch(icmp_hdr->ih_code) - { - case ICMP_TTL_EXC: - ipr_ttl_exc (ip_port_nr, old_ip_hdr->ih_dst, (ipaddr_t)-1, - IPR_TTL_TIMEOUT); - break; - case ICMP_FRAG_REASSEM: - /* Ignore reassembly time-outs. */ - break; - default: - DBLOCK(1, printf("got strange code: %d\n", - icmp_hdr->ih_code)); - break; - } - bf_afree(old_ip_pack); -} - -static void icmp_router_advertisement(icmp_port, icmp_pack, icmp_len, icmp_hdr) -icmp_port_t *icmp_port; -acc_t *icmp_pack; -int icmp_len; -icmp_hdr_t *icmp_hdr; -{ - int entries; - int entry_size; - u16_t lifetime; - int i; - char *bufp; - - if (icmp_len < 8) - { - DBLOCK(1, - printf("router advertisement with wrong size (%d)\n", - icmp_len)); - return; - } - if (icmp_hdr->ih_code != 0) - { - DBLOCK(1, - printf("router advertisement with wrong code (%d)\n", - icmp_hdr->ih_code)); - return; - } - entries= icmp_hdr->ih_hun.ihh_ram.iram_na; - entry_size= icmp_hdr->ih_hun.ihh_ram.iram_aes * 4; - if (entries < 1) - { - DBLOCK(1, printf( - "router advertisement with wrong number of entries (%d)\n", - entries)); - return; - } - if (entry_size < 8) - { - DBLOCK(1, printf( - "router advertisement with wrong entry size (%d)\n", - entry_size)); - return; - } - if (icmp_len < 8 + entries * entry_size) - { - DBLOCK(1, - printf("router advertisement with wrong size\n"); - printf( - "\t(entries= %d, entry_size= %d, icmp_len= %d)\n", - entries, entry_size, icmp_len)); - return; - } - lifetime= ntohs(icmp_hdr->ih_hun.ihh_ram.iram_lt); - if (lifetime > 9000) - { - DBLOCK(1, printf( - "router advertisement with wrong lifetime (%d)\n", - lifetime)); - return; - } - for (i= 0, bufp= (char *)&icmp_hdr->ih_dun.uhd_data[0]; i< entries; i++, - bufp += entry_size) - { - u32_t addr; - i32_t pref; - - addr= *(ipaddr_t *)bufp; - pref= ntohl(*(u32_t *)(bufp+4)); - ipr_add_oroute(icmp_port->icp_ipport, HTONL(0L), HTONL(0L), - addr, lifetime ? lifetime * HZ : 1, - 1, 0, 0, pref, NULL); - } -} - -static void icmp_redirect(icmp_port, ip_hdr, icmp_pack, icmp_len, icmp_hdr) -icmp_port_t *icmp_port; -ip_hdr_t *ip_hdr; -acc_t *icmp_pack; -int icmp_len; -icmp_hdr_t *icmp_hdr; -{ - acc_t *old_ip_pack; - ip_hdr_t *old_ip_hdr; - int ip_port_nr; - ipaddr_t dst, mask; - - if (icmp_len < 8 + IP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("redirect with wrong size\n")); - return; - } - old_ip_pack= bf_cut (icmp_pack, 8, icmp_len-8); - old_ip_pack= bf_packIffLess(old_ip_pack, IP_MIN_HDR_SIZE); - old_ip_hdr= (ip_hdr_t *)ptr2acc_data(old_ip_pack); - - ip_port_nr= icmp_port->icp_ipport; - - switch(icmp_hdr->ih_code) - { - case ICMP_REDIRECT_NET: - dst= old_ip_hdr->ih_dst; - mask= ip_get_netmask(dst); - ipr_redirect (ip_port_nr, dst & mask, mask, - ip_hdr->ih_src, icmp_hdr->ih_hun.ihh_gateway, - IPR_REDIRECT_TIMEOUT); - break; - case ICMP_REDIRECT_HOST: - ipr_redirect (ip_port_nr, old_ip_hdr->ih_dst, (ipaddr_t)-1, - ip_hdr->ih_src, icmp_hdr->ih_hun.ihh_gateway, - IPR_REDIRECT_TIMEOUT); - break; - default: - DBLOCK(1, printf("got strange code: %d\n", - icmp_hdr->ih_code)); - break; - } - bf_afree(old_ip_pack); -} - -static acc_t *icmp_err_pack(pack, icmp_hdr_pp) -acc_t *pack; -icmp_hdr_t **icmp_hdr_pp; -{ - ip_hdr_t *ip_hdr; - icmp_hdr_t *icmp_hdr_p; - acc_t *ip_pack, *icmp_pack, *tmp_pack; - int ip_hdr_len, icmp_hdr_len, ih_type; - size_t size, pack_len; - ipaddr_t dest; - nettype_t nettype; - - pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - pack_len= bf_bufsize(pack); - - /* If the IP protocol is ICMP (except echo request/reply) or the - * fragment offset is non-zero, - * drop the packet. Also check if the source address is valid. - */ - if ((ntohs(ip_hdr->ih_flags_fragoff) & IH_FRAGOFF_MASK) != 0) - { - bf_afree(pack); - return NULL; - } - if (ip_hdr->ih_proto == IPPROTO_ICMP) - { - if (ip_hdr_len>IP_MIN_HDR_SIZE) - { - pack= bf_packIffLess(pack, ip_hdr_len); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - } - - if (pack_len < ip_hdr_len+ICMP_MIN_HDR_SIZE) - { - bf_afree(pack); - return NULL; - } - icmp_pack= bf_cut(pack, ip_hdr_len, ICMP_MIN_HDR_SIZE); - icmp_pack= bf_packIffLess (icmp_pack, ICMP_MIN_HDR_SIZE); - icmp_hdr_p= (icmp_hdr_t *)ptr2acc_data(icmp_pack); - ih_type= icmp_hdr_p->ih_type; - bf_afree(icmp_pack); icmp_pack= NULL; - - if (ih_type != ICMP_TYPE_ECHO_REQ && - ih_type != ICMP_TYPE_ECHO_REPL) - { - bf_afree(pack); - return NULL; - } - } - dest= ip_hdr->ih_src; - nettype= ip_nettype(dest); - if (nettype != IPNT_CLASS_A && nettype != IPNT_LOCAL && - nettype != IPNT_CLASS_B && nettype != IPNT_CLASS_C) - { - printf("icmp_err_pack: invalid source address: "); - writeIpAddr(dest); - printf("\n"); - bf_afree(pack); - return NULL; - } - - /* Take the IP header and the first 64 bits of user data. */ - size= ntohs(ip_hdr->ih_length); - if (size < ip_hdr_len || pack_len < size) - { - printf("icmp_err_pack: wrong packet size:\n"); - printf("\thdrlen= %d, ih_length= %d, bufsize= %d\n", - ip_hdr_len, size, pack_len); - bf_afree(pack); - return NULL; - } - if (ip_hdr_len + 8 < size) - size= ip_hdr_len+8; - tmp_pack= bf_cut(pack, 0, size); - bf_afree(pack); - pack= tmp_pack; - tmp_pack= NULL; - - /* Create a minimal size ICMP hdr. */ - icmp_hdr_len= offsetof(icmp_hdr_t, ih_dun); - icmp_pack= bf_memreq(icmp_hdr_len); - pack= bf_append(icmp_pack, pack); - size += icmp_hdr_len; - pack= bf_packIffLess(pack, icmp_hdr_len); - icmp_hdr_p= (icmp_hdr_t *)ptr2acc_data(pack); - icmp_hdr_p->ih_type= 0; - icmp_hdr_p->ih_code= 0; - icmp_hdr_p->ih_chksum= 0; - icmp_hdr_p->ih_hun.ihh_unused= 0; - icmp_hdr_p->ih_chksum= ~icmp_pack_oneCsum(pack); - *icmp_hdr_pp= icmp_hdr_p; - - /* Create an IP header */ - ip_hdr_len= IP_MIN_HDR_SIZE; - - ip_pack= bf_memreq(ip_hdr_len); - ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_pack); - - ip_hdr->ih_vers_ihl= ip_hdr_len >> 2; - ip_hdr->ih_tos= 0; - ip_hdr->ih_length= htons(ip_hdr_len + size); - ip_hdr->ih_flags_fragoff= 0; - ip_hdr->ih_ttl= ICMP_DEF_TTL; - ip_hdr->ih_proto= IPPROTO_ICMP; - ip_hdr->ih_dst= dest; - - assert(ip_pack->acc_next == NULL); - ip_pack->acc_next= pack; - return ip_pack; -} - -/* - * $PchId: icmp.c,v 1.23 2005/06/28 14:16:56 philip Exp $ - */ diff --git a/minix/net/inet/generic/icmp.h b/minix/net/inet/generic/icmp.h deleted file mode 100644 index 12fe3b954..000000000 --- a/minix/net/inet/generic/icmp.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -icmp.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef ICMP_H -#define ICMP_H - -#define ICMP_MAX_DATAGRAM 8196 -#define ICMP_DEF_TTL 96 - -/* Rate limit. The implementation is a bit sloppy and may send twice the - * number of packets. - */ -#define ICMP_MAX_RATE 100 /* This many per interval */ -#define ICMP_RATE_INTERVAL (1*HZ) /* Interval in ticks */ -#define ICMP_RATE_WARN 10 /* Report this many dropped packets */ - -/* Prototypes */ - -void icmp_prep ARGS(( void )); -void icmp_init ARGS(( void )); - - -#endif /* ICMP_H */ - -/* - * $PchId: icmp.h,v 1.7 2001/04/19 19:06:18 philip Exp $ - */ diff --git a/minix/net/inet/generic/icmp_lib.h b/minix/net/inet/generic/icmp_lib.h deleted file mode 100644 index 8601ff499..000000000 --- a/minix/net/inet/generic/icmp_lib.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -icmp_lib.h - -Created Sept 30, 1991 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef ICMP_LIB_H -#define ICMP_LIB_H - -/* Prototypes */ - -void icmp_snd_parmproblem ARGS(( acc_t *pack )); -void icmp_snd_time_exceeded ARGS(( int port_nr, acc_t *pack, int code )); -void icmp_snd_unreachable ARGS(( int port_nr, acc_t *pack, int code )); -void icmp_snd_redirect ARGS(( int port_nr, acc_t *pack, int code, - ipaddr_t gw )); -void icmp_snd_mtu ARGS(( int port_nr, acc_t *pack, u16_t mtu )); - -#endif /* ICMP_LIB_H */ - -/* - * $PchId: icmp_lib.h,v 1.6 2002/06/08 21:32:44 philip Exp $ - */ diff --git a/minix/net/inet/generic/io.c b/minix/net/inet/generic/io.c deleted file mode 100644 index 7b861d20a..000000000 --- a/minix/net/inet/generic/io.c +++ /dev/null @@ -1,34 +0,0 @@ -/* -io.c - -Copyright 1995 Philip Homburg -*/ - -#include - -#include "inet.h" -#include "io.h" - -void writeIpAddr(addr) -ipaddr_t addr; -{ -#define addrInBytes ((u8_t *)&addr) - - printf("%d.%d.%d.%d", addrInBytes[0], addrInBytes[1], - addrInBytes[2], addrInBytes[3]); -#undef addrInBytes -} - -void writeEtherAddr(addr) -ether_addr_t *addr; -{ -#define addrInBytes ((u8_t *)addr->ea_addr) - - printf("%x:%x:%x:%x:%x:%x", addrInBytes[0], addrInBytes[1], - addrInBytes[2], addrInBytes[3], addrInBytes[4], addrInBytes[5]); -#undef addrInBytes -} - -/* - * $PchId: io.c,v 1.6 1998/10/23 20:24:34 philip Exp $ - */ diff --git a/minix/net/inet/generic/io.h b/minix/net/inet/generic/io.h deleted file mode 100644 index 43d98ff5c..000000000 --- a/minix/net/inet/generic/io.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -io.h - -Created Sept 30, 1991 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef IO_H -#define IO_H - -/* Prototypes */ - -void writeIpAddr ARGS(( ipaddr_t addr )); -void writeEtherAddr ARGS(( ether_addr_t *addr )); - -#endif /* IO_H */ - -/* - * $PchId: io.h,v 1.4 1995/11/21 06:45:27 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip.c b/minix/net/inet/generic/ip.c deleted file mode 100644 index 05792f643..000000000 --- a/minix/net/inet/generic/ip.c +++ /dev/null @@ -1,495 +0,0 @@ -/* -ip.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "event.h" -#include "type.h" - -#include "arp.h" -#include "assert.h" -#include "clock.h" -#include "eth.h" -#include "icmp.h" -#include "icmp_lib.h" -#include "io.h" -#include "ip.h" -#include "ip_int.h" -#include "ipr.h" -#include "sr.h" - -THIS_FILE - -static void ip_close ARGS(( int fd )); -static int ip_cancel ARGS(( int fd, int which_operation )); -static int ip_select ARGS(( int fd, unsigned operations )); - -static void ip_buffree ARGS(( int priority )); -#ifdef BUF_CONSISTENCY_CHECK -static void ip_bufcheck ARGS(( void )); -#endif -static void ip_bad_callback ARGS(( struct ip_port *ip_port )); - -ip_port_t *ip_port_table; -ip_fd_t ip_fd_table[IP_FD_NR]; -ip_ass_t ip_ass_table[IP_ASS_NR]; - -void ip_prep() -{ - ip_port_table= alloc(ip_conf_nr * sizeof(ip_port_table[0])); - icmp_prep(); -} - -void ip_init() -{ - int i, j, result; - ip_ass_t *ip_ass; - ip_fd_t *ip_fd; - ip_port_t *ip_port; - struct ip_conf *icp; - - assert (BUF_S >= sizeof(struct nwio_ethopt)); - assert (BUF_S >= IP_MAX_HDR_SIZE + ETH_HDR_SIZE); - assert (BUF_S >= sizeof(nwio_ipopt_t)); - assert (BUF_S >= sizeof(nwio_route_t)); - - for (i=0, ip_ass= ip_ass_table; iia_frags= 0; - ip_ass->ia_first_time= 0; - ip_ass->ia_port= 0; - } - - for (i=0, ip_fd= ip_fd_table; iif_flags= IFF_EMPTY; - ip_fd->if_rdbuf_head= 0; - } - - for (i=0, ip_port= ip_port_table, icp= ip_conf; - iip_port= i; - ip_port->ip_flags= IPF_EMPTY; - ip_port->ip_dev_main= (ip_dev_t)ip_bad_callback; - ip_port->ip_dev_set_ipaddr= (ip_dev_t)ip_bad_callback; - ip_port->ip_dev_send= (ip_dev_send_t)ip_bad_callback; - ip_port->ip_dl_type= icp->ic_devtype; - ip_port->ip_mtu= IP_DEF_MTU; - ip_port->ip_mtu_max= IP_MAX_PACKSIZE; - memset(&ip_port->ip_dl, 0, sizeof(ip_port->ip_dl)); - - switch(ip_port->ip_dl_type) - { - case IPDL_ETH: - ip_port->ip_dl.dl_eth.de_port= icp->ic_port; - result= ipeth_init(ip_port); - if (result == -1) - continue; - assert(result == NW_OK); - break; - case IPDL_PSIP: - ip_port->ip_dl.dl_ps.ps_port= icp->ic_port; - result= ipps_init(ip_port); - if (result == -1) - continue; - assert(result == NW_OK); - break; - default: - ip_panic(( "unknown ip_dl_type %d", - ip_port->ip_dl_type )); - break; - } - ip_port->ip_loopb_head= NULL; - ip_port->ip_loopb_tail= NULL; - ev_init(&ip_port->ip_loopb_event); - ip_port->ip_routeq_head= NULL; - ip_port->ip_routeq_tail= NULL; - ev_init(&ip_port->ip_routeq_event); - ip_port->ip_flags |= IPF_CONFIGURED; - ip_port->ip_proto_any= NULL; - for (j= 0; jip_proto[j]= NULL; - } - -#ifndef BUF_CONSISTENCY_CHECK - bf_logon(ip_buffree); -#else - bf_logon(ip_buffree, ip_bufcheck); -#endif - - icmp_init(); - ipr_init(); - - for (i=0, ip_port= ip_port_table; iip_flags & IPF_CONFIGURED)) - continue; - ip_port->ip_frame_id= (u16_t)get_time(); - - sr_add_minor(if2minor(ip_conf[i].ic_ifno, IP_DEV_OFF), - i, ip_open, ip_close, ip_read, - ip_write, ip_ioctl, ip_cancel, ip_select); - - (*ip_port->ip_dev_main)(ip_port); - } -} - -static int ip_cancel (fd, which_operation) -int fd; -int which_operation; -{ - ip_fd_t *ip_fd; - acc_t *repl_res; - int result; - - ip_fd= &ip_fd_table[fd]; - - switch (which_operation) - { - case SR_CANCEL_IOCTL: - assert (ip_fd->if_flags & IFF_IOCTL_IP); - ip_fd->if_flags &= ~IFF_IOCTL_IP; - repl_res= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - (size_t)EINTR, (size_t)0, TRUE); - assert (!repl_res); - break; - case SR_CANCEL_READ: - assert (ip_fd->if_flags & IFF_READ_IP); - ip_fd->if_flags &= ~IFF_READ_IP; - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - (size_t)EINTR, (acc_t *)0, FALSE); - assert (!result); - break; -#if 0 - case SR_CANCEL_WRITE: - assert(0); - assert (ip_fd->if_flags & IFF_WRITE_MASK); - ip_fd->if_flags &= ~IFF_WRITE_MASK; - repl_res= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - (size_t)EINTR, (size_t)0, FALSE); - assert (!repl_res); - break; -#endif - default: - ip_panic(( "unknown cancel request" )); - break; - } - return NW_OK; -} - -static int ip_select(fd, operations) -int fd; -unsigned operations; -{ - unsigned resops; - ip_fd_t *ip_fd; - - ip_fd= &ip_fd_table[fd]; - assert (ip_fd->if_flags & IFF_INUSE); - - resops= 0; - - if (operations & SR_SELECT_READ) - { - if (ip_sel_read(ip_fd)) - resops |= SR_SELECT_READ; - else if (!(operations & SR_SELECT_POLL)) - ip_fd->if_flags |= IFF_SEL_READ; - } - if (operations & SR_SELECT_WRITE) - { - /* Should handle special case when the interface is down */ - resops |= SR_SELECT_WRITE; - } - if (operations & SR_SELECT_EXCEPTION) - { - /* Nothing */ - } - return resops; -} - -int ip_open (port, srfd, get_userdata, put_userdata, put_pkt, - select_res) -int port; -int srfd; -get_userdata_t get_userdata; -put_userdata_t put_userdata; -put_pkt_t put_pkt; -select_res_t select_res; -{ - int i; - ip_fd_t *ip_fd; - ip_port_t *ip_port; - - ip_port= &ip_port_table[port]; - if (!(ip_port->ip_flags & IPF_CONFIGURED)) - return ENXIO; - - for (i=0; i=IP_FD_NR) - { - DBLOCK(1, printf("out of fds\n")); - return EAGAIN; - } - - ip_fd= &ip_fd_table[i]; - - ip_fd->if_flags= IFF_INUSE; - - ip_fd->if_ipopt.nwio_flags= NWIO_DEFAULT; - ip_fd->if_ipopt.nwio_tos= 0; - ip_fd->if_ipopt.nwio_df= FALSE; - ip_fd->if_ipopt.nwio_ttl= 255; - ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz= 0; - - ip_fd->if_port= ip_port; - ip_fd->if_srfd= srfd; - assert(ip_fd->if_rdbuf_head == NULL); - ip_fd->if_get_userdata= get_userdata; - ip_fd->if_put_userdata= put_userdata; - ip_fd->if_put_pkt= put_pkt; - ip_fd->if_select_res= select_res; - - return i; -} - -static void ip_close (fd) -int fd; -{ - ip_fd_t *ip_fd; - acc_t *pack; - - ip_fd= &ip_fd_table[fd]; - - assert ((ip_fd->if_flags & IFF_INUSE) && - !(ip_fd->if_flags & IFF_BUSY)); - - if (ip_fd->if_flags & IFF_OPTSET) - ip_unhash_proto(ip_fd); - while (ip_fd->if_rdbuf_head) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - ip_fd->if_flags= IFF_EMPTY; -} - -static void ip_buffree(priority) -int priority; -{ - int i; - ip_port_t *ip_port; - ip_fd_t *ip_fd; - ip_ass_t *ip_ass; - acc_t *pack, *next_pack; - - for (i= 0, ip_port= ip_port_table; iip_dl_type == IPDL_ETH) - { - /* Can't free de_frame. - * bf_check_acc(ip_port->ip_dl.dl_eth.de_frame); - */ - if (priority == IP_PRI_PORTBUFS) - { - next_pack= ip_port->ip_dl.dl_eth.de_arp_head; - while(next_pack != NULL) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - ip_port->ip_dl.dl_eth.de_arp_head= next_pack; - - next_pack= ip_port->ip_dl.dl_eth.de_q_head; - while(next_pack != NULL) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - ip_port->ip_dl.dl_eth.de_q_head= next_pack; - } - } - else if (ip_port->ip_dl_type == IPDL_PSIP) - { - if (priority == IP_PRI_PORTBUFS) - { - next_pack= ip_port->ip_dl.dl_ps.ps_send_head; - while (next_pack != NULL) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - ip_port->ip_dl.dl_ps.ps_send_head= next_pack; - } - } - if (priority == IP_PRI_PORTBUFS) - { - next_pack= ip_port->ip_loopb_head; - while(next_pack && next_pack->acc_ext_link) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - if (next_pack) - { - if (ev_in_queue(&ip_port->ip_loopb_event)) - { -#if DEBUG - printf( -"not freeing ip_loopb_head, ip_loopb_event enqueued\n"); -#endif - } - else - { - bf_afree(next_pack); - next_pack= NULL; - } - } - ip_port->ip_loopb_head= next_pack; - - next_pack= ip_port->ip_routeq_head; - while(next_pack && next_pack->acc_ext_link) - { - pack= next_pack; - next_pack= pack->acc_ext_link; - bf_afree(pack); - } - if (next_pack) - { - if (ev_in_queue(&ip_port->ip_routeq_event)) - { -#if DEBUG - printf( -"not freeing ip_loopb_head, ip_routeq_event enqueued\n"); -#endif - } - else - { - bf_afree(next_pack); - next_pack= NULL; - } - } - ip_port->ip_routeq_head= next_pack; - } - } - if (priority == IP_PRI_FDBUFS_EXTRA) - { - for (i= 0, ip_fd= ip_fd_table; iif_rdbuf_head && - ip_fd->if_rdbuf_head->acc_ext_link) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - } - } - if (priority == IP_PRI_FDBUFS) - { - for (i= 0, ip_fd= ip_fd_table; iif_rdbuf_head) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - } - } - if (priority == IP_PRI_ASSBUFS) - { - for (i= 0, ip_ass= ip_ass_table; iia_frags != NULL) - { - pack= ip_ass->ia_frags; - ip_ass->ia_frags= pack->acc_ext_link; - bf_afree(pack); - } - ip_ass->ia_first_time= 0; - } - } -} - -#ifdef BUF_CONSISTENCY_CHECK -static void ip_bufcheck() -{ - int i; - ip_port_t *ip_port; - ip_fd_t *ip_fd; - ip_ass_t *ip_ass; - acc_t *pack; - - for (i= 0, ip_port= ip_port_table; iip_dl_type == IPDL_ETH) - { - bf_check_acc(ip_port->ip_dl.dl_eth.de_frame); - for (pack= ip_port->ip_dl.dl_eth.de_q_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - for (pack= ip_port->ip_dl.dl_eth.de_arp_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - } - else if (ip_port->ip_dl_type == IPDL_PSIP) - { - for (pack= ip_port->ip_dl.dl_ps.ps_send_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - } - for (pack= ip_port->ip_loopb_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - for (pack= ip_port->ip_routeq_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - } - for (i= 0, ip_fd= ip_fd_table; iif_rdbuf_head; pack; - pack= pack->acc_ext_link) - { - bf_check_acc(pack); - } - } - for (i= 0, ip_ass= ip_ass_table; iia_frags; pack; pack= pack->acc_ext_link) - bf_check_acc(pack); - } -} -#endif /* BUF_CONSISTENCY_CHECK */ - -__dead -static void ip_bad_callback(ip_port) -struct ip_port *ip_port; -{ - ip_panic(( "no callback filled in for port %d", ip_port->ip_port )); -} - -/* - * $PchId: ip.c,v 1.19 2005/06/28 14:17:40 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip.h b/minix/net/inet/generic/ip.h deleted file mode 100644 index 8d30f8723..000000000 --- a/minix/net/inet/generic/ip.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -ip.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET_IP_H -#define INET_IP_H - -/* Prototypes */ - -struct acc; - -void ip_prep ARGS(( void )); -void ip_init ARGS(( void )); -int ip_open ARGS(( int port, int srfd, - get_userdata_t get_userdata, put_userdata_t put_userdata, - put_pkt_t put_pkt, select_res_t select_res )); -int ip_ioctl ARGS(( int fd, ioreq_t req )); -int ip_read ARGS(( int fd, size_t count )); -int ip_write ARGS(( int fd, size_t count )); -int ip_send ARGS(( int fd, struct acc *data, size_t data_len )); - -#endif /* INET_IP_H */ - -/* - * $PchId: ip.h,v 1.8 2005/06/28 14:17:57 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_eth.c b/minix/net/inet/generic/ip_eth.c deleted file mode 100644 index 26e47b385..000000000 --- a/minix/net/inet/generic/ip_eth.c +++ /dev/null @@ -1,722 +0,0 @@ -/* -generic/ip_eth.c - -Ethernet specific part of the IP implementation - -Created: Apr 22, 1993 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "type.h" -#include "arp.h" -#include "assert.h" -#include "buf.h" -#include "clock.h" -#include "eth.h" -#include "event.h" -#include "icmp_lib.h" -#include "io.h" -#include "ip.h" -#include "ip_int.h" - -THIS_FILE - -typedef struct xmit_hdr -{ - time_t xh_time; - ipaddr_t xh_ipaddr; -} xmit_hdr_t; - -static ether_addr_t broadcast_ethaddr= -{ - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } -}; -static ether_addr_t ipmulticast_ethaddr= -{ - { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 } -}; - -static void do_eth_read ARGS(( ip_port_t *port )); -static acc_t *get_eth_data ARGS(( int fd, size_t offset, - size_t count, int for_ioctl )); -static int put_eth_data ARGS(( int fd, size_t offset, - acc_t *data, int for_ioctl )); -static void ipeth_main ARGS(( ip_port_t *port )); -static void ipeth_set_ipaddr ARGS(( ip_port_t *port )); -static void ipeth_restart_send ARGS(( ip_port_t *ip_port )); -static int ipeth_send ARGS(( struct ip_port *ip_port, ipaddr_t dest, - acc_t *pack, int type )); -static void ipeth_arp_reply ARGS(( int ip_port_nr, ipaddr_t ipaddr, - ether_addr_t *dst_ether_ptr )); -static int ipeth_update_ttl ARGS(( time_t enq_time, time_t now, - acc_t *eth_pack )); -static void ip_eth_arrived ARGS(( int port, acc_t *pack, - size_t pack_size )); - - -int ipeth_init(ip_port) -ip_port_t *ip_port; -{ - assert(BUF_S >= sizeof(xmit_hdr_t)); - assert(BUF_S >= sizeof(eth_hdr_t)); - - ip_port->ip_dl.dl_eth.de_fd= eth_open(ip_port-> - ip_dl.dl_eth.de_port, ip_port->ip_port, - get_eth_data, put_eth_data, ip_eth_arrived, - 0 /* no select_res */); - if (ip_port->ip_dl.dl_eth.de_fd < 0) - { - DBLOCK(1, printf("ip.c: unable to open eth port\n")); - return -1; - } - ip_port->ip_dl.dl_eth.de_state= IES_EMPTY; - ip_port->ip_dl.dl_eth.de_flags= IEF_EMPTY; - ip_port->ip_dl.dl_eth.de_q_head= NULL; - ip_port->ip_dl.dl_eth.de_q_tail= NULL; - ip_port->ip_dl.dl_eth.de_arp_head= NULL; - ip_port->ip_dl.dl_eth.de_arp_tail= NULL; - ip_port->ip_dev_main= ipeth_main; - ip_port->ip_dev_set_ipaddr= ipeth_set_ipaddr; - ip_port->ip_dev_send= ipeth_send; - ip_port->ip_mtu= ETH_MAX_PACK_SIZE-ETH_HDR_SIZE; - ip_port->ip_mtu_max= ip_port->ip_mtu; - return 0; -} - -static void ipeth_main(ip_port) -ip_port_t *ip_port; -{ - int result; - - switch (ip_port->ip_dl.dl_eth.de_state) - { - case IES_EMPTY: - ip_port->ip_dl.dl_eth.de_state= IES_SETPROTO; - - result= eth_ioctl(ip_port->ip_dl.dl_eth.de_fd, NWIOSETHOPT); - if (result == NW_SUSPEND) - ip_port->ip_dl.dl_eth.de_flags |= IEF_SUSPEND; - if (result<0) - { - DBLOCK(1, printf("eth_ioctl(..,0x%lx)=%d\n", - (unsigned long)NWIOSETHOPT, result)); - return; - } - if (ip_port->ip_dl.dl_eth.de_state != IES_SETPROTO) - return; - /* drops through */ - case IES_SETPROTO: - result= arp_set_cb(ip_port->ip_dl.dl_eth.de_port, - ip_port->ip_port, - ipeth_arp_reply); - if (result != NW_OK) - { - printf("ipeth_main: arp_set_cb failed: %d\n", - result); - return; - } - - /* Wait until the interface is configured up. */ - ip_port->ip_dl.dl_eth.de_state= IES_GETIPADDR; - if (!(ip_port->ip_flags & IPF_IPADDRSET)) - { - ip_port->ip_dl.dl_eth.de_flags |= IEF_SUSPEND; - return; - } - - /* fall through */ - case IES_GETIPADDR: - ip_port->ip_dl.dl_eth.de_state= IES_MAIN; - do_eth_read(ip_port); - return; - default: - ip_panic(( "unknown state: %d", - ip_port->ip_dl.dl_eth.de_state)); - } -} - -static acc_t *get_eth_data (fd, offset, count, for_ioctl) -int fd; -size_t offset; -size_t count; -int for_ioctl; -{ - ip_port_t *ip_port; - acc_t *data; - int result; - - ip_port= &ip_port_table[fd]; - - switch (ip_port->ip_dl.dl_eth.de_state) - { - case IES_SETPROTO: - if (!count) - { - result= (int)offset; - if (result<0) - { - ip_port->ip_dl.dl_eth.de_state= IES_ERROR; - break; - } - if (ip_port->ip_dl.dl_eth.de_flags & IEF_SUSPEND) - ipeth_main(ip_port); - return NW_OK; - } - assert ((!offset) && (count == sizeof(struct nwio_ethopt))); - { - struct nwio_ethopt *ethopt; - acc_t *acc; - - acc= bf_memreq(sizeof(*ethopt)); - ethopt= (struct nwio_ethopt *)ptr2acc_data(acc); - ethopt->nweo_flags= NWEO_COPY|NWEO_EN_BROAD| - NWEO_EN_MULTI|NWEO_TYPESPEC; - ethopt->nweo_type= HTONS(ETH_IP_PROTO); - return acc; - } - - case IES_MAIN: - if (!count) - { - result= (int)offset; - if (result<0) - ip_warning(( "error on write: %d\n", result )); - bf_afree (ip_port->ip_dl.dl_eth.de_frame); - ip_port->ip_dl.dl_eth.de_frame= 0; - - if (ip_port->ip_dl.dl_eth.de_flags & IEF_WRITE_SP) - { - ip_port->ip_dl.dl_eth.de_flags &= - ~IEF_WRITE_SP; - ipeth_restart_send(ip_port); - } - return NW_OK; - } - data= bf_cut (ip_port->ip_dl.dl_eth.de_frame, offset, count); - assert (data); - return data; - default: - printf( - "get_eth_data(%d, 0x%d, 0x%d) called but ip_state=0x%x\n", - fd, offset, count, ip_port->ip_dl.dl_eth.de_state); - break; - } - return 0; -} - -static int put_eth_data (port, offset, data, for_ioctl) -int port; -size_t offset; -acc_t *data; -int for_ioctl; -{ - ip_port_t *ip_port; - int result; - - ip_port= &ip_port_table[port]; - - assert(0); - - if (ip_port->ip_dl.dl_eth.de_flags & IEF_READ_IP) - { - if (!data) - { - result= (int)offset; - if (result<0) - { - DBLOCK(1, printf( - "ip.c: put_eth_data(..,%d,..)\n", result)); - return NW_OK; - } - if (ip_port->ip_dl.dl_eth.de_flags & IEF_READ_SP) - { - ip_port->ip_dl.dl_eth.de_flags &= - ~(IEF_READ_IP|IEF_READ_SP); - do_eth_read(ip_port); - } - else - ip_port->ip_dl.dl_eth.de_flags &= ~IEF_READ_IP; - return NW_OK; - } - assert (!offset); - /* Warning: the above assertion is illegal; puts and - gets of data can be brokenup in any piece the server - likes. However we assume that the server is eth.c - and it transfers only whole packets. */ - ip_eth_arrived(port, data, bf_bufsize(data)); - return NW_OK; - } - printf("ip_port->ip_dl.dl_eth.de_state= 0x%x", - ip_port->ip_dl.dl_eth.de_state); - ip_panic (( "strange status" )); - return -1; -} - -static void ipeth_set_ipaddr(ip_port) -ip_port_t *ip_port; -{ - arp_set_ipaddr (ip_port->ip_dl.dl_eth.de_port, ip_port->ip_ipaddr); - if (ip_port->ip_dl.dl_eth.de_state == IES_GETIPADDR) - ipeth_main(ip_port); -} - -static int ipeth_send(ip_port, dest, pack, type) -struct ip_port *ip_port; -ipaddr_t dest; -acc_t *pack; -int type; -{ - int i, r; - acc_t *eth_pack, *tail; - size_t pack_size; - eth_hdr_t *eth_hdr; - xmit_hdr_t *xmit_hdr; - ipaddr_t tmpaddr; - time_t t; - u32_t *p; - - /* Start optimistic: the arp will succeed without blocking and the - * ethernet packet can be sent without blocking also. Start with - * the allocation of the ethernet header. - */ - eth_pack= bf_memreq(sizeof(*eth_hdr)); - assert(eth_pack->acc_next == NULL); - eth_pack->acc_next= pack; - pack_size= bf_bufsize(eth_pack); - if (pack_size= 0; i--, p++) - { - *p= 0xdeadbeef; - } - - eth_pack= bf_append(eth_pack, tail); - } - eth_hdr= (eth_hdr_t *)ptr2acc_data(eth_pack); - - /* Lookup the ethernet address */ - if (type != IP_LT_NORMAL) - { - if (type == IP_LT_BROADCAST) - eth_hdr->eh_dst= broadcast_ethaddr; - else - { - tmpaddr= ntohl(dest); - eth_hdr->eh_dst= ipmulticast_ethaddr; - eth_hdr->eh_dst.ea_addr[5]= tmpaddr & 0xff; - eth_hdr->eh_dst.ea_addr[4]= (tmpaddr >> 8) & 0xff; - eth_hdr->eh_dst.ea_addr[3]= (tmpaddr >> 16) & 0x7f; - } - } - else - { - if ((dest ^ ip_port->ip_ipaddr) & ip_port->ip_subnetmask) - { - ip_panic(( "invalid destination" )); - } - - assert(dest != ip_port->ip_ipaddr); - - r= arp_ip_eth(ip_port->ip_dl.dl_eth.de_port, - dest, ð_hdr->eh_dst); - if (r == NW_SUSPEND) - { - /* Unfortunately, the arp takes some time, use - * the ethernet header to store the next hop - * ip address and the current time. - */ - xmit_hdr= (xmit_hdr_t *)eth_hdr; - xmit_hdr->xh_time= get_time(); - xmit_hdr->xh_ipaddr= dest; - eth_pack->acc_ext_link= NULL; - if (ip_port->ip_dl.dl_eth.de_arp_head == NULL) - ip_port->ip_dl.dl_eth.de_arp_head= eth_pack; - else - { - ip_port->ip_dl.dl_eth.de_arp_tail-> - acc_ext_link= eth_pack; - } - ip_port->ip_dl.dl_eth.de_arp_tail= eth_pack; - return NW_OK; - } - if (r == EHOSTUNREACH) - { - bf_afree(eth_pack); - return r; - } - assert(r == NW_OK); - } - - /* If we have no write in progress, we can try to send the ethernet - * packet using eth_send. If the IP packet is larger than mtu, - * enqueue the packet and let ipeth_restart_send deal with it. - */ - pack_size= bf_bufsize(eth_pack); - if (ip_port->ip_dl.dl_eth.de_frame == NULL && pack_size <= - ip_port->ip_mtu + sizeof(*eth_hdr)) - { - r= eth_send(ip_port->ip_dl.dl_eth.de_fd, - eth_pack, pack_size); - if (r == NW_OK) - return NW_OK; - - /* A non-blocking send is not possible, start a regular - * send. - */ - assert(r == NW_WOULDBLOCK); - ip_port->ip_dl.dl_eth.de_frame= eth_pack; - r= eth_write(ip_port->ip_dl.dl_eth.de_fd, pack_size); - if (r == NW_SUSPEND) - { - assert(!(ip_port->ip_dl.dl_eth.de_flags & - IEF_WRITE_SP)); - ip_port->ip_dl.dl_eth.de_flags |= IEF_WRITE_SP; - } - assert(r == NW_OK || r == NW_SUSPEND); - return NW_OK; - } - - /* Enqueue the packet, and store the current time, in the - * space for the ethernet source address. - */ - t= get_time(); - assert(sizeof(t) <= sizeof(eth_hdr->eh_src)); - memcpy(ð_hdr->eh_src, &t, sizeof(t)); - - eth_pack->acc_ext_link= NULL; - if (ip_port->ip_dl.dl_eth.de_q_head == NULL) - ip_port->ip_dl.dl_eth.de_q_head= eth_pack; - else - { - ip_port->ip_dl.dl_eth.de_q_tail->acc_ext_link= eth_pack; - } - ip_port->ip_dl.dl_eth.de_q_tail= eth_pack; - if (ip_port->ip_dl.dl_eth.de_frame == NULL) - ipeth_restart_send(ip_port); - return NW_OK; -} - -static void ipeth_restart_send(ip_port) -ip_port_t *ip_port; -{ - time_t now, enq_time; - int i, r; - acc_t *eth_pack, *ip_pack, *next_eth_pack, *next_part, *tail; - size_t pack_size; - eth_hdr_t *eth_hdr, *next_eth_hdr; - u32_t *p; - - now= get_time(); - - while (ip_port->ip_dl.dl_eth.de_q_head != NULL) - { - eth_pack= ip_port->ip_dl.dl_eth.de_q_head; - ip_port->ip_dl.dl_eth.de_q_head= eth_pack->acc_ext_link; - - eth_hdr= (eth_hdr_t *)ptr2acc_data(eth_pack); - - pack_size= bf_bufsize(eth_pack); - - if (pack_size > ip_port->ip_mtu+sizeof(*eth_hdr)) - { - /* Split the IP packet */ - assert(eth_pack->acc_linkC == 1); - ip_pack= eth_pack->acc_next; eth_pack->acc_next= NULL; - next_part= ip_pack; ip_pack= NULL; - ip_pack= ip_split_pack(ip_port, &next_part, - ip_port->ip_mtu); - if (ip_pack == NULL) - { - bf_afree(eth_pack); - continue; - } - - eth_pack->acc_next= ip_pack; ip_pack= NULL; - - /* Allocate new ethernet header */ - next_eth_pack= bf_memreq(sizeof(*next_eth_hdr)); - next_eth_hdr= (eth_hdr_t *)ptr2acc_data(next_eth_pack); - *next_eth_hdr= *eth_hdr; - next_eth_pack->acc_next= next_part; - - next_eth_pack->acc_ext_link= NULL; - if (ip_port->ip_dl.dl_eth.de_q_head == NULL) - ip_port->ip_dl.dl_eth.de_q_head= next_eth_pack; - else - { - ip_port->ip_dl.dl_eth.de_q_tail->acc_ext_link= - next_eth_pack; - } - ip_port->ip_dl.dl_eth.de_q_tail= next_eth_pack; - - pack_size= bf_bufsize(eth_pack); - } - - memcpy(&enq_time, ð_hdr->eh_src, sizeof(enq_time)); - if (enq_time + HZ < now) - { - r= ipeth_update_ttl(enq_time, now, eth_pack); - if (r == ETIMEDOUT) - { - ip_pack= bf_delhead(eth_pack, sizeof(*eth_hdr)); - eth_pack= NULL; - icmp_snd_time_exceeded(ip_port->ip_port, - ip_pack, ICMP_TTL_EXC); - continue; - } - assert(r == NW_OK); - } - - if (pack_size= 0; i--, p++) - { - *p= 0xdeadbeef; - } - - eth_pack= bf_append(eth_pack, tail); - pack_size= ETH_MIN_PACK_SIZE; - } - - assert(ip_port->ip_dl.dl_eth.de_frame == NULL); - - r= eth_send(ip_port->ip_dl.dl_eth.de_fd, eth_pack, pack_size); - if (r == NW_OK) - continue; - - /* A non-blocking send is not possible, start a regular - * send. - */ - assert(r == NW_WOULDBLOCK); - ip_port->ip_dl.dl_eth.de_frame= eth_pack; - r= eth_write(ip_port->ip_dl.dl_eth.de_fd, pack_size); - if (r == NW_SUSPEND) - { - assert(!(ip_port->ip_dl.dl_eth.de_flags & - IEF_WRITE_SP)); - ip_port->ip_dl.dl_eth.de_flags |= IEF_WRITE_SP; - return; - } - assert(r == NW_OK); - } -} - - -static void ipeth_arp_reply(ip_port_nr, ipaddr, eth_addr) -int ip_port_nr; -ipaddr_t ipaddr; -ether_addr_t *eth_addr; -{ - acc_t *prev, *eth_pack; - int r; - xmit_hdr_t *xmit_hdr; - ip_port_t *ip_port; - time_t t; - eth_hdr_t *eth_hdr; - ether_addr_t tmp_eth_addr; - - assert (ip_port_nr >= 0 && ip_port_nr < ip_conf_nr); - ip_port= &ip_port_table[ip_port_nr]; - - for (;;) - { - for (prev= 0, eth_pack= ip_port->ip_dl.dl_eth.de_arp_head; - eth_pack; - prev= eth_pack, eth_pack= eth_pack->acc_ext_link) - { - xmit_hdr= (xmit_hdr_t *)ptr2acc_data(eth_pack); - if (xmit_hdr->xh_ipaddr == ipaddr) - break; - } - - if (eth_pack == NULL) - { - /* No packet found. */ - break; - } - - /* Delete packet from the queue. */ - if (prev == NULL) - { - ip_port->ip_dl.dl_eth.de_arp_head= - eth_pack->acc_ext_link; - } - else - { - prev->acc_ext_link= eth_pack->acc_ext_link; - if (prev->acc_ext_link == NULL) - ip_port->ip_dl.dl_eth.de_arp_tail= prev; - } - - if (eth_addr == NULL) - { - /* Destination is unreachable, delete packet. */ - bf_afree(eth_pack); - continue; - } - - /* Fill in the ethernet address and put the packet on the - * transmit queue. - */ - t= xmit_hdr->xh_time; - eth_hdr= (eth_hdr_t *)ptr2acc_data(eth_pack); - eth_hdr->eh_dst= *eth_addr; - memcpy(ð_hdr->eh_src, &t, sizeof(t)); - - eth_pack->acc_ext_link= NULL; - if (ip_port->ip_dl.dl_eth.de_q_head == NULL) - ip_port->ip_dl.dl_eth.de_q_head= eth_pack; - else - { - ip_port->ip_dl.dl_eth.de_q_tail->acc_ext_link= - eth_pack; - } - ip_port->ip_dl.dl_eth.de_q_tail= eth_pack; - } - - /* Try to get some more ARPs in progress. */ - while (ip_port->ip_dl.dl_eth.de_arp_head) - { - eth_pack= ip_port->ip_dl.dl_eth.de_arp_head; - xmit_hdr= (xmit_hdr_t *)ptr2acc_data(eth_pack); - r= arp_ip_eth(ip_port->ip_dl.dl_eth.de_port, - xmit_hdr->xh_ipaddr, &tmp_eth_addr); - if (r == NW_SUSPEND) - break; /* Normal case */ - - /* Dequeue the packet */ - ip_port->ip_dl.dl_eth.de_arp_head= eth_pack->acc_ext_link; - - if (r == EHOSTUNREACH) - { - bf_afree(eth_pack); - continue; - } - assert(r == NW_OK); - - /* Fill in the ethernet address and put the packet on the - * transmit queue. - */ - t= xmit_hdr->xh_time; - eth_hdr= (eth_hdr_t *)ptr2acc_data(eth_pack); - eth_hdr->eh_dst= tmp_eth_addr; - memcpy(ð_hdr->eh_src, &t, sizeof(t)); - - eth_pack->acc_ext_link= NULL; - if (ip_port->ip_dl.dl_eth.de_q_head == NULL) - ip_port->ip_dl.dl_eth.de_q_head= eth_pack; - else - { - ip_port->ip_dl.dl_eth.de_q_tail->acc_ext_link= - eth_pack; - } - ip_port->ip_dl.dl_eth.de_q_tail= eth_pack; - } - - /* Restart sending ethernet packets. */ - if (ip_port->ip_dl.dl_eth.de_frame == NULL) - ipeth_restart_send(ip_port); -} - -static int ipeth_update_ttl(enq_time, now, eth_pack) -time_t enq_time; -time_t now; -acc_t *eth_pack; -{ - int ttl_diff; - ip_hdr_t *ip_hdr; - u32_t sum; - u16_t word; - acc_t *ip_pack; - - ttl_diff= (now-enq_time)/HZ; - enq_time += ttl_diff*HZ; - assert(enq_time <= now && enq_time + HZ > now); - - ip_pack= eth_pack->acc_next; - assert(ip_pack->acc_length >= sizeof(*ip_hdr)); - assert(ip_pack->acc_linkC == 1 && - ip_pack->acc_buffer->buf_linkC == 1); - - ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_pack); - if (ip_hdr->ih_ttl <= ttl_diff) - return ETIMEDOUT; - sum= (u16_t)~ip_hdr->ih_hdr_chk; - word= *(u16_t *)&ip_hdr->ih_ttl; - if (word > sum) - sum += 0xffff - word; - else - sum -= word; - ip_hdr->ih_ttl -= ttl_diff; - word= *(u16_t *)&ip_hdr->ih_ttl; - sum += word; - if (sum > 0xffff) - sum -= 0xffff; - assert(!(sum & 0xffff0000)); - ip_hdr->ih_hdr_chk= ~sum; - assert(ip_hdr->ih_ttl > 0); - return NW_OK; -} - -static void do_eth_read(ip_port) -ip_port_t *ip_port; -{ - int result; - - assert(!(ip_port->ip_dl.dl_eth.de_flags & IEF_READ_IP)); - - for (;;) - { - ip_port->ip_dl.dl_eth.de_flags |= IEF_READ_IP; - - result= eth_read (ip_port->ip_dl.dl_eth.de_fd, - ETH_MAX_PACK_SIZE); - if (result == NW_SUSPEND) - { - assert(!(ip_port->ip_dl.dl_eth.de_flags & - IEF_READ_SP)); - ip_port->ip_dl.dl_eth.de_flags |= IEF_READ_SP; - return; - } - ip_port->ip_dl.dl_eth.de_flags &= ~IEF_READ_IP; - if (result<0) - { - return; - } - } -} - -static void ip_eth_arrived(port, pack, pack_size) -int port; -acc_t *pack; -size_t pack_size; -{ - int broadcast; - ip_port_t *ip_port; - - ip_port= &ip_port_table[port]; - broadcast= (*(u8_t *)ptr2acc_data(pack) & 1); - - pack= bf_delhead(pack, ETH_HDR_SIZE); - - if (broadcast) - ip_arrived_broadcast(ip_port, pack); - else - ip_arrived(ip_port, pack); -} - -/* - * $PchId: ip_eth.c,v 1.25 2005/06/28 14:18:10 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_int.h b/minix/net/inet/generic/ip_int.h deleted file mode 100644 index 95fcaec4a..000000000 --- a/minix/net/inet/generic/ip_int.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -ip_int.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET_IP_INT_H -#define INET_IP_INT_H - -#define IP_FD_NR (8*IP_PORT_MAX) -#define IP_ASS_NR 3 - -#define IP_42BSD_BCAST 1 /* hostnumber 0 is also network - broadcast */ - -#define IP_LT_NORMAL 0 /* Normal */ -#define IP_LT_BROADCAST 1 /* Broadcast */ -#define IP_LT_MULTICAST 2 /* Multicast */ - -struct ip_port; -struct ip_fd; -typedef void (*ip_dev_t) ARGS(( struct ip_port *ip_port )); -typedef int (*ip_dev_send_t) ARGS(( struct ip_port *ip_port, ipaddr_t dest, - acc_t *pack, int type )); - -#define IP_PROTO_HASH_NR 32 - -typedef struct ip_port -{ - int ip_flags, ip_dl_type; - int ip_port; - union sxfer_ip_dl_u - { - struct - { - int de_state; - int de_flags; - int de_port; - int de_fd; - acc_t *de_frame; - acc_t *de_q_head; - acc_t *de_q_tail; - acc_t *de_arp_head; - acc_t *de_arp_tail; - } dl_eth; - struct - { - int dummy_int[3]; - int ps_port; - acc_t *ps_send_head; - acc_t *ps_send_tail; - void* dummy_ptr[3]; - } dl_ps; - } ip_dl; - ipaddr_t ip_ipaddr; - ipaddr_t ip_subnetmask; - ipaddr_t ip_classfulmask; - u16_t ip_frame_id; - u16_t ip_mtu; - u16_t ip_mtu_max; /* Max MTU for this kind of network */ - ip_dev_t ip_dev_main; - ip_dev_t ip_dev_set_ipaddr; - ip_dev_send_t ip_dev_send; - acc_t *ip_loopb_head; - acc_t *ip_loopb_tail; - event_t ip_loopb_event; - acc_t *ip_routeq_head; - acc_t *ip_routeq_tail; - event_t ip_routeq_event; - struct ip_fd *ip_proto_any; - struct ip_fd *ip_proto[IP_PROTO_HASH_NR]; -} ip_port_t; - -#define IES_EMPTY 0x0 -#define IES_SETPROTO 0x1 -#define IES_GETIPADDR 0x2 -#define IES_MAIN 0x3 -#define IES_ERROR 0x4 - -#define IEF_EMPTY 0x1 -#define IEF_SUSPEND 0x8 -#define IEF_READ_IP 0x10 -#define IEF_READ_SP 0x20 -#define IEF_WRITE_SP 0x80 - -#define IPF_EMPTY 0x0 -#define IPF_CONFIGURED 0x1 -#define IPF_IPADDRSET 0x2 -#define IPF_NETMASKSET 0x4 -#define IPF_SUBNET_BCAST 0x8 /* Subset support subnet broadcasts */ - -#define IPDL_ETH NETTYPE_ETH -#define IPDL_PSIP NETTYPE_PSIP - -typedef struct ip_ass -{ - acc_t *ia_frags; - int ia_min_ttl; - ip_port_t *ia_port; - time_t ia_first_time; - ipaddr_t ia_srcaddr, ia_dstaddr; - int ia_proto, ia_id; -} ip_ass_t; - -typedef struct ip_fd -{ - int if_flags; - struct nwio_ipopt if_ipopt; - ip_port_t *if_port; - struct ip_fd *if_proto_next; - int if_srfd; - acc_t *if_rdbuf_head; - acc_t *if_rdbuf_tail; - get_userdata_t if_get_userdata; - put_userdata_t if_put_userdata; - put_pkt_t if_put_pkt; - select_res_t if_select_res; - time_t if_exp_time; - size_t if_rd_count; - ioreq_t if_ioctl; -} ip_fd_t; - -#define IFF_EMPTY 0x00 -#define IFF_INUSE 0x01 -#define IFF_OPTSET 0x02 -#define IFF_BUSY 0x0C -# define IFF_READ_IP 0x04 -# define IFF_IOCTL_IP 0x08 -#define IFF_SEL_READ 0x10 - -typedef enum nettype -{ - IPNT_ZERO, /* 0.xx.xx.xx */ - IPNT_CLASS_A, /* 1.xx.xx.xx .. 126.xx.xx.xx */ - IPNT_LOCAL, /* 127.xx.xx.xx */ - IPNT_CLASS_B, /* 128.xx.xx.xx .. 191.xx.xx.xx */ - IPNT_CLASS_C, /* 192.xx.xx.xx .. 223.xx.xx.xx */ - IPNT_CLASS_D, /* 224.xx.xx.xx .. 239.xx.xx.xx */ - IPNT_CLASS_E, /* 240.xx.xx.xx .. 247.xx.xx.xx */ - IPNT_MARTIAN, /* 248.xx.xx.xx .. 254.xx.xx.xx + others */ - IPNT_BROADCAST /* 255.255.255.255 */ -} nettype_t; - -struct nwio_ipconf; - -/* ip_eth.c */ -int ipeth_init ARGS(( ip_port_t *ip_port )); - -/* ip_ioctl.c */ -void ip_hash_proto ARGS(( ip_fd_t *ip_fd )); -void ip_unhash_proto ARGS(( ip_fd_t *ip_fd )); -int ip_setconf ARGS(( int ip_port, struct nwio_ipconf *ipconfp )); - -/* ip_lib.c */ -ipaddr_t ip_get_netmask ARGS(( ipaddr_t hostaddr )); -ipaddr_t ip_get_ifaddr ARGS(( int ip_port_nr )); -int ip_chk_hdropt ARGS(( u8_t *opt, int optlen )); -void ip_print_frags ARGS(( acc_t *acc )); -nettype_t ip_nettype ARGS(( ipaddr_t ipaddr )); -ipaddr_t ip_netmask ARGS(( nettype_t nettype )); -char *ip_nettoa ARGS(( nettype_t nettype )); - -/* ip_ps.c */ -int ipps_init ARGS(( ip_port_t *ip_port )); -void ipps_get ARGS(( int ip_port_nr )); -void ipps_put ARGS(( int ip_port_nr, ipaddr_t nexthop, acc_t *pack )); - -/* ip_read.c */ -void ip_port_arrive ARGS(( ip_port_t *port, acc_t *pack, ip_hdr_t *ip_hdr )); -void ip_arrived ARGS(( ip_port_t *port, acc_t *pack )); -void ip_arrived_broadcast ARGS(( ip_port_t *port, acc_t *pack )); -void ip_process_loopb ARGS(( event_t *ev, ev_arg_t arg )); -int ip_sel_read ARGS(( ip_fd_t *ip_fd )); -void ip_packet2user ARGS(( ip_fd_t *ip_fd, acc_t *pack, time_t exp_time, - size_t data_len )); - -/* ip_write.c */ -void dll_eth_write_frame ARGS(( ip_port_t *port )); -acc_t *ip_split_pack ARGS(( ip_port_t *ip_port, acc_t **ref_last, int mtu )); -void ip_hdr_chksum ARGS(( ip_hdr_t *ip_hdr, int ip_hdr_len )); - - -extern ip_fd_t ip_fd_table[IP_FD_NR]; -extern ip_port_t *ip_port_table; -extern ip_ass_t ip_ass_table[IP_ASS_NR]; - -#define NWIO_DEFAULT (NWIO_EN_LOC | NWIO_EN_BROAD | NWIO_REMANY | \ - NWIO_RWDATALL | NWIO_HDR_O_SPEC) - -#endif /* INET_IP_INT_H */ - -/* - * $PchId: ip_int.h,v 1.19 2004/08/03 16:24:23 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_ioctl.c b/minix/net/inet/generic/ip_ioctl.c deleted file mode 100644 index 4b63f3de3..000000000 --- a/minix/net/inet/generic/ip_ioctl.c +++ /dev/null @@ -1,678 +0,0 @@ -/* -ip_ioctl.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "event.h" -#include "type.h" - -#include "arp.h" -#include "assert.h" -#include "clock.h" -#include "icmp_lib.h" -#include "ip.h" -#include "ip_int.h" -#include "ipr.h" - -THIS_FILE - -static int ip_checkopt ARGS(( ip_fd_t *ip_fd )); -static void reply_thr_get ARGS(( ip_fd_t *ip_fd, size_t - reply, int for_ioctl )); -static void report_addr ARGS(( ip_port_t *ip_port )); - -int ip_ioctl (fd, req) -int fd; -ioreq_t req; -{ - ip_fd_t *ip_fd; - ip_port_t *ip_port; - nwio_ipopt_t *ipopt; - nwio_ipopt_t oldopt, newopt; - nwio_ipconf2_t *ipconf2; - nwio_ipconf_t *ipconf; - nwio_route_t *route_ent; - acc_t *data; - int result; - unsigned int new_en_flags, new_di_flags, - old_en_flags, old_di_flags; - unsigned long new_flags; - int ent_no, r; - nwio_ipconf_t ipconf_var; - - assert (fd>=0 && fdif_flags & IFF_INUSE); - - switch (req) - { - case NWIOSIPOPT: - ip_port= ip_fd->if_port; - - if (!(ip_port->ip_flags & IPF_IPADDRSET)) - { - ip_fd->if_ioctl= NWIOSIPOPT; - ip_fd->if_flags |= IFF_IOCTL_IP; - return NW_SUSPEND; - } - ip_fd->if_flags &= ~IFF_IOCTL_IP; - - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, - sizeof(nwio_ipopt_t), TRUE); - - data= bf_packIffLess (data, sizeof(nwio_ipopt_t)); - assert (data->acc_length == sizeof(nwio_ipopt_t)); - - ipopt= (nwio_ipopt_t *)ptr2acc_data(data); - oldopt= ip_fd->if_ipopt; - newopt= *ipopt; - - old_en_flags= oldopt.nwio_flags & 0xffff; - old_di_flags= (oldopt.nwio_flags >> 16) & 0xffff; - new_en_flags= newopt.nwio_flags & 0xffff; - new_di_flags= (newopt.nwio_flags >> 16) & 0xffff; - if (new_en_flags & new_di_flags) - { - bf_afree(data); - reply_thr_get (ip_fd, EBADMODE, TRUE); - return NW_OK; - } - - /* NWIO_ACC_MASK */ - if (new_di_flags & NWIO_ACC_MASK) - { - bf_afree(data); - reply_thr_get (ip_fd, EBADMODE, TRUE); - return NW_OK; - /* access modes can't be disable */ - } - - if (!(new_en_flags & NWIO_ACC_MASK)) - new_en_flags |= (old_en_flags & NWIO_ACC_MASK); - - /* NWIO_LOC_MASK */ - if (!((new_en_flags|new_di_flags) & NWIO_LOC_MASK)) - { - new_en_flags |= (old_en_flags & NWIO_LOC_MASK); - new_di_flags |= (old_di_flags & NWIO_LOC_MASK); - } - - /* NWIO_BROAD_MASK */ - if (!((new_en_flags|new_di_flags) & NWIO_BROAD_MASK)) - { - new_en_flags |= (old_en_flags & NWIO_BROAD_MASK); - new_di_flags |= (old_di_flags & NWIO_BROAD_MASK); - } - - /* NWIO_REM_MASK */ - if (!((new_en_flags|new_di_flags) & NWIO_REM_MASK)) - { - new_en_flags |= (old_en_flags & NWIO_REM_MASK); - new_di_flags |= (old_di_flags & NWIO_REM_MASK); - newopt.nwio_rem= oldopt.nwio_rem; - } - - /* NWIO_PROTO_MASK */ - if (!((new_en_flags|new_di_flags) & NWIO_PROTO_MASK)) - { - new_en_flags |= (old_en_flags & NWIO_PROTO_MASK); - new_di_flags |= (old_di_flags & NWIO_PROTO_MASK); - newopt.nwio_proto= oldopt.nwio_proto; - } - - /* NWIO_HDR_O_MASK */ - if (!((new_en_flags|new_di_flags) & NWIO_HDR_O_MASK)) - { - new_en_flags |= (old_en_flags & NWIO_HDR_O_MASK); - new_di_flags |= (old_di_flags & NWIO_HDR_O_MASK); - newopt.nwio_tos= oldopt.nwio_tos; - newopt.nwio_ttl= oldopt.nwio_ttl; - newopt.nwio_df= oldopt.nwio_df; - newopt.nwio_hdropt= oldopt.nwio_hdropt; - } - - /* NWIO_RW_MASK */ - if (!((new_en_flags|new_di_flags) & NWIO_RW_MASK)) - { - new_en_flags |= (old_en_flags & NWIO_RW_MASK); - new_di_flags |= (old_di_flags & NWIO_RW_MASK); - } - - new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags; - - if ((new_flags & NWIO_RWDATONLY) && (new_flags & - (NWIO_REMANY|NWIO_PROTOANY|NWIO_HDR_O_ANY))) - { - bf_afree(data); - reply_thr_get(ip_fd, EBADMODE, TRUE); - return NW_OK; - } - - if (ip_fd->if_flags & IFF_OPTSET) - ip_unhash_proto(ip_fd); - - newopt.nwio_flags= new_flags; - ip_fd->if_ipopt= newopt; - - result= ip_checkopt(ip_fd); - - if (result<0) - ip_fd->if_ipopt= oldopt; - - bf_afree(data); - reply_thr_get (ip_fd, result, TRUE); - return NW_OK; - - case NWIOGIPOPT: - data= bf_memreq(sizeof(nwio_ipopt_t)); - - ipopt= (nwio_ipopt_t *)ptr2acc_data(data); - - *ipopt= ip_fd->if_ipopt; - - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, - TRUE); - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, - (acc_t *)0, TRUE); - - case NWIOSIPCONF2: - case NWIOSIPCONF: - ip_port= ip_fd->if_port; - - if (req == NWIOSIPCONF2) - { - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, - sizeof(*ipconf2), TRUE); - data= bf_packIffLess (data, sizeof(*ipconf2)); - assert (data->acc_length == sizeof(*ipconf2)); - - ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data); - - ipconf= &ipconf_var; - ipconf->nwic_flags= ipconf2->nwic_flags; - ipconf->nwic_ipaddr= ipconf2->nwic_ipaddr; - ipconf->nwic_netmask= ipconf2->nwic_netmask; - ipconf->nwic_flags &= ~NWIC_MTU_SET; - } - else - { - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, - sizeof(*ipconf), TRUE); - data= bf_packIffLess (data, sizeof(*ipconf)); - assert (data->acc_length == sizeof(*ipconf)); - - ipconf= (nwio_ipconf_t *)ptr2acc_data(data); - } - r= ip_setconf(ip_port-ip_port_table, ipconf); - bf_afree(data); - return (*ip_fd->if_put_userdata)(ip_fd-> if_srfd, r, - (acc_t *)0, TRUE); - - case NWIOGIPCONF2: - ip_port= ip_fd->if_port; - - if (!(ip_port->ip_flags & IPF_IPADDRSET)) - { - ip_fd->if_ioctl= NWIOGIPCONF2; - ip_fd->if_flags |= IFF_IOCTL_IP; - return NW_SUSPEND; - } - ip_fd->if_flags &= ~IFF_IOCTL_IP; - data= bf_memreq(sizeof(nwio_ipconf_t)); - ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data); - ipconf2->nwic_flags= NWIC_IPADDR_SET; - ipconf2->nwic_ipaddr= ip_port->ip_ipaddr; - ipconf2->nwic_netmask= ip_port->ip_subnetmask; - if (ip_port->ip_flags & IPF_NETMASKSET) - ipconf2->nwic_flags |= NWIC_NETMASK_SET; - - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, - TRUE); - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, - (acc_t *)0, TRUE); - - case NWIOGIPCONF: - ip_port= ip_fd->if_port; - - if (!(ip_port->ip_flags & IPF_IPADDRSET)) - { - ip_fd->if_ioctl= NWIOGIPCONF; - ip_fd->if_flags |= IFF_IOCTL_IP; - return NW_SUSPEND; - } - ip_fd->if_flags &= ~IFF_IOCTL_IP; - data= bf_memreq(sizeof(*ipconf)); - ipconf= (nwio_ipconf_t *)ptr2acc_data(data); - ipconf->nwic_flags= NWIC_IPADDR_SET; - ipconf->nwic_ipaddr= ip_port->ip_ipaddr; - ipconf->nwic_netmask= ip_port->ip_subnetmask; - if (ip_port->ip_flags & IPF_NETMASKSET) - ipconf->nwic_flags |= NWIC_NETMASK_SET; - ipconf->nwic_mtu= ip_port->ip_mtu; - - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, - TRUE); - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, - (acc_t *)0, TRUE); - - case NWIOGIPOROUTE: - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - 0, sizeof(nwio_route_t), TRUE); - if (data == NULL) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - EFAULT, NULL, TRUE); - } - - data= bf_packIffLess (data, sizeof(nwio_route_t) ); - route_ent= (nwio_route_t *)ptr2acc_data(data); - ent_no= route_ent->nwr_ent_no; - bf_afree(data); - - data= bf_memreq(sizeof(nwio_route_t)); - route_ent= (nwio_route_t *)ptr2acc_data(data); - result= ipr_get_oroute(ent_no, route_ent); - if (result < 0) - bf_afree(data); - else - { - assert(result == NW_OK); - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, - data, TRUE); - } - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - result, (acc_t *)0, TRUE); - - case NWIOSIPOROUTE: - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - 0, sizeof(nwio_route_t), TRUE); - if (data == NULL) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - EFAULT, NULL, TRUE); - } - if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET)) - { - /* Interface is down, no changes allowed */ - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - ENETDOWN, NULL, TRUE); - } - - data= bf_packIffLess (data, sizeof(nwio_route_t) ); - route_ent= (nwio_route_t *)ptr2acc_data(data); - result= ipr_add_oroute(ip_fd->if_port-ip_port_table, - route_ent->nwr_dest, route_ent->nwr_netmask, - route_ent->nwr_gateway, (time_t)0, - route_ent->nwr_dist, route_ent->nwr_mtu, - !!(route_ent->nwr_flags & NWRF_STATIC), - route_ent->nwr_pref, NULL); - bf_afree(data); - - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - result, (acc_t *)0, TRUE); - - case NWIODIPOROUTE: - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - 0, sizeof(nwio_route_t), TRUE); - if (data == NULL) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - EFAULT, NULL, TRUE); - } - - data= bf_packIffLess (data, sizeof(nwio_route_t) ); - route_ent= (nwio_route_t *)ptr2acc_data(data); - result= ipr_del_oroute(ip_fd->if_port-ip_port_table, - route_ent->nwr_dest, route_ent->nwr_netmask, - route_ent->nwr_gateway, - !!(route_ent->nwr_flags & NWRF_STATIC)); - bf_afree(data); - - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - result, (acc_t *)0, TRUE); - - case NWIOGIPIROUTE: - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - 0, sizeof(nwio_route_t), TRUE); - if (data == NULL) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - EFAULT, NULL, TRUE); - } - - data= bf_packIffLess (data, sizeof(nwio_route_t) ); - route_ent= (nwio_route_t *)ptr2acc_data(data); - ent_no= route_ent->nwr_ent_no; - bf_afree(data); - - data= bf_memreq(sizeof(nwio_route_t)); - route_ent= (nwio_route_t *)ptr2acc_data(data); - result= ipr_get_iroute(ent_no, route_ent); - if (result < 0) - bf_afree(data); - else - { - assert(result == NW_OK); - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, - data, TRUE); - } - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - result, (acc_t *)0, TRUE); - - case NWIOSIPIROUTE: - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - 0, sizeof(nwio_route_t), TRUE); - if (data == NULL) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - EFAULT, NULL, TRUE); - } - if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET)) - { - /* Interface is down, no changes allowed */ - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - ENETDOWN, NULL, TRUE); - } - - data= bf_packIffLess (data, sizeof(nwio_route_t) ); - route_ent= (nwio_route_t *)ptr2acc_data(data); - result= ipr_add_iroute(ip_fd->if_port-ip_port_table, - route_ent->nwr_dest, route_ent->nwr_netmask, - route_ent->nwr_gateway, - (route_ent->nwr_flags & NWRF_UNREACHABLE) ? - IRTD_UNREACHABLE : route_ent->nwr_dist, - route_ent->nwr_mtu, - !!(route_ent->nwr_flags & NWRF_STATIC), NULL); - bf_afree(data); - - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - result, (acc_t *)0, TRUE); - - case NWIODIPIROUTE: - data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, - 0, sizeof(nwio_route_t), TRUE); - if (data == NULL) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - EFAULT, NULL, TRUE); - } - - data= bf_packIffLess (data, sizeof(nwio_route_t) ); - route_ent= (nwio_route_t *)ptr2acc_data(data); - result= ipr_del_iroute(ip_fd->if_port-ip_port_table, - route_ent->nwr_dest, route_ent->nwr_netmask, - route_ent->nwr_gateway, - !!(route_ent->nwr_flags & NWRF_STATIC)); - bf_afree(data); - - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - result, (acc_t *)0, TRUE); - - /* The following ARP ioctls are only valid if the - * underlying device is an ethernet. - */ - case NWIOARPGIP: - case NWIOARPGNEXT: - case NWIOARPSIP: - case NWIOARPDIP: - ip_port= ip_fd->if_port; - - if (ip_port->ip_dl_type != IPDL_ETH) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - ENOTTY, (acc_t *)0, TRUE); - } - - if (!(ip_port->ip_flags & IPF_IPADDRSET)) - { - ip_fd->if_ioctl= req; - ip_fd->if_flags |= IFF_IOCTL_IP; - printf("ip_ioctl: suspending ARP request\n"); - return NW_SUSPEND; - } - - result= arp_ioctl(ip_port->ip_dl.dl_eth.de_port, - ip_fd->if_srfd, req, ip_fd->if_get_userdata, - ip_fd->if_put_userdata); - assert (result != SUSPEND); - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, - (acc_t *)0, TRUE); - - default: - break; - } - DBLOCK(1, printf("replying ENOTTY: 0x%lx\n", req)); - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, ENOTTY, - (acc_t *)0, TRUE); -} - -void ip_hash_proto(ip_fd) -ip_fd_t *ip_fd; -{ - ip_port_t *ip_port; - int hash; - - ip_port= ip_fd->if_port; - if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY) - { - ip_fd->if_proto_next= ip_port->ip_proto_any; - ip_port->ip_proto_any= ip_fd; - } - else - { - hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1); - ip_fd->if_proto_next= ip_port->ip_proto[hash]; - ip_port->ip_proto[hash]= ip_fd; - } -} - -void ip_unhash_proto(ip_fd) -ip_fd_t *ip_fd; -{ - ip_port_t *ip_port; - ip_fd_t *prev, *curr, **ip_fd_p; - int hash; - - ip_port= ip_fd->if_port; - if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOANY) - { - ip_fd_p= &ip_port->ip_proto_any; - } - else - { - hash= ip_fd->if_ipopt.nwio_proto & (IP_PROTO_HASH_NR-1); - ip_fd_p= &ip_port->ip_proto[hash]; - } - for (prev= NULL, curr= *ip_fd_p; curr; - prev= curr, curr= curr->if_proto_next) - { - if (curr == ip_fd) - break; - } - assert(curr); - if (prev) - prev->if_proto_next= curr->if_proto_next; - else - *ip_fd_p= curr->if_proto_next; -} - -int ip_setconf(ip_port_nr, ipconf) -int ip_port_nr; -nwio_ipconf_t *ipconf; -{ - int i, do_report; - ip_port_t *ip_port; - ip_fd_t *ip_fd; - ipaddr_t ipaddr; - u32_t mtu; - - ip_port= &ip_port_table[ip_port_nr]; - - if (ipconf->nwic_flags & ~NWIC_FLAGS) - return EBADMODE; - - do_report= 0; - if (ipconf->nwic_flags & NWIC_MTU_SET) - { - mtu= ipconf->nwic_mtu; - if (mtu < IP_MIN_MTU || mtu > ip_port->ip_mtu_max) - return EINVAL; - ip_port->ip_mtu= mtu; - do_report= 1; - } - - if (ipconf->nwic_flags & NWIC_NETMASK_SET) - { - ip_port->ip_subnetmask= ipconf->nwic_netmask; - ip_port->ip_flags |= IPF_NETMASKSET|IPF_SUBNET_BCAST; - if (ntohl(ip_port->ip_subnetmask) >= 0xfffffffe) - ip_port->ip_flags &= ~IPF_SUBNET_BCAST; - do_report= 1; - } - if (ipconf->nwic_flags & NWIC_IPADDR_SET) - { - ipaddr= ipconf->nwic_ipaddr; - ip_port->ip_ipaddr= ipaddr; - ip_port->ip_flags |= IPF_IPADDRSET; - ip_port->ip_classfulmask= - ip_netmask(ip_nettype(ipaddr)); - if (!(ip_port->ip_flags & IPF_NETMASKSET)) - { - ip_port->ip_subnetmask= ip_port->ip_classfulmask; - } - if (ipaddr == HTONL(0x00000000)) - { - /* Special case. Use 0.0.0.0 to shutdown interface. */ - ip_port->ip_flags &= ~(IPF_IPADDRSET|IPF_NETMASKSET); - ip_port->ip_subnetmask= HTONL(0x00000000); - } - (*ip_port->ip_dev_set_ipaddr)(ip_port); - - /* revive calls waiting for an ip addresses */ - for (i=0, ip_fd= ip_fd_table; iif_flags & IFF_INUSE)) - continue; - if (ip_fd->if_port != ip_port) - continue; - if (ip_fd->if_flags & IFF_IOCTL_IP) - ip_ioctl (i, ip_fd->if_ioctl); - } - - do_report= 1; - } - - ipr_chk_itab(ip_port-ip_port_table, ip_port->ip_ipaddr, - ip_port->ip_subnetmask); - ipr_chk_otab(ip_port-ip_port_table, ip_port->ip_ipaddr, - ip_port->ip_subnetmask); - if (do_report) - report_addr(ip_port); - - return 0; -} - -static int ip_checkopt (ip_fd) -ip_fd_t *ip_fd; -{ -/* bug: we don't check access modes yet */ - - unsigned long flags; - unsigned int en_di_flags; - acc_t *pack; - int result; - - flags= ip_fd->if_ipopt.nwio_flags; - en_di_flags= (flags >>16) | (flags & 0xffff); - - if (flags & NWIO_HDR_O_SPEC) - { - result= ip_chk_hdropt (ip_fd->if_ipopt.nwio_hdropt.iho_data, - ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz); - if (result<0) - return result; - } - if ((en_di_flags & NWIO_ACC_MASK) && - (en_di_flags & NWIO_LOC_MASK) && - (en_di_flags & NWIO_BROAD_MASK) && - (en_di_flags & NWIO_REM_MASK) && - (en_di_flags & NWIO_PROTO_MASK) && - (en_di_flags & NWIO_HDR_O_MASK) && - (en_di_flags & NWIO_RW_MASK)) - { - ip_fd->if_flags |= IFF_OPTSET; - - ip_hash_proto(ip_fd); - } - - else - ip_fd->if_flags &= ~IFF_OPTSET; - - while (ip_fd->if_rdbuf_head) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - return NW_OK; -} - -static void reply_thr_get(ip_fd, reply, for_ioctl) -ip_fd_t *ip_fd; -size_t reply; -int for_ioctl; -{ - acc_t *result; - result= (ip_fd->if_get_userdata)(ip_fd->if_srfd, reply, - (size_t)0, for_ioctl); - assert (!result); -} - -static void report_addr(ip_port) -ip_port_t *ip_port; -{ - int i, hdr_len; - ip_fd_t *ip_fd; - acc_t *pack; - ip_hdr_t *ip_hdr; - - pack= bf_memreq(IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - - hdr_len= IP_MIN_HDR_SIZE; - ip_hdr->ih_vers_ihl= (IP_VERSION << 4) | (hdr_len/4); - ip_hdr->ih_tos= 0; - ip_hdr->ih_length= htons(ip_port->ip_mtu); - ip_hdr->ih_id= 0; - ip_hdr->ih_flags_fragoff= 0; - ip_hdr->ih_ttl= 0; - ip_hdr->ih_proto= 0; - ip_hdr->ih_src= ip_port->ip_ipaddr; - ip_hdr->ih_dst= ip_port->ip_subnetmask; - ip_hdr_chksum(ip_hdr, hdr_len); - - for (i=0, ip_fd= ip_fd_table; iif_flags & IFF_INUSE)) - { - continue; - } - if (ip_fd->if_port != ip_port) - { - continue; - } - - /* Deliver packet to user */ - pack->acc_linkC++; - ip_packet2user(ip_fd, pack, 255, IP_MIN_HDR_SIZE); - } - bf_afree(pack); pack= NULL; -} - -/* - * $PchId: ip_ioctl.c,v 1.22 2004/08/03 11:10:08 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_lib.c b/minix/net/inet/generic/ip_lib.c deleted file mode 100644 index 639ccb768..000000000 --- a/minix/net/inet/generic/ip_lib.c +++ /dev/null @@ -1,229 +0,0 @@ -/* -ip_lib.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "event.h" -#include "type.h" - -#include "assert.h" -#include "io.h" -#include "ip_int.h" - -THIS_FILE - -ipaddr_t ip_get_netmask (ipaddr_t hostaddr) -{ - return ip_netmask(ip_nettype(hostaddr)); -} - -int ip_chk_hdropt (u8_t *opt, int optlen) -{ - int i, security_present= FALSE, lose_source_present= FALSE, - strict_source_present= FALSE, record_route_present= FALSE, - timestamp_present= FALSE; - - assert (!(optlen & 3)); - i= 0; - while (i optlen) - { - DBLOCK(1, printf("option of wrong length\n")); - return EINVAL; - } - return NW_OK; -} - -void ip_print_frags(acc_t *acc) -{ -#if DEBUG - ip_hdr_t *ip_hdr; - int first; - - if (!acc) - printf("(null)"); - - for (first= 1; acc; acc= acc->acc_ext_link, first= 0) - { -assert (acc->acc_length >= IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(acc); - if (first) - { - writeIpAddr(ip_hdr->ih_src); - printf(" > "); - writeIpAddr(ip_hdr->ih_dst); - } - printf(" {%x:%d@%d%c}", ntohs(ip_hdr->ih_id), - ntohs(ip_hdr->ih_length), - (ntohs(ip_hdr->ih_flags_fragoff) & IH_FRAGOFF_MASK)*8, - (ntohs(ip_hdr->ih_flags_fragoff) & IH_MORE_FRAGS) ? - '+' : '\0'); - } -#endif -} - -ipaddr_t ip_get_ifaddr(int port_nr) -{ - assert(port_nr >= 0 && port_nr < ip_conf_nr); - - return ip_port_table[port_nr].ip_ipaddr; -} - -nettype_t ip_nettype(ipaddr_t ipaddr) -{ - u8_t highbyte; - nettype_t nettype; - - ipaddr= ntohl(ipaddr); - highbyte= (ipaddr >> 24) & 0xff; - if (highbyte == 0) - { - if (ipaddr == 0) - nettype= IPNT_ZERO; - else - nettype= IPNT_MARTIAN; - } - else if (highbyte < 127) - nettype= IPNT_CLASS_A; - else if (highbyte == 127) - nettype= IPNT_LOCAL; - else if (highbyte < 192) - nettype= IPNT_CLASS_B; - else if (highbyte < 224) - nettype= IPNT_CLASS_C; - else if (highbyte < 240) - nettype= IPNT_CLASS_D; - else if (highbyte < 248) - nettype= IPNT_CLASS_E; - else if (highbyte < 255) - nettype= IPNT_MARTIAN; - else - { - if (ipaddr == (ipaddr_t)-1) - nettype= IPNT_BROADCAST; - else - nettype= IPNT_MARTIAN; - } - return nettype; -} - -ipaddr_t ip_netmask(nettype_t nettype) -{ - switch(nettype) - { - case IPNT_ZERO: return HTONL(0x00000000); - case IPNT_CLASS_A: - case IPNT_LOCAL: return HTONL(0xff000000); - case IPNT_CLASS_B: return HTONL(0xffff0000); - case IPNT_CLASS_C: return HTONL(0xffffff00); - default: return HTONL(0xffffffff); - } -} - -#if 0 -char *ip_nettoa(nettype_t nettype) -{ - switch(nettype) - { - case IPNT_ZERO: return "zero"; - case IPNT_CLASS_A: return "class A"; - case IPNT_LOCAL: return "local"; - case IPNT_CLASS_B: return "class B"; - case IPNT_CLASS_C: return "class C"; - case IPNT_CLASS_D: return "class D"; - case IPNT_CLASS_E: return "class E"; - case IPNT_MARTIAN: return "martian"; - case IPNT_BROADCAST: return "broadcast"; - default: return ""; - } -} -#endif - -/* - * $PchId: ip_lib.c,v 1.10 2002/06/08 21:35:52 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_ps.c b/minix/net/inet/generic/ip_ps.c deleted file mode 100644 index f3b69c8e5..000000000 --- a/minix/net/inet/generic/ip_ps.c +++ /dev/null @@ -1,275 +0,0 @@ -/* -generic/ip_ps.c - -pseudo IP specific part of the IP implementation - -Created: Apr 23, 1993 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "assert.h" -#include "type.h" -#include "buf.h" -#include "event.h" -#include "ip.h" -#include "ip_int.h" -#include "psip.h" - -THIS_FILE - -static void ipps_main ARGS(( ip_port_t *ip_port )); -static void ipps_set_ipaddr ARGS(( ip_port_t *ip_port )); -static int ipps_send ARGS(( struct ip_port *ip_port, ipaddr_t dest, - acc_t *pack, int type )); - -int ipps_init(ip_port) -ip_port_t *ip_port; -{ - int result; - - result= psip_enable(ip_port->ip_dl.dl_ps.ps_port, ip_port->ip_port); - if (result == -1) - return -1; - ip_port->ip_dl.dl_ps.ps_send_head= NULL; - ip_port->ip_dl.dl_ps.ps_send_tail= NULL; - ip_port->ip_dev_main= ipps_main; - ip_port->ip_dev_set_ipaddr= ipps_set_ipaddr; - ip_port->ip_dev_send= ipps_send; - return result; -} - -void ipps_get(ip_port_nr) -int ip_port_nr; -{ - int result; - ipaddr_t dest; - acc_t *acc, *pack, *next_part; - ip_port_t *ip_port; - - assert(ip_port_nr >= 0 && ip_port_nr < ip_conf_nr); - ip_port= &ip_port_table[ip_port_nr]; - assert(ip_port->ip_dl_type == IPDL_PSIP); - - while (ip_port->ip_dl.dl_ps.ps_send_head != NULL) - { - pack= ip_port->ip_dl.dl_ps.ps_send_head; - ip_port->ip_dl.dl_ps.ps_send_head= pack->acc_ext_link; - - /* Extract nexthop address */ - pack= bf_packIffLess(pack, sizeof(dest)); - dest= *(ipaddr_t *)ptr2acc_data(pack); - pack= bf_delhead(pack, sizeof(dest)); - - if (bf_bufsize(pack) > ip_port->ip_mtu) - { - next_part= pack; - pack= ip_split_pack(ip_port, &next_part, - ip_port->ip_mtu); - if (pack == NULL) - continue; - - /* Prepend nexthop address */ - acc= bf_memreq(sizeof(dest)); - *(ipaddr_t *)(ptr2acc_data(acc))= dest; - acc->acc_next= next_part; - next_part= acc; acc= NULL; - - assert(next_part->acc_linkC == 1); - next_part->acc_ext_link= NULL; - if (ip_port->ip_dl.dl_ps.ps_send_head) - { - ip_port->ip_dl.dl_ps.ps_send_tail-> - acc_ext_link= next_part; - } - else - { - ip_port->ip_dl.dl_ps.ps_send_head= - next_part; - } - ip_port->ip_dl.dl_ps.ps_send_tail= next_part; - } - - result= psip_send(ip_port->ip_dl.dl_ps.ps_port, dest, pack); - if (result != NW_SUSPEND) - { - assert(result == NW_OK); - continue; - } - - /* Prepend nexthop address */ - acc= bf_memreq(sizeof(dest)); - *(ipaddr_t *)(ptr2acc_data(acc))= dest; - acc->acc_next= pack; - pack= acc; acc= NULL; - - pack->acc_ext_link= ip_port->ip_dl.dl_ps.ps_send_head; - ip_port->ip_dl.dl_ps.ps_send_head= pack; - if (pack->acc_ext_link == NULL) - ip_port->ip_dl.dl_ps.ps_send_tail= pack; - break; - } -} - -void ipps_put(ip_port_nr, nexthop, pack) -int ip_port_nr; -ipaddr_t nexthop; -acc_t *pack; -{ - ip_port_t *ip_port; - - assert(ip_port_nr >= 0 && ip_port_nr < ip_conf_nr); - ip_port= &ip_port_table[ip_port_nr]; - assert(ip_port->ip_dl_type == IPDL_PSIP); - if (nexthop == HTONL(0xffffffff)) - ip_arrived_broadcast(ip_port, pack); - else - ip_arrived(ip_port, pack); -} - -static void ipps_main(ip_port) -ip_port_t *ip_port; -{ - /* nothing to do */ -} - -static void ipps_set_ipaddr(ip_port) -ip_port_t *ip_port; -{ -} - -static int ipps_send(ip_port, dest, pack, type) -struct ip_port *ip_port; -ipaddr_t dest; -acc_t *pack; -int type; -{ - int result; - acc_t *acc, *next_part; - - if (type != IP_LT_NORMAL) - { - ip_arrived_broadcast(ip_port, bf_dupacc(pack)); - - /* Map all broadcasts to the on-link broadcast address. - * This saves the application from having to to find out - * if the destination is a subnet broadcast. - */ - dest= HTONL(0xffffffff); - } - - /* Note that allocating a packet may trigger a cleanup action, - * which may cause the send queue to become empty. - */ - while (ip_port->ip_dl.dl_ps.ps_send_head != NULL) - { - acc= bf_memreq(sizeof(dest)); - - if (ip_port->ip_dl.dl_ps.ps_send_head == NULL) - { - bf_afree(acc); acc= NULL; - continue; - } - - /* Prepend nexthop address */ - *(ipaddr_t *)(ptr2acc_data(acc))= dest; - acc->acc_next= pack; - pack= acc; acc= NULL; - - assert(pack->acc_linkC == 1); - pack->acc_ext_link= NULL; - - ip_port->ip_dl.dl_ps.ps_send_tail->acc_ext_link= pack; - ip_port->ip_dl.dl_ps.ps_send_tail= pack; - - return NW_OK; - } - - while (pack) - { - if (bf_bufsize(pack) > ip_port->ip_mtu) - { - next_part= pack; - pack= ip_split_pack(ip_port, &next_part, - ip_port->ip_mtu); - if (pack == NULL) - { - return NW_OK; - } - - /* Prepend nexthop address */ - acc= bf_memreq(sizeof(dest)); - *(ipaddr_t *)(ptr2acc_data(acc))= dest; - acc->acc_next= next_part; - next_part= acc; acc= NULL; - - assert(next_part->acc_linkC == 1); - next_part->acc_ext_link= NULL; - ip_port->ip_dl.dl_ps.ps_send_head= next_part; - ip_port->ip_dl.dl_ps.ps_send_tail= next_part; - } - result= psip_send(ip_port->ip_dl.dl_ps.ps_port, dest, pack); - if (result == NW_SUSPEND) - { - /* Prepend nexthop address */ - acc= bf_memreq(sizeof(dest)); - *(ipaddr_t *)(ptr2acc_data(acc))= dest; - acc->acc_next= pack; - pack= acc; acc= NULL; - - assert(pack->acc_linkC == 1); - pack->acc_ext_link= ip_port->ip_dl.dl_ps.ps_send_head; - ip_port->ip_dl.dl_ps.ps_send_head= pack; - if (!pack->acc_ext_link) - ip_port->ip_dl.dl_ps.ps_send_tail= pack; - break; - } - assert(result == NW_OK); - pack= ip_port->ip_dl.dl_ps.ps_send_head; - if (!pack) - break; - ip_port->ip_dl.dl_ps.ps_send_head= pack->acc_ext_link; - - /* Extract nexthop address */ - pack= bf_packIffLess(pack, sizeof(dest)); - dest= *(ipaddr_t *)ptr2acc_data(pack); - pack= bf_delhead(pack, sizeof(dest)); - } - - return NW_OK; -} - -#if 0 -int ipps_check(ip_port_t *ip_port) -{ - int n, bad; - acc_t *prev, *curr; - - for (n= 0, prev= NULL, curr= ip_port->ip_dl.dl_ps.ps_send_head_; - curr; prev= curr, curr= curr->acc_ext_link) - { - n++; - } - bad= 0; - if (prev != NULL && prev != ip_port->ip_dl.dl_ps.ps_send_tail_) - { - printf("ipps_check, ip[%d]: wrong tail: got %p, expected %p\n", - ip_port-ip_port_table, - ip_port->ip_dl.dl_ps.ps_send_tail_, prev); - bad++; - } - if (n != ip_port->ip_dl.dl_ps.ps_send_nr) - { - printf("ipps_check, ip[%d]: wrong count: got %d, expected %d\n", - ip_port-ip_port_table, - ip_port->ip_dl.dl_ps.ps_send_nr, n); - bad++; - } - return bad == 0; -} -#endif - -/* - * $PchId: ip_ps.c,v 1.15 2003/01/21 15:57:52 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_read.c b/minix/net/inet/generic/ip_read.c deleted file mode 100644 index 5c8926d08..000000000 --- a/minix/net/inet/generic/ip_read.c +++ /dev/null @@ -1,1074 +0,0 @@ -/* -ip_read.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "type.h" - -#include "assert.h" -#include "icmp_lib.h" -#include "io.h" -#include "ip.h" -#include "ip_int.h" -#include "ipr.h" -#include "sr.h" - -THIS_FILE - -static ip_ass_t *find_ass_ent ARGS(( ip_port_t *ip_port, u16_t id, - ipproto_t proto, ipaddr_t src, ipaddr_t dst )); -static acc_t *merge_frags ARGS(( acc_t *first, acc_t *second )); -static int ip_frag_chk ARGS(( acc_t *pack )); -static acc_t *reassemble ARGS(( ip_port_t *ip_port, acc_t *pack, - ip_hdr_t *ip_hdr )); -static void route_packets ARGS(( event_t *ev, ev_arg_t ev_arg )); -static int broadcast_dst ARGS(( ip_port_t *ip_port, ipaddr_t dest )); - -int ip_read(int fd, size_t count) -{ - ip_fd_t *ip_fd; - acc_t *pack; - - ip_fd= &ip_fd_table[fd]; - if (!(ip_fd->if_flags & IFF_OPTSET)) - { - return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, EBADMODE, - (acc_t *)0, FALSE); - } - - ip_fd->if_rd_count= count; - - ip_fd->if_flags |= IFF_READ_IP; - if (ip_fd->if_rdbuf_head) - { - if (get_time() <= ip_fd->if_exp_time) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - ip_packet2user (ip_fd, pack, ip_fd->if_exp_time, - bf_bufsize(pack)); - assert(!(ip_fd->if_flags & IFF_READ_IP)); - return NW_OK; - } - while (ip_fd->if_rdbuf_head) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - } - return NW_SUSPEND; -} - -static acc_t *reassemble (ip_port, pack, pack_hdr) -ip_port_t *ip_port; -acc_t *pack; -ip_hdr_t *pack_hdr; -{ - ip_ass_t *ass_ent; - size_t pack_offset, tmp_offset; - u16_t pack_flags_fragoff; - acc_t *prev_acc, *curr_acc, *next_acc, *head_acc, *tmp_acc; - ip_hdr_t *tmp_hdr; - time_t first_time; - - ass_ent= find_ass_ent (ip_port, pack_hdr->ih_id, - pack_hdr->ih_proto, pack_hdr->ih_src, pack_hdr->ih_dst); - - pack_flags_fragoff= ntohs(pack_hdr->ih_flags_fragoff); - pack_offset= (pack_flags_fragoff & IH_FRAGOFF_MASK)*8; - pack->acc_ext_link= NULL; - - head_acc= ass_ent->ia_frags; - ass_ent->ia_frags= NULL; - if (head_acc == NULL) - { - ass_ent->ia_frags= pack; - return NULL; - } - - prev_acc= NULL; - curr_acc= NULL; - next_acc= head_acc; - - while(next_acc) - { - tmp_hdr= (ip_hdr_t *)ptr2acc_data(next_acc); - tmp_offset= (ntohs(tmp_hdr->ih_flags_fragoff) & - IH_FRAGOFF_MASK)*8; - - if (pack_offset < tmp_offset) - break; - - prev_acc= curr_acc; - curr_acc= next_acc; - next_acc= next_acc->acc_ext_link; - } - if (curr_acc == NULL) - { - assert(prev_acc == NULL); - assert(next_acc != NULL); - - curr_acc= merge_frags(pack, next_acc); - head_acc= curr_acc; - } - else - { - curr_acc= merge_frags(curr_acc, pack); - if (next_acc != NULL) - curr_acc= merge_frags(curr_acc, next_acc); - if (prev_acc != NULL) - prev_acc->acc_ext_link= curr_acc; - else - head_acc= curr_acc; - } - ass_ent->ia_frags= head_acc; - - pack= ass_ent->ia_frags; - pack_hdr= (ip_hdr_t *)ptr2acc_data(pack); - pack_flags_fragoff= ntohs(pack_hdr->ih_flags_fragoff); - - if (!(pack_flags_fragoff & (IH_FRAGOFF_MASK|IH_MORE_FRAGS))) - /* it's now a complete packet */ - { - first_time= ass_ent->ia_first_time; - - ass_ent->ia_frags= 0; - ass_ent->ia_first_time= 0; - - while (pack->acc_ext_link) - { - tmp_acc= pack->acc_ext_link; - pack->acc_ext_link= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - } - if ((ass_ent->ia_min_ttl) * HZ + first_time < - get_time()) - { - if (broadcast_dst(ip_port, pack_hdr->ih_dst)) - { - DBLOCK(1, printf( - "ip_read'reassemble: reassembly timeout for broadcast packet\n");); - bf_afree(pack); pack= NULL; - return NULL; - } - icmp_snd_time_exceeded(ip_port->ip_port, pack, - ICMP_FRAG_REASSEM); - } - else - return pack; - } - return NULL; -} - -static acc_t *merge_frags (first, second) -acc_t *first, *second; -{ - ip_hdr_t *first_hdr, *second_hdr; - size_t first_hdr_size, second_hdr_size, first_datasize, second_datasize, - first_offset, second_offset; - acc_t *cut_second, *tmp_acc; - - if (!second) - { - first->acc_ext_link= NULL; - return first; - } - -assert (first->acc_length >= IP_MIN_HDR_SIZE); -assert (second->acc_length >= IP_MIN_HDR_SIZE); - - first_hdr= (ip_hdr_t *)ptr2acc_data(first); - first_offset= (ntohs(first_hdr->ih_flags_fragoff) & - IH_FRAGOFF_MASK) * 8; - first_hdr_size= (first_hdr->ih_vers_ihl & IH_IHL_MASK) * 4; - first_datasize= ntohs(first_hdr->ih_length) - first_hdr_size; - - second_hdr= (ip_hdr_t *)ptr2acc_data(second); - second_offset= (ntohs(second_hdr->ih_flags_fragoff) & - IH_FRAGOFF_MASK) * 8; - second_hdr_size= (second_hdr->ih_vers_ihl & IH_IHL_MASK) * 4; - second_datasize= ntohs(second_hdr->ih_length) - second_hdr_size; - - assert (first_hdr_size + first_datasize == bf_bufsize(first)); - assert (second_hdr_size + second_datasize == bf_bufsize(second)); - assert (second_offset >= first_offset); - - if (second_offset > first_offset+first_datasize) - { - DBLOCK(1, printf("ip fragments out of order\n")); - first->acc_ext_link= second; - return first; - } - - if (second_offset + second_datasize <= first_offset + - first_datasize) - { - /* May cause problems if we try to merge. */ - bf_afree(first); - return second; - } - - if (!(second_hdr->ih_flags_fragoff & HTONS(IH_MORE_FRAGS))) - first_hdr->ih_flags_fragoff &= ~HTONS(IH_MORE_FRAGS); - - second_datasize= second_offset+second_datasize-(first_offset+ - first_datasize); - cut_second= bf_cut(second, second_hdr_size + first_offset+ - first_datasize-second_offset, second_datasize); - tmp_acc= second->acc_ext_link; - bf_afree(second); - second= tmp_acc; - - first_datasize += second_datasize; - first_hdr->ih_length= htons(first_hdr_size + first_datasize); - - first= bf_append (first, cut_second); - first->acc_ext_link= second; - -assert (first_hdr_size + first_datasize == bf_bufsize(first)); - - return first; -} - -static ip_ass_t *find_ass_ent ARGS(( ip_port_t *ip_port, u16_t id, - ipproto_t proto, ipaddr_t src, ipaddr_t dst )) -{ - ip_ass_t *new_ass_ent, *tmp_ass_ent; - int i; - acc_t *tmp_acc, *curr_acc; - - new_ass_ent= 0; - - for (i=0, tmp_ass_ent= ip_ass_table; iia_frags && tmp_ass_ent->ia_first_time) - { - DBLOCK(1, - printf("strange ip_ass entry (can be a race condition)\n")); - continue; - } - - if ((tmp_ass_ent->ia_srcaddr == src) && - (tmp_ass_ent->ia_dstaddr == dst) && - (tmp_ass_ent->ia_proto == proto) && - (tmp_ass_ent->ia_id == id) && - (tmp_ass_ent->ia_port == ip_port)) - { - return tmp_ass_ent; - } - if (!new_ass_ent || tmp_ass_ent->ia_first_time < - new_ass_ent->ia_first_time) - { - new_ass_ent= tmp_ass_ent; - } - } - - if (new_ass_ent->ia_frags) - { - DBLOCK(2, printf("old frags id= %u, proto= %u, src= ", - ntohs(new_ass_ent->ia_id), - new_ass_ent->ia_proto); - writeIpAddr(new_ass_ent->ia_srcaddr); printf(" dst= "); - writeIpAddr(new_ass_ent->ia_dstaddr); printf(": "); - ip_print_frags(new_ass_ent->ia_frags); printf("\n")); - curr_acc= new_ass_ent->ia_frags->acc_ext_link; - while (curr_acc) - { - tmp_acc= curr_acc->acc_ext_link; - bf_afree(curr_acc); - curr_acc= tmp_acc; - } - curr_acc= new_ass_ent->ia_frags; - new_ass_ent->ia_frags= 0; - if (broadcast_dst(ip_port, new_ass_ent->ia_dstaddr)) - { - DBLOCK(1, printf( - "ip_read'find_ass_ent: reassembly timeout for broadcast packet\n")); - bf_afree(curr_acc); curr_acc= NULL; - } - else - { - icmp_snd_time_exceeded(ip_port->ip_port, - curr_acc, ICMP_FRAG_REASSEM); - } - } - new_ass_ent->ia_min_ttl= IP_MAX_TTL; - new_ass_ent->ia_port= ip_port; - new_ass_ent->ia_first_time= get_time(); - new_ass_ent->ia_srcaddr= src; - new_ass_ent->ia_dstaddr= dst; - new_ass_ent->ia_proto= proto; - new_ass_ent->ia_id= id; - - return new_ass_ent; -} - -static int ip_frag_chk(pack) -acc_t *pack; -{ - ip_hdr_t *ip_hdr; - int hdr_len; - - if (pack->acc_length < sizeof(ip_hdr_t)) - { - DBLOCK(1, printf("wrong length\n")); - return FALSE; - } - - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - - hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) * 4; - if (pack->acc_length < hdr_len) - { - DBLOCK(1, printf("wrong length\n")); - - return FALSE; - } - - if (((ip_hdr->ih_vers_ihl >> 4) & IH_VERSION_MASK) != - IP_VERSION) - { - DBLOCK(1, printf("wrong version (ih_vers_ihl=0x%x)\n", - ip_hdr->ih_vers_ihl)); - return FALSE; - } - if (ntohs(ip_hdr->ih_length) != bf_bufsize(pack)) - { - DBLOCK(1, printf("wrong size\n")); - - return FALSE; - } - if ((u16_t)~oneC_sum(0, (u16_t *)ip_hdr, hdr_len)) - { - DBLOCK(1, printf("packet with wrong checksum (= %x)\n", - (u16_t)~oneC_sum(0, (u16_t *)ip_hdr, hdr_len))); - return FALSE; - } - if (hdr_len>IP_MIN_HDR_SIZE && ip_chk_hdropt((u8_t *) - (ptr2acc_data(pack) + IP_MIN_HDR_SIZE), - hdr_len-IP_MIN_HDR_SIZE)) - { - DBLOCK(1, printf("packet with wrong options\n")); - return FALSE; - } - return TRUE; -} - -int ip_sel_read (ip_fd_t *ip_fd) -{ - acc_t *pack; - - if (!(ip_fd->if_flags & IFF_OPTSET)) - return 1; /* Read will not block */ - - if (ip_fd->if_rdbuf_head) - { - if (get_time() <= ip_fd->if_exp_time) - return 1; - - while (ip_fd->if_rdbuf_head) - { - pack= ip_fd->if_rdbuf_head; - ip_fd->if_rdbuf_head= pack->acc_ext_link; - bf_afree(pack); - } - } - return 0; -} - -void ip_packet2user (ip_fd, pack, exp_time, data_len) -ip_fd_t *ip_fd; -acc_t *pack; -time_t exp_time; -size_t data_len; -{ - acc_t *tmp_pack; - ip_hdr_t *ip_hdr; - int result, ip_hdr_len; - size_t transf_size; - - assert (ip_fd->if_flags & IFF_INUSE); - if (!(ip_fd->if_flags & IFF_READ_IP)) - { - if (pack->acc_linkC != 1) - { - tmp_pack= bf_dupacc(pack); - bf_afree(pack); - pack= tmp_pack; - tmp_pack= NULL; - } - pack->acc_ext_link= NULL; - if (ip_fd->if_rdbuf_head == NULL) - { - ip_fd->if_rdbuf_head= pack; - ip_fd->if_exp_time= exp_time; - } - else - ip_fd->if_rdbuf_tail->acc_ext_link= pack; - ip_fd->if_rdbuf_tail= pack; - - if (ip_fd->if_flags & IFF_SEL_READ) - { - ip_fd->if_flags &= ~IFF_SEL_READ; - if (ip_fd->if_select_res) - ip_fd->if_select_res(ip_fd->if_srfd, - SR_SELECT_READ); - else - printf("ip_packet2user: no select_res\n"); - } - return; - } - - assert (pack->acc_length >= IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - - if (ip_fd->if_ipopt.nwio_flags & NWIO_RWDATONLY) - { - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) * 4; - - assert (data_len > ip_hdr_len); - data_len -= ip_hdr_len; - pack= bf_delhead(pack, ip_hdr_len); - } - - if (data_len > ip_fd->if_rd_count) - { - tmp_pack= bf_cut (pack, 0, ip_fd->if_rd_count); - bf_afree(pack); - pack= tmp_pack; - transf_size= ip_fd->if_rd_count; - } - else - transf_size= data_len; - - if (ip_fd->if_put_pkt) - { - (*ip_fd->if_put_pkt)(ip_fd->if_srfd, pack, transf_size); - return; - } - - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, - (size_t)0, pack, FALSE); - if (result >= 0) - { - if (data_len > transf_size) - result= EPACKSIZE; - else - result= transf_size; - } - - ip_fd->if_flags &= ~IFF_READ_IP; - result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, - (acc_t *)0, FALSE); - assert (result >= 0); -} - -void ip_port_arrive (ip_port, pack, ip_hdr) -ip_port_t *ip_port; -acc_t *pack; -ip_hdr_t *ip_hdr; -{ - ip_fd_t *ip_fd, *first_fd, *share_fd; - unsigned long ip_pack_stat; - unsigned size; - int i; - int hash, proto; - time_t exp_time; - - assert (pack->acc_linkC>0); - assert (pack->acc_length >= IP_MIN_HDR_SIZE); - - if (ntohs(ip_hdr->ih_flags_fragoff) & (IH_FRAGOFF_MASK|IH_MORE_FRAGS)) - { - pack= reassemble (ip_port, pack, ip_hdr); - if (!pack) - return; - assert (pack->acc_length >= IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - assert (!(ntohs(ip_hdr->ih_flags_fragoff) & - (IH_FRAGOFF_MASK|IH_MORE_FRAGS))); - } - size= ntohs(ip_hdr->ih_length); - if (size > bf_bufsize(pack)) - { - /* Should discard packet */ - assert(0); - bf_afree(pack); pack= NULL; - return; - } - - exp_time= get_time() + (ip_hdr->ih_ttl+1) * HZ; - - if (ip_hdr->ih_dst == ip_port->ip_ipaddr) - ip_pack_stat= NWIO_EN_LOC; - else - ip_pack_stat= NWIO_EN_BROAD; - - proto= ip_hdr->ih_proto; - hash= proto & (IP_PROTO_HASH_NR-1); - - first_fd= NULL; - for (i= 0; i<2; i++) - { - share_fd= NULL; - - ip_fd= (i == 0) ? ip_port->ip_proto_any : - ip_port->ip_proto[hash]; - for (; ip_fd; ip_fd= ip_fd->if_proto_next) - { - if (i && ip_fd->if_ipopt.nwio_proto != proto) - continue; - if (!(ip_fd->if_ipopt.nwio_flags & ip_pack_stat)) - continue; - if ((ip_fd->if_ipopt.nwio_flags & NWIO_REMSPEC) && - ip_hdr->ih_src != ip_fd->if_ipopt.nwio_rem) - { - continue; - } - if ((ip_fd->if_ipopt.nwio_flags & NWIO_ACC_MASK) == - NWIO_SHARED) - { - if (!share_fd) - { - share_fd= ip_fd; - continue; - } - if (!ip_fd->if_rdbuf_head) - share_fd= ip_fd; - continue; - } - if (!first_fd) - { - first_fd= ip_fd; - continue; - } - pack->acc_linkC++; - ip_packet2user(ip_fd, pack, exp_time, size); - - } - if (share_fd) - { - pack->acc_linkC++; - ip_packet2user(share_fd, pack, exp_time, size); - } - } - if (first_fd) - { - if (first_fd->if_put_pkt && - (first_fd->if_flags & IFF_READ_IP) && - !(first_fd->if_ipopt.nwio_flags & NWIO_RWDATONLY)) - { - (*first_fd->if_put_pkt)(first_fd->if_srfd, pack, - size); - } - else - ip_packet2user(first_fd, pack, exp_time, size); - } - else - { - if (ip_pack_stat == NWIO_EN_LOC) - { - DBLOCK(0x01, - printf("ip_port_arrive: dropping packet for proto %d\n", - proto)); - } - else - { - DBLOCK(0x20, printf("dropping packet for proto %d\n", - proto)); - } - bf_afree(pack); - } -} - -void ip_arrived(ip_port, pack) -ip_port_t *ip_port; -acc_t *pack; -{ - ip_hdr_t *ip_hdr; - ipaddr_t dest; - int ip_frag_len, ip_hdr_len, highbyte; - size_t pack_size; - acc_t *tmp_pack, *hdr_pack; - ev_arg_t ev_arg; - - pack_size= bf_bufsize(pack); - - if (pack_size < IP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("wrong acc_length\n")); - bf_afree(pack); - return; - } - pack= bf_align(pack, IP_MIN_HDR_SIZE, 4); - pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE); -assert (pack->acc_length >= IP_MIN_HDR_SIZE); - - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - if (ip_hdr_len>IP_MIN_HDR_SIZE) - { - pack= bf_packIffLess(pack, ip_hdr_len); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - } - ip_frag_len= ntohs(ip_hdr->ih_length); - if (ip_frag_len != pack_size) - { - if (pack_size < ip_frag_len) - { - /* Sent ICMP? */ - DBLOCK(1, printf("wrong acc_length\n")); - bf_afree(pack); - return; - } - assert(ip_frag_lenih_dst; - - if (dest == ip_port->ip_ipaddr) - { - ip_port_arrive (ip_port, pack, ip_hdr); - return; - } - if (broadcast_dst(ip_port, dest)) - { - ip_port_arrive (ip_port, pack, ip_hdr); - return; - } - - if (pack->acc_linkC != 1 || pack->acc_buffer->buf_linkC != 1) - { - /* Get a private copy of the IP header */ - hdr_pack= bf_memreq(ip_hdr_len); - memcpy(ptr2acc_data(hdr_pack), ip_hdr, ip_hdr_len); - pack= bf_delhead(pack, ip_hdr_len); - hdr_pack->acc_next= pack; - pack= hdr_pack; hdr_pack= NULL; - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - } - assert(pack->acc_linkC == 1); - assert(pack->acc_buffer->buf_linkC == 1); - - /* Try to decrement the ttl field with one. */ - if (ip_hdr->ih_ttl < 2) - { - icmp_snd_time_exceeded(ip_port->ip_port, pack, - ICMP_TTL_EXC); - return; - } - ip_hdr->ih_ttl--; - ip_hdr_chksum(ip_hdr, ip_hdr_len); - - /* Avoid routing to bad destinations. */ - highbyte= ntohl(dest) >> 24; - if (highbyte == 0 || highbyte == 127 || - (highbyte == 169 && (((ntohl(dest) >> 16) & 0xff) == 254)) || - highbyte >= 0xe0) - { - /* Bogus destination address */ - bf_afree(pack); - return; - } - - /* Further processing from an event handler */ - if (pack->acc_linkC != 1) - { - tmp_pack= bf_dupacc(pack); - bf_afree(pack); - pack= tmp_pack; - tmp_pack= NULL; - } - pack->acc_ext_link= NULL; - if (ip_port->ip_routeq_head) - { - ip_port->ip_routeq_tail->acc_ext_link= pack; - ip_port->ip_routeq_tail= pack; - return; - } - - ip_port->ip_routeq_head= pack; - ip_port->ip_routeq_tail= pack; - ev_arg.ev_ptr= ip_port; - ev_enqueue(&ip_port->ip_routeq_event, route_packets, ev_arg); -} - -void ip_arrived_broadcast(ip_port, pack) -ip_port_t *ip_port; -acc_t *pack; -{ - ip_hdr_t *ip_hdr; - int ip_frag_len, ip_hdr_len; - size_t pack_size; - acc_t *tmp_pack; - - pack_size= bf_bufsize(pack); - - if (pack_size < IP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("wrong acc_length\n")); - bf_afree(pack); - return; - } - pack= bf_align(pack, IP_MIN_HDR_SIZE, 4); - pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE); -assert (pack->acc_length >= IP_MIN_HDR_SIZE); - - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - - DIFBLOCK(0x20, (ip_hdr->ih_dst & HTONL(0xf0000000)) == HTONL(0xe0000000), - printf("got multicast packet\n")); - - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - if (ip_hdr_len>IP_MIN_HDR_SIZE) - { - pack= bf_align(pack, IP_MIN_HDR_SIZE, 4); - pack= bf_packIffLess(pack, ip_hdr_len); - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - } - ip_frag_len= ntohs(ip_hdr->ih_length); - if (ip_frag_lenih_dst)) - { -#if 0 - printf( - "ip[%d]: broadcast packet for ip-nonbroadcast addr, src=", - ip_port->ip_port); - writeIpAddr(ip_hdr->ih_src); - printf(" dst="); - writeIpAddr(ip_hdr->ih_dst); - printf("\n"); -#endif - bf_afree(pack); - return; - } - - ip_port_arrive (ip_port, pack, ip_hdr); -} - -static void route_packets(ev, ev_arg) -event_t *ev; -ev_arg_t ev_arg; -{ - ip_port_t *ip_port; - ipaddr_t dest; - acc_t *pack; - iroute_t *iroute; - ip_port_t *next_port; - int r, type; - ip_hdr_t *ip_hdr; - size_t req_mtu; - - ip_port= ev_arg.ev_ptr; - assert(&ip_port->ip_routeq_event == ev); - - while (pack= ip_port->ip_routeq_head, pack != NULL) - { - ip_port->ip_routeq_head= pack->acc_ext_link; - - ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); - dest= ip_hdr->ih_dst; - - iroute= iroute_frag(ip_port->ip_port, dest); - if (iroute == NULL || iroute->irt_dist == IRTD_UNREACHABLE) - { - /* Also unreachable */ - /* Finding out if we send a network unreachable is too - * much trouble. - */ - if (iroute == NULL) - { - printf("ip[%d]: no route to ", - ip_port-ip_port_table); - writeIpAddr(dest); - printf("\n"); - } - icmp_snd_unreachable(ip_port->ip_port, pack, - ICMP_HOST_UNRCH); - continue; - } - next_port= &ip_port_table[iroute->irt_port]; - - if (ip_hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG)) - { - req_mtu= bf_bufsize(pack); - if (req_mtu > next_port->ip_mtu || - (iroute->irt_mtu && req_mtu>iroute->irt_mtu)) - { - icmp_snd_mtu(ip_port->ip_port, pack, - next_port->ip_mtu); - continue; - } - } - - if (next_port != ip_port) - { - if (iroute->irt_gateway != 0) - { - /* Just send the packet to the next gateway */ - pack->acc_linkC++; /* Extra ref for ICMP */ - r= next_port->ip_dev_send(next_port, - iroute->irt_gateway, - pack, IP_LT_NORMAL); - if (r == EHOSTUNREACH) - { - printf("ip[%d]: gw ", - ip_port-ip_port_table); - writeIpAddr(iroute->irt_gateway); - printf(" on ip[%d] is down for dest ", - next_port-ip_port_table); - writeIpAddr(dest); - printf("\n"); - icmp_snd_unreachable(next_port- - ip_port_table, pack, - ICMP_HOST_UNRCH); - pack= NULL; - } - else - { - assert(r == 0); - bf_afree(pack); pack= NULL; - } - continue; - } - /* The packet is for the attached network. Special - * addresses are the ip address of the interface and - * net.0 if no IP_42BSD_BCAST. - */ - if (dest == next_port->ip_ipaddr) - { - ip_port_arrive (next_port, pack, ip_hdr); - continue; - } - if (dest == iroute->irt_dest) - { - /* Never forward obsolete directed broadcasts */ -#if IP_42BSD_BCAST && 0 - type= IP_LT_BROADCAST; -#else - /* Bogus destination address */ - DBLOCK(1, printf( - "ip[%d]: dropping old-fashioned directed broadcast ", - ip_port-ip_port_table); - writeIpAddr(dest); - printf("\n");); - icmp_snd_unreachable(next_port-ip_port_table, - pack, ICMP_HOST_UNRCH); - continue; -#endif - } - else if (dest == (iroute->irt_dest | - ~iroute->irt_subnetmask)) - { - if (!ip_forward_directed_bcast) - { - /* Do not forward directed broadcasts */ - DBLOCK(1, printf( - "ip[%d]: dropping directed broadcast ", - ip_port-ip_port_table); - writeIpAddr(dest); - printf("\n");); - icmp_snd_unreachable(next_port- - ip_port_table, pack, - ICMP_HOST_UNRCH); - continue; - } - else - type= IP_LT_BROADCAST; - } - else - type= IP_LT_NORMAL; - - /* Just send the packet to it's destination */ - pack->acc_linkC++; /* Extra ref for ICMP */ - r= next_port->ip_dev_send(next_port, dest, pack, type); - if (r == EHOSTUNREACH) - { - DBLOCK(1, printf("ip[%d]: next hop ", - ip_port-ip_port_table); - writeIpAddr(dest); - printf(" on ip[%d] is down\n", - next_port-ip_port_table);); - icmp_snd_unreachable(next_port-ip_port_table, - pack, ICMP_HOST_UNRCH); - pack= NULL; - } - else - { - assert(r == 0 || (printf("r = %d\n", r), 0)); - bf_afree(pack); pack= NULL; - } - continue; - } - - /* Now we know that the packet should be routed over the same - * network as it came from. If there is a next hop gateway, - * we can send the packet to that gateway and send a redirect - * ICMP to the sender if the sender is on the attached - * network. If there is no gateway complain. - */ - if (iroute->irt_gateway == 0) - { - printf("ip_arrived: packet should not be here, src="); - writeIpAddr(ip_hdr->ih_src); - printf(" dst="); - writeIpAddr(ip_hdr->ih_dst); - printf("\n"); - bf_afree(pack); - continue; - } - if (((ip_hdr->ih_src ^ ip_port->ip_ipaddr) & - ip_port->ip_subnetmask) == 0) - { - /* Finding out if we can send a network redirect - * instead of a host redirect is too much trouble. - */ - pack->acc_linkC++; - icmp_snd_redirect(ip_port->ip_port, pack, - ICMP_REDIRECT_HOST, iroute->irt_gateway); - } - else - { - printf("ip_arrived: packet is wrongly routed, src="); - writeIpAddr(ip_hdr->ih_src); - printf(" dst="); - writeIpAddr(ip_hdr->ih_dst); - printf("\n"); - printf("in port %d, output %d, dest net ", - ip_port->ip_port, - iroute->irt_port); - writeIpAddr(iroute->irt_dest); - printf("/"); - writeIpAddr(iroute->irt_subnetmask); - printf(" next hop "); - writeIpAddr(iroute->irt_gateway); - printf("\n"); - bf_afree(pack); - continue; - } - /* No code for unreachable ICMPs here. The sender should - * process the ICMP redirect and figure it out. - */ - ip_port->ip_dev_send(ip_port, iroute->irt_gateway, pack, - IP_LT_NORMAL); - } -} - -static int broadcast_dst(ip_port, dest) -ip_port_t *ip_port; -ipaddr_t dest; -{ - ipaddr_t my_ipaddr, netmask, classmask; - - /* Treat class D (multicast) address as broadcasts. */ - if ((dest & HTONL(0xF0000000)) == HTONL(0xE0000000)) - { - return 1; - } - - /* Accept without complaint if netmask not yet configured. */ - if (!(ip_port->ip_flags & IPF_NETMASKSET)) - { - return 1; - } - /* Two possibilities, 0 (iff IP_42BSD_BCAST) and -1 */ - if (dest == HTONL((ipaddr_t)-1)) - return 1; -#if IP_42BSD_BCAST - if (dest == HTONL((ipaddr_t)0)) - return 1; -#endif - netmask= ip_port->ip_subnetmask; - my_ipaddr= ip_port->ip_ipaddr; - - if (((my_ipaddr ^ dest) & netmask) != 0) - { - classmask= ip_port->ip_classfulmask; - - /* Not a subnet broadcast, maybe a classful broadcast */ - if (((my_ipaddr ^ dest) & classmask) != 0) - { - return 0; - } - /* Two possibilities, net.0 (iff IP_42BSD_BCAST) and net.-1 */ - if ((dest & ~classmask) == ~classmask) - { - return 1; - } -#if IP_42BSD_BCAST - if ((dest & ~classmask) == 0) - return 1; -#endif - return 0; - } - - if (!(ip_port->ip_flags & IPF_SUBNET_BCAST)) - return 0; /* No subnet broadcasts on this network */ - - /* Two possibilities, subnet.0 (iff IP_42BSD_BCAST) and subnet.-1 */ - if ((dest & ~netmask) == ~netmask) - return 1; -#if IP_42BSD_BCAST - if ((dest & ~netmask) == 0) - return 1; -#endif - return 0; -} - -void ip_process_loopb(ev, arg) -event_t *ev; -ev_arg_t arg; -{ - ip_port_t *ip_port; - acc_t *pack; - - ip_port= arg.ev_ptr; - assert(ev == &ip_port->ip_loopb_event); - - while(pack= ip_port->ip_loopb_head, pack != NULL) - { - ip_port->ip_loopb_head= pack->acc_ext_link; - ip_arrived(ip_port, pack); - } -} - -/* - * $PchId: ip_read.c,v 1.33 2005/06/28 14:18:50 philip Exp $ - */ diff --git a/minix/net/inet/generic/ip_write.c b/minix/net/inet/generic/ip_write.c deleted file mode 100644 index b363036e1..000000000 --- a/minix/net/inet/generic/ip_write.c +++ /dev/null @@ -1,513 +0,0 @@ -/* -ip_write.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "event.h" -#include "type.h" - -#include "arp.h" -#include "assert.h" -#include "clock.h" -#include "eth.h" -#include "icmp_lib.h" -#include "io.h" -#include "ip.h" -#include "ip_int.h" -#include "ipr.h" - -THIS_FILE - -static void error_reply ARGS(( ip_fd_t *fd, int error )); - -int ip_write (fd, count) -int fd; -size_t count; -{ - ip_fd_t *ip_fd; - acc_t *pack; - int r; - - ip_fd= &ip_fd_table[fd]; - if (count > IP_MAX_PACKSIZE) - { - error_reply (ip_fd, EPACKSIZE); - return NW_OK; - } - pack= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, (size_t)0, - count, FALSE); - if (!pack) - return NW_OK; - r= ip_send(fd, pack, count); - assert(r != NW_WOULDBLOCK); - - if (r == NW_OK) - error_reply (ip_fd, count); - else - error_reply (ip_fd, r); - return NW_OK; -} - -int ip_send(fd, data, data_len) -int fd; -acc_t *data; -size_t data_len; -{ - ip_port_t *ip_port; - ip_fd_t *ip_fd; - ip_hdr_t *ip_hdr, *tmp_hdr; - ipaddr_t dstaddr, nexthop, hostrep_dst, my_ipaddr, netmask; - u8_t *addrInBytes; - acc_t *tmp_pack, *tmp_pack1; - int hdr_len, hdr_opt_len, r; - int type, ttl; - size_t req_mtu; - ev_arg_t arg; - - ip_fd= &ip_fd_table[fd]; - ip_port= ip_fd->if_port; - - if (!(ip_fd->if_flags & IFF_OPTSET)) - { - bf_afree(data); - return EBADMODE; - } - - if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET)) - { - /* Interface is down. */ - bf_afree(data); - return ENETDOWN; - } - - data_len= bf_bufsize(data); - - if (ip_fd->if_ipopt.nwio_flags & NWIO_RWDATONLY) - { - tmp_pack= bf_memreq(IP_MIN_HDR_SIZE); - tmp_pack->acc_next= data; - data= tmp_pack; - data_len += IP_MIN_HDR_SIZE; - } - if (data_lenacc_linkC != 1 || data->acc_buffer->buf_linkC != 1) - { - tmp_pack= bf_memreq(IP_MIN_HDR_SIZE); - tmp_hdr= (ip_hdr_t *)ptr2acc_data(tmp_pack); - *tmp_hdr= *ip_hdr; - tmp_pack->acc_next= bf_cut(data, IP_MIN_HDR_SIZE, - data_len-IP_MIN_HDR_SIZE); - bf_afree(data); - ip_hdr= tmp_hdr; - data= tmp_pack; - assert (data->acc_length >= IP_MIN_HDR_SIZE); - } - - if (ip_fd->if_ipopt.nwio_flags & NWIO_HDR_O_SPEC) - { - hdr_opt_len= ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz; - if (hdr_opt_len) - { - tmp_pack= bf_cut(data, 0, IP_MIN_HDR_SIZE); - tmp_pack1= bf_cut (data, IP_MIN_HDR_SIZE, - data_len-IP_MIN_HDR_SIZE); - bf_afree(data); - data= bf_packIffLess(tmp_pack, IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(data); - tmp_pack= bf_memreq (hdr_opt_len); - memcpy (ptr2acc_data(tmp_pack), ip_fd->if_ipopt. - nwio_hdropt.iho_data, hdr_opt_len); - data->acc_next= tmp_pack; - tmp_pack->acc_next= tmp_pack1; - hdr_len= IP_MIN_HDR_SIZE+hdr_opt_len; - } - else - hdr_len= IP_MIN_HDR_SIZE; - ip_hdr->ih_vers_ihl= hdr_len/4; - ip_hdr->ih_tos= ip_fd->if_ipopt.nwio_tos; - ip_hdr->ih_flags_fragoff= 0; - if (ip_fd->if_ipopt.nwio_df) - ip_hdr->ih_flags_fragoff |= HTONS(IH_DONT_FRAG); - ip_hdr->ih_ttl= ip_fd->if_ipopt.nwio_ttl; - ttl= ORTD_UNREACHABLE+1; /* Don't check TTL */ - } - else - { - hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK)*4; - r= NW_OK; - if (hdr_lendata_len) - r= EPACKSIZE; - else if (!ip_hdr->ih_ttl) - r= EINVAL; - if (r != NW_OK) - { - bf_afree(data); - return r; - } - - data= bf_packIffLess(data, hdr_len); - ip_hdr= (ip_hdr_t *)ptr2acc_data(data); - if (hdr_len != IP_MIN_HDR_SIZE) - { - r= ip_chk_hdropt((u8_t *)(ptr2acc_data(data) + - IP_MIN_HDR_SIZE), - hdr_len-IP_MIN_HDR_SIZE); - if (r != NW_OK) - { - bf_afree(data); - return r; - } - } - ttl= ip_hdr->ih_ttl; - } - - ip_hdr->ih_vers_ihl= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) | - (IP_VERSION << 4); - ip_hdr->ih_length= htons(data_len); - ip_hdr->ih_flags_fragoff &= ~HTONS(IH_FRAGOFF_MASK | - IH_FLAGS_UNUSED | IH_MORE_FRAGS); - if (ip_fd->if_ipopt.nwio_flags & NWIO_PROTOSPEC) - ip_hdr->ih_proto= ip_fd->if_ipopt.nwio_proto; - ip_hdr->ih_id= htons(ip_port->ip_frame_id++); - ip_hdr->ih_src= ip_fd->if_port->ip_ipaddr; - if (ip_fd->if_ipopt.nwio_flags & NWIO_REMSPEC) - ip_hdr->ih_dst= ip_fd->if_ipopt.nwio_rem; - - netmask= ip_port->ip_subnetmask; - my_ipaddr= ip_port->ip_ipaddr; - - dstaddr= ip_hdr->ih_dst; - hostrep_dst= ntohl(dstaddr); - r= 0; - if (hostrep_dst == (ipaddr_t)-1) - ; /* OK, local broadcast */ - else if ((hostrep_dst & 0xe0000000l) == 0xe0000000l) - ; /* OK, Multicast */ - else if ((hostrep_dst & 0xf0000000l) == 0xf0000000l) - r= EAFNOSUPPORT; /* Bad class */ - else if ((dstaddr ^ my_ipaddr) & netmask) - ; /* OK, remote destination */ - else if (!(dstaddr & ~netmask) && - (ip_port->ip_flags & IPF_SUBNET_BCAST)) - { - r= EAFNOSUPPORT; /* Zero host part */ - } - if (r<0) - { - DIFBLOCK(1, r == EAFNOSUPPORT, - printf("bad destination: "); - writeIpAddr(ip_hdr->ih_dst); - printf("\n")); - bf_afree(data); - return r; - } - ip_hdr_chksum(ip_hdr, hdr_len); - - data= bf_packIffLess(data, IP_MIN_HDR_SIZE); - assert (data->acc_length >= IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(data); - - if (ip_hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG)) - { - req_mtu= bf_bufsize(data); - if (req_mtu > ip_port->ip_mtu) - { - DBLOCK(1, printf( - "packet is larger than link MTU and DF is set\n")); - bf_afree(data); - return EPACKSIZE; - } - } - else - req_mtu= 0; - - addrInBytes= (u8_t *)&dstaddr; - - if ((addrInBytes[0] & 0xff) == 0x7f) /* local loopback */ - { - assert (data->acc_linkC == 1); - dstaddr= ip_hdr->ih_dst; /* swap src and dst - * addresses */ - ip_hdr->ih_dst= ip_hdr->ih_src; - ip_hdr->ih_src= dstaddr; - data->acc_ext_link= NULL; - if (ip_port->ip_loopb_head == NULL) - { - ip_port->ip_loopb_head= data; - arg.ev_ptr= ip_port; - ev_enqueue(&ip_port->ip_loopb_event, - ip_process_loopb, arg); - } - else - ip_port->ip_loopb_tail->acc_ext_link= data; - ip_port->ip_loopb_tail= data; - - return NW_OK; - } - - if ((dstaddr & HTONL(0xe0000000)) == HTONL(0xe0000000)) - { - if (dstaddr == (ipaddr_t)-1) - { - r= (*ip_port->ip_dev_send)(ip_port, dstaddr, data, - IP_LT_BROADCAST); - return r; - } - if (ip_nettype(dstaddr) == IPNT_CLASS_D) - { - /* Multicast, what about multicast routing? */ - r= (*ip_port->ip_dev_send)(ip_port, dstaddr, data, - IP_LT_MULTICAST); - return r; - } - } - - if (dstaddr == my_ipaddr) - { - assert (data->acc_linkC == 1); - - data->acc_ext_link= NULL; - if (ip_port->ip_loopb_head == NULL) - { - ip_port->ip_loopb_head= data; - arg.ev_ptr= ip_port; - ev_enqueue(&ip_port->ip_loopb_event, - ip_process_loopb, arg); - } - else - ip_port->ip_loopb_tail->acc_ext_link= data; - ip_port->ip_loopb_tail= data; - - return NW_OK; - } - - if (((dstaddr ^ my_ipaddr) & netmask) == 0) - { - type= ((dstaddr == (my_ipaddr | ~netmask) && - (ip_port->ip_flags & IPF_SUBNET_BCAST)) ? - IP_LT_BROADCAST : IP_LT_NORMAL); - - r= (*ip_port->ip_dev_send)(ip_port, dstaddr, data, type); - return r; - } - - r= oroute_frag (ip_port - ip_port_table, dstaddr, ttl, req_mtu, - &nexthop); - - if (r == NW_OK) - { - if (nexthop == ip_port->ip_ipaddr) - { - data->acc_ext_link= NULL; - if (ip_port->ip_loopb_head == NULL) - { - ip_port->ip_loopb_head= data; - arg.ev_ptr= ip_port; - ev_enqueue(&ip_port->ip_loopb_event, - ip_process_loopb, arg); - } - else - ip_port->ip_loopb_tail->acc_ext_link= data; - ip_port->ip_loopb_tail= data; - } - else - { - r= (*ip_port->ip_dev_send)(ip_port, - nexthop, data, IP_LT_NORMAL); - } - } - else - { - DBLOCK(0x10, printf("got error %d\n", r)); - bf_afree(data); - } - return r; -} - -void ip_hdr_chksum(ip_hdr, ip_hdr_len) -ip_hdr_t *ip_hdr; -int ip_hdr_len; -{ - ip_hdr->ih_hdr_chk= 0; - ip_hdr->ih_hdr_chk= ~oneC_sum (0, (u16_t *)ip_hdr, ip_hdr_len); -} - -acc_t *ip_split_pack (ip_port, ref_last, mtu) -ip_port_t *ip_port; -acc_t **ref_last; -int mtu; -{ - int pack_siz; - ip_hdr_t *first_hdr, *second_hdr; - int first_hdr_len, second_hdr_len; - int first_data_len, second_data_len; - int data_len, max_data_len, nfrags, new_first_data_len; - int first_opt_size, second_opt_size; - acc_t *first_pack, *second_pack, *tmp_pack; - u8_t *first_optptr, *second_optptr; - int i, optlen; - - first_pack= *ref_last; - *ref_last= 0; - second_pack= 0; - - first_pack= bf_align(first_pack, IP_MIN_HDR_SIZE, 4); - first_pack= bf_packIffLess(first_pack, IP_MIN_HDR_SIZE); - assert (first_pack->acc_length >= IP_MIN_HDR_SIZE); - - first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack); - first_hdr_len= (first_hdr->ih_vers_ihl & IH_IHL_MASK) * 4; - if (first_hdr_len>IP_MIN_HDR_SIZE) - { - first_pack= bf_packIffLess(first_pack, first_hdr_len); - first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack); - } - - pack_siz= bf_bufsize(first_pack); - assert(pack_siz > mtu); - - assert (!(first_hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG))); - - if (first_pack->acc_linkC != 1 || - first_pack->acc_buffer->buf_linkC != 1) - { - /* Get a private copy of the IP header */ - tmp_pack= bf_memreq(first_hdr_len); - memcpy(ptr2acc_data(tmp_pack), first_hdr, first_hdr_len); - first_pack= bf_delhead(first_pack, first_hdr_len); - tmp_pack->acc_next= first_pack; - first_pack= tmp_pack; tmp_pack= NULL; - first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack); - } - - data_len= ntohs(first_hdr->ih_length) - first_hdr_len; - - /* Try to split the packet evenly. */ - assert(mtu > first_hdr_len); - max_data_len= mtu-first_hdr_len; - nfrags= (data_len/max_data_len)+1; - new_first_data_len= data_len/nfrags; - if (new_first_data_len < 8) - { - /* Special case for extremely small MTUs */ - new_first_data_len= 8; - } - new_first_data_len &= ~7; /* data goes in 8 byte chuncks */ - - assert(new_first_data_len >= 8); - assert(new_first_data_len+first_hdr_len <= mtu); - - second_data_len= data_len-new_first_data_len; - second_pack= bf_cut(first_pack, first_hdr_len+ - new_first_data_len, second_data_len); - tmp_pack= first_pack; - first_data_len= new_first_data_len; - first_pack= bf_cut (tmp_pack, 0, first_hdr_len+first_data_len); - bf_afree(tmp_pack); - tmp_pack= bf_memreq(first_hdr_len); - tmp_pack->acc_next= second_pack; - second_pack= tmp_pack; - second_hdr= (ip_hdr_t *)ptr2acc_data(second_pack); - *second_hdr= *first_hdr; - second_hdr->ih_flags_fragoff= htons( - ntohs(first_hdr->ih_flags_fragoff)+(first_data_len/8)); - - first_opt_size= first_hdr_len-IP_MIN_HDR_SIZE; - second_opt_size= 0; - if (first_opt_size) - { - first_pack= bf_packIffLess (first_pack, - first_hdr_len); - first_hdr= (ip_hdr_t *)ptr2acc_data(first_pack); - assert (first_pack->acc_length>=first_hdr_len); - first_optptr= (u8_t *)ptr2acc_data(first_pack)+ - IP_MIN_HDR_SIZE; - second_optptr= (u8_t *)ptr2acc_data( - second_pack)+IP_MIN_HDR_SIZE; - i= 0; - while (iih_vers_ihl= (second_hdr->ih_vers_ihl & 0xf0) - + (second_hdr_len/4); - second_hdr->ih_length= htons(second_data_len+ - second_hdr_len); - second_pack->acc_length= second_hdr_len; - - assert(first_pack->acc_linkC == 1); - assert(first_pack->acc_buffer->buf_linkC == 1); - - first_hdr->ih_flags_fragoff |= HTONS(IH_MORE_FRAGS); - first_hdr->ih_length= htons(first_data_len+ - first_hdr_len); - assert (!(second_hdr->ih_flags_fragoff & HTONS(IH_DONT_FRAG))); - - ip_hdr_chksum(first_hdr, first_hdr_len); - if (second_data_len+second_hdr_len <= mtu) - { - /* second_pack will not be split any further, so we have to - * calculate the header checksum. - */ - ip_hdr_chksum(second_hdr, second_hdr_len); - } - - *ref_last= second_pack; - - return first_pack; -} - -static void error_reply (ip_fd, error) -ip_fd_t *ip_fd; -int error; -{ - if ((*ip_fd->if_get_userdata)(ip_fd->if_srfd, (size_t)error, - (size_t)0, FALSE)) - { - ip_panic(( "can't error_reply" )); - } -} - -/* - * $PchId: ip_write.c,v 1.22 2004/08/03 11:11:04 philip Exp $ - */ diff --git a/minix/net/inet/generic/ipr.c b/minix/net/inet/generic/ipr.c deleted file mode 100644 index e620d089f..000000000 --- a/minix/net/inet/generic/ipr.c +++ /dev/null @@ -1,1247 +0,0 @@ -/* -ipr.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "clock.h" - -#include "type.h" -#include "assert.h" -#include "buf.h" -#include "event.h" -#include "io.h" -#include "ip_int.h" -#include "ipr.h" - -THIS_FILE - -#define OROUTE_NR 128 -#define OROUTE_STATIC_NR 16 -#define OROUTE_HASH_ASS_NR 4 -#define OROUTE_HASH_NR 32 -#define OROUTE_HASH_MASK (OROUTE_HASH_NR-1) - -#define hash_oroute(port_nr, ipaddr, hash_tmp) (hash_tmp= (ipaddr), \ - hash_tmp= (hash_tmp >> 20) ^ hash_tmp, \ - hash_tmp= (hash_tmp >> 10) ^ hash_tmp, \ - hash_tmp= (hash_tmp >> 5) ^ hash_tmp, \ - (hash_tmp + (port_nr)) & OROUTE_HASH_MASK) - -typedef struct oroute_hash -{ - ipaddr_t orh_addr; - oroute_t *orh_route; -} oroute_hash_t; - -static oroute_t oroute_table[OROUTE_NR]; -static oroute_t *oroute_head; -static int static_oroute_nr; -static oroute_hash_t oroute_hash_table[OROUTE_HASH_NR][OROUTE_HASH_ASS_NR]; - -#define IROUTE_NR 512 -#define IROUTE_HASH_ASS_NR 4 -#define IROUTE_HASH_NR 32 -#define IROUTE_HASH_MASK (IROUTE_HASH_NR-1) - -#define hash_iroute(port_nr, ipaddr, hash_tmp) (hash_tmp= (ipaddr), \ - hash_tmp= (hash_tmp >> 20) ^ hash_tmp, \ - hash_tmp= (hash_tmp >> 10) ^ hash_tmp, \ - hash_tmp= (hash_tmp >> 5) ^ hash_tmp, \ - (hash_tmp + (port_nr)) & IROUTE_HASH_MASK) - -typedef struct iroute_hash -{ - ipaddr_t irh_addr; - iroute_t *irh_route; -} iroute_hash_t; - -static iroute_t iroute_table[IROUTE_NR]; -static iroute_hash_t iroute_hash_table[IROUTE_HASH_NR][IROUTE_HASH_ASS_NR]; - -static oroute_t *oroute_find_ent ARGS(( int port_nr, ipaddr_t dest )); -static void oroute_del ARGS(( oroute_t *oroute )); -static oroute_t *sort_dists ARGS(( oroute_t *oroute )); -static oroute_t *sort_gws ARGS(( oroute_t *oroute )); -static void oroute_uncache_nw ARGS(( ipaddr_t dest, ipaddr_t netmask )); -static void iroute_uncache_nw ARGS(( ipaddr_t dest, ipaddr_t netmask )); - -void ipr_init() -{ - int i; - oroute_t *oroute; - iroute_t *iroute; - - for (i= 0, oroute= oroute_table; iort_flags= ORTF_EMPTY; - static_oroute_nr= 0; - assert(OROUTE_HASH_ASS_NR == 4); - - for (i= 0, iroute= iroute_table; iirt_flags= IRTF_EMPTY; - assert(IROUTE_HASH_ASS_NR == 4); -} - - -iroute_t *iroute_frag(port_nr, dest) -int port_nr; -ipaddr_t dest; -{ - int hash, i; - iroute_hash_t *iroute_hash; - iroute_hash_t tmp_hash; - iroute_t *iroute, *bestroute; - unsigned long hash_tmp; - u32_t tmp_mask; - - hash= hash_iroute(port_nr, dest, hash_tmp); - iroute_hash= &iroute_hash_table[hash][0]; - if (iroute_hash[0].irh_addr == dest) - iroute= iroute_hash[0].irh_route; - else if (iroute_hash[1].irh_addr == dest) - { - tmp_hash= iroute_hash[1]; - iroute_hash[1]= iroute_hash[0]; - iroute_hash[0]= tmp_hash; - iroute= tmp_hash.irh_route; - } - else if (iroute_hash[2].irh_addr == dest) - { - tmp_hash= iroute_hash[2]; - iroute_hash[2]= iroute_hash[1]; - iroute_hash[1]= iroute_hash[0]; - iroute_hash[0]= tmp_hash; - iroute= tmp_hash.irh_route; - } - else if (iroute_hash[3].irh_addr == dest) - { - tmp_hash= iroute_hash[3]; - iroute_hash[3]= iroute_hash[2]; - iroute_hash[2]= iroute_hash[1]; - iroute_hash[1]= iroute_hash[0]; - iroute_hash[0]= tmp_hash; - iroute= tmp_hash.irh_route; - } - else - iroute= NULL; - if (iroute) - return iroute; - - bestroute= NULL; - for (i= 0, iroute= iroute_table; i < IROUTE_NR; i++, iroute++) - { - if (!(iroute->irt_flags & IRTF_INUSE)) - continue; - if (((dest ^ iroute->irt_dest) & iroute->irt_subnetmask) != 0) - continue; - if (!bestroute) - { - bestroute= iroute; - continue; - } - - /* More specific netmasks are better */ - if (iroute->irt_subnetmask != bestroute->irt_subnetmask) - { - /* Using two ntohl macros in one expression - * is not allowed (tmp_l is modified twice) - */ - tmp_mask= ntohl(iroute->irt_subnetmask); - if (tmp_mask > ntohl(bestroute->irt_subnetmask)) - bestroute= iroute; - continue; - } - - /* Dynamic routes override static routes */ - if ((iroute->irt_flags & IRTF_STATIC) != - (bestroute->irt_flags & IRTF_STATIC)) - { - if (bestroute->irt_flags & IRTF_STATIC) - bestroute= iroute; - continue; - } - - /* A route to the local interface give an opportunity - * to send redirects. - */ - if (iroute->irt_port != bestroute->irt_port) - { - if (iroute->irt_port == port_nr) - bestroute= iroute; - continue; - } - } - if (bestroute == NULL) - return NULL; - - iroute_hash[3]= iroute_hash[2]; - iroute_hash[2]= iroute_hash[1]; - iroute_hash[1]= iroute_hash[0]; - iroute_hash[0].irh_addr= dest; - iroute_hash[0].irh_route= bestroute; - - return bestroute; -} - -int oroute_frag(port_nr, dest, ttl, msgsize, nexthop) -int port_nr; -ipaddr_t dest; -int ttl; -size_t msgsize; -ipaddr_t *nexthop; -{ - oroute_t *oroute; - - oroute= oroute_find_ent(port_nr, dest); - if (!oroute || oroute->ort_dist > ttl) - return ENETUNREACH; - if (msgsize && oroute->ort_mtu && - oroute->ort_mtu < msgsize) - { - return EPACKSIZE; - } - - *nexthop= oroute->ort_gateway; - return NW_OK; -} - - -int ipr_add_oroute(port_nr, dest, subnetmask, gateway, - timeout, dist, mtu, static_route, preference, oroute_p) -int port_nr; -ipaddr_t dest; -ipaddr_t subnetmask; -ipaddr_t gateway; -time_t timeout; -int dist; -int mtu; -int static_route; -i32_t preference; -oroute_t **oroute_p; -{ - int i; - ip_port_t *ip_port; - oroute_t *oroute, *oldest_route, *prev, *nw_route, *gw_route, - *prev_route; - time_t currtim, exp_tim, exp_tim_orig; - - oldest_route= 0; - currtim= get_time(); - if (timeout) - exp_tim= timeout+currtim; - else - exp_tim= 0; - - DBLOCK(0x10, - printf("ip[%d]: adding oroute to ", port_nr); - writeIpAddr(dest); - printf("["); writeIpAddr(subnetmask); printf("] through "); - writeIpAddr(gateway); - printf(" timeout: %lds, distance %d, pref %ld, mtu %d\n", - (long)timeout/HZ, dist, (long)preference, mtu)); - - ip_port= &ip_port_table[port_nr]; - - /* Validate gateway */ - if (((gateway ^ ip_port->ip_ipaddr) & ip_port->ip_subnetmask) != 0) - { - DBLOCK(1, printf("ip[%d]: (ipr_add_oroute) invalid gateway: ", - port_nr); writeIpAddr(gateway); printf("\n")); - return EINVAL; - } - - if (static_route) - { - if (static_oroute_nr >= OROUTE_STATIC_NR) - return ENOMEM; - static_oroute_nr++; - } - else - { - /* Try to track down any old routes. */ - for(oroute= oroute_head; oroute; oroute= oroute->ort_nextnw) - { - if (oroute->ort_port != port_nr) - continue; - if (oroute->ort_dest == dest && - oroute->ort_subnetmask == subnetmask) - { - break; - } - } - for(; oroute; oroute= oroute->ort_nextgw) - { - if (oroute->ort_gateway == gateway) - break; - } - for(; oroute; oroute= oroute->ort_nextdist) - { - if ((oroute->ort_flags & ORTF_STATIC) != 0) - continue; - if (oroute->ort_dist > dist) - continue; - break; - } - if (oroute) - { - assert(oroute->ort_port == port_nr); - if (dest != 0) - { - /* The new expire should not be later - * than the old expire time. Except for - * default routes, where the expire time - * is simple set to the new value. - */ - exp_tim_orig= oroute->ort_exp_tim; - if (!exp_tim) - exp_tim= exp_tim_orig; - else if (exp_tim_orig && - exp_tim > exp_tim_orig) - { - exp_tim= exp_tim_orig; - } - } - oroute_del(oroute); - oroute->ort_flags= 0; - oldest_route= oroute; - } - } - - if (oldest_route == NULL) - { - /* Look for an unused entry, or remove an existing one */ - for (i= 0, oroute= oroute_table; iort_flags & ORTF_INUSE) == 0) - break; - if (oroute->ort_exp_tim && oroute->ort_exp_tim < - currtim) - { - oroute_del(oroute); - oroute->ort_flags= 0; - break; - } - if (oroute->ort_flags & ORTF_STATIC) - continue; - if (oroute->ort_dest == 0) - { - /* Never remove default routes. */ - continue; - } - if (oldest_route == NULL) - { - oldest_route= oroute; - continue; - } - if (oroute->ort_timestamp < oldest_route->ort_timestamp) - { - oldest_route= oroute; - } - } - if (i < OROUTE_NR) - oldest_route= oroute; - else - { - assert(oldest_route); - oroute_del(oldest_route); - oldest_route->ort_flags= 0; - } - } - - oldest_route->ort_dest= dest; - oldest_route->ort_gateway= gateway; - oldest_route->ort_subnetmask= subnetmask; - oldest_route->ort_exp_tim= exp_tim; - oldest_route->ort_timestamp= currtim; - oldest_route->ort_dist= dist; - oldest_route->ort_mtu= mtu; - oldest_route->ort_port= port_nr; - oldest_route->ort_flags= ORTF_INUSE; - oldest_route->ort_pref= preference; - if (static_route) - oldest_route->ort_flags |= ORTF_STATIC; - - /* Insert the route by tearing apart the routing table, - * and insert the entry during the reconstruction. - */ - for (prev= 0, nw_route= oroute_head; nw_route; - prev= nw_route, nw_route= nw_route->ort_nextnw) - { - if (nw_route->ort_port != port_nr) - continue; - if (nw_route->ort_dest == dest && - nw_route->ort_subnetmask == subnetmask) - { - if (prev) - prev->ort_nextnw= nw_route->ort_nextnw; - else - oroute_head= nw_route->ort_nextnw; - break; - } - } - prev_route= nw_route; - for(prev= NULL, gw_route= nw_route; gw_route; - prev= gw_route, gw_route= gw_route->ort_nextgw) - { - if (gw_route->ort_gateway == gateway) - { - if (prev) - prev->ort_nextgw= gw_route->ort_nextgw; - else - nw_route= gw_route->ort_nextgw; - break; - } - } - oldest_route->ort_nextdist= gw_route; - gw_route= oldest_route; - gw_route= sort_dists(gw_route); - gw_route->ort_nextgw= nw_route; - nw_route= gw_route; - nw_route= sort_gws(nw_route); - nw_route->ort_nextnw= oroute_head; - oroute_head= nw_route; - if (nw_route != prev_route) - oroute_uncache_nw(nw_route->ort_dest, nw_route->ort_subnetmask); - if (oroute_p != NULL) - *oroute_p= oldest_route; - return NW_OK; -} - -int ipr_del_oroute(port_nr, dest, subnetmask, gateway, static_route) -int port_nr; -ipaddr_t dest; -ipaddr_t subnetmask; -ipaddr_t gateway; -int static_route; -{ - int i; - oroute_t *oroute; - - for(i= 0, oroute= oroute_table; iort_flags & ORTF_INUSE) == 0) - continue; - if (oroute->ort_port != port_nr || - oroute->ort_dest != dest || - oroute->ort_subnetmask != subnetmask || - oroute->ort_gateway != gateway) - { - continue; - } - if (!!(oroute->ort_flags & ORTF_STATIC) != static_route) - continue; - break; - } - - if (i == OROUTE_NR) - return ESRCH; - - if (static_route) - static_oroute_nr--; - - oroute_del(oroute); - oroute->ort_flags &= ~ORTF_INUSE; - return NW_OK; -} - - - -void ipr_chk_otab(port_nr, addr, mask) -int port_nr; -ipaddr_t addr; -ipaddr_t mask; -{ - int i; - oroute_t *oroute; - - DBLOCK(1, - printf("ip[%d] (ipr_chk_otab): addr ", port_nr); - writeIpAddr(addr); - printf(" mask "); - writeIpAddr(mask); - printf("\n"); - ); - - if (addr == 0) - { - /* Special hack to flush entries for an interface that - * goes down. - */ - addr= mask= HTONL(0xffffffff); - } - - for(i= 0, oroute= oroute_table; iort_flags & ORTF_INUSE) == 0) - continue; - if (oroute->ort_port != port_nr || - ((oroute->ort_gateway ^ addr) & mask) == 0) - { - continue; - } - DBLOCK(1, printf("ip[%d] (ipr_chk_otab): deleting route to ", - port_nr); - writeIpAddr(oroute->ort_dest); - printf(" gw "); - writeIpAddr(oroute->ort_gateway); - printf("\n")); - - if (oroute->ort_flags & ORTF_STATIC) - static_oroute_nr--; - oroute_del(oroute); - oroute->ort_flags &= ~ORTF_INUSE; - } -} - - -void ipr_gateway_down(port_nr, gateway, timeout) -int port_nr; -ipaddr_t gateway; -time_t timeout; -{ - oroute_t *route_ind; - time_t currtim; - int i; - int result; - - currtim= get_time(); - for (i= 0, route_ind= oroute_table; iort_flags & ORTF_INUSE)) - continue; - if (route_ind->ort_gateway != gateway) - continue; - if (route_ind->ort_exp_tim && route_ind->ort_exp_tim < currtim) - continue; - result= ipr_add_oroute(port_nr, route_ind->ort_dest, - route_ind->ort_subnetmask, gateway, - timeout, ORTD_UNREACHABLE, route_ind->ort_mtu, - FALSE, 0, NULL); - assert(result == NW_OK); - } -} - - -void ipr_destunrch(port_nr, dest, netmask, timeout) -int port_nr; -ipaddr_t dest; -ipaddr_t netmask; -time_t timeout; -{ - oroute_t *oroute; - int result; - - oroute= oroute_find_ent(port_nr, dest); - - if (!oroute) - { - DBLOCK(1, printf("ip[%d]: got a dest unreachable for ", - port_nr); - writeIpAddr(dest); printf("but no route present\n")); - - return; - } - result= ipr_add_oroute(port_nr, dest, netmask, oroute->ort_gateway, - timeout, ORTD_UNREACHABLE, oroute->ort_mtu, FALSE, 0, NULL); - assert(result == NW_OK); -} - - -void ipr_redirect(port_nr, dest, netmask, old_gateway, new_gateway, - timeout) -int port_nr; -ipaddr_t dest; -ipaddr_t netmask; -ipaddr_t old_gateway; -ipaddr_t new_gateway; -time_t timeout; -{ - oroute_t *oroute; - ip_port_t *ip_port; - int result; - - ip_port= &ip_port_table[port_nr]; - oroute= oroute_find_ent(port_nr, dest); - - if (!oroute) - { - DBLOCK(1, printf("ip[%d]: got a redirect for ", port_nr); - writeIpAddr(dest); printf("but no route present\n")); - return; - } - if (oroute->ort_gateway != old_gateway) - { - DBLOCK(1, printf("ip[%d]: got a redirect from ", port_nr); - writeIpAddr(old_gateway); printf(" for "); - writeIpAddr(dest); printf(" but curr gateway is "); - writeIpAddr(oroute->ort_gateway); printf("\n")); - return; - } - if ((new_gateway ^ ip_port->ip_ipaddr) & ip_port->ip_subnetmask) - { - DBLOCK(1, printf("ip[%d]: redirect from ", port_nr); - writeIpAddr(old_gateway); printf(" for "); - writeIpAddr(dest); printf(" but new gateway "); - writeIpAddr(new_gateway); - printf(" is not on local subnet\n")); - return; - } - if (oroute->ort_flags & ORTF_STATIC) - { - if (oroute->ort_dest == dest) - { - DBLOCK(1, printf("ip[%d]: got a redirect for ", - port_nr); - writeIpAddr(dest); - printf("but route is fixed\n")); - return; - } - } - else - { - result= ipr_add_oroute(port_nr, dest, netmask, - oroute->ort_gateway, HZ, ORTD_UNREACHABLE, - oroute->ort_mtu, FALSE, 0, NULL); - assert(result == NW_OK); - } - result= ipr_add_oroute(port_nr, dest, netmask, new_gateway, - timeout, 1, oroute->ort_mtu, FALSE, 0, NULL); - assert(result == NW_OK); -} - - -void ipr_ttl_exc(port_nr, dest, netmask, timeout) -int port_nr; -ipaddr_t dest; -ipaddr_t netmask; -time_t timeout; -{ - oroute_t *oroute; - int new_dist; - int result; - - oroute= oroute_find_ent(port_nr, dest); - - if (!oroute) - { - DBLOCK(1, printf("ip[%d]: got a ttl exceeded for ", - port_nr); - writeIpAddr(dest); printf("but no route present\n")); - return; - } - - new_dist= oroute->ort_dist * 2; - if (new_dist > IP_DEF_TTL) - { - new_dist= oroute->ort_dist+1; - if (new_dist >= IP_DEF_TTL) - { - DBLOCK(1, printf("ip[%d]: got a ttl exceeded for ", - port_nr); - writeIpAddr(dest); - printf(" but dist is %d\n", - oroute->ort_dist)); - return; - } - } - - result= ipr_add_oroute(port_nr, dest, netmask, oroute->ort_gateway, - timeout, new_dist, oroute->ort_mtu, FALSE, 0, NULL); - assert(result == NW_OK); -} - -void ipr_mtu( - int port_nr, - ipaddr_t dest, - u16_t mtu, - time_t timeout -) -{ - oroute_t *oroute; - int result; - - oroute= oroute_find_ent(port_nr, dest); - - if (!oroute) - { - DBLOCK(1, printf("ip[%d]: got a mtu exceeded for ", - port_nr); - writeIpAddr(dest); printf("but no route present\n")); - return; - } - - if (mtu < IP_MIN_MTU) - return; - if (oroute->ort_mtu && mtu >= oroute->ort_mtu) - return; /* Only decrease mtu */ - - result= ipr_add_oroute(port_nr, dest, HTONL(0xffffffff), - oroute->ort_gateway, timeout, oroute->ort_dist, mtu, - FALSE, 0, NULL); - assert(result == NW_OK); -} - - -int ipr_get_oroute(ent_no, route_ent) -int ent_no; -nwio_route_t *route_ent; -{ - oroute_t *oroute; - - if (ent_no<0 || ent_no>= OROUTE_NR) - return ENOENT; - - oroute= &oroute_table[ent_no]; - if ((oroute->ort_flags & ORTF_INUSE) && oroute->ort_exp_tim && - oroute->ort_exp_tim < get_time()) - { - oroute_del(oroute); - oroute->ort_flags &= ~ORTF_INUSE; - } - - route_ent->nwr_ent_no= ent_no; - route_ent->nwr_ent_count= OROUTE_NR; - route_ent->nwr_dest= oroute->ort_dest; - route_ent->nwr_netmask= oroute->ort_subnetmask; - route_ent->nwr_gateway= oroute->ort_gateway; - route_ent->nwr_dist= oroute->ort_dist; - route_ent->nwr_flags= NWRF_EMPTY; - if (oroute->ort_flags & ORTF_INUSE) - { - route_ent->nwr_flags |= NWRF_INUSE; - if (oroute->ort_flags & ORTF_STATIC) - route_ent->nwr_flags |= NWRF_STATIC; - } - route_ent->nwr_pref= oroute->ort_pref; - route_ent->nwr_mtu= oroute->ort_mtu; - route_ent->nwr_ifaddr= ip_get_ifaddr(oroute->ort_port); - return NW_OK; -} - - -static oroute_t *oroute_find_ent(port_nr, dest) -int port_nr; -ipaddr_t dest; -{ - int hash; - oroute_hash_t *oroute_hash; - oroute_hash_t tmp_hash; - oroute_t *oroute, *bestroute; - time_t currtim; - unsigned long hash_tmp; - u32_t tmp_mask; - - currtim= get_time(); - - hash= hash_oroute(port_nr, dest, hash_tmp); - oroute_hash= &oroute_hash_table[hash][0]; - if (oroute_hash[0].orh_addr == dest) - oroute= oroute_hash[0].orh_route; - else if (oroute_hash[1].orh_addr == dest) - { - tmp_hash= oroute_hash[1]; - oroute_hash[1]= oroute_hash[0]; - oroute_hash[0]= tmp_hash; - oroute= tmp_hash.orh_route; - } - else if (oroute_hash[2].orh_addr == dest) - { - tmp_hash= oroute_hash[2]; - oroute_hash[2]= oroute_hash[1]; - oroute_hash[1]= oroute_hash[0]; - oroute_hash[0]= tmp_hash; - oroute= tmp_hash.orh_route; - } - else if (oroute_hash[3].orh_addr == dest) - { - tmp_hash= oroute_hash[3]; - oroute_hash[3]= oroute_hash[2]; - oroute_hash[2]= oroute_hash[1]; - oroute_hash[1]= oroute_hash[0]; - oroute_hash[0]= tmp_hash; - oroute= tmp_hash.orh_route; - } - else - oroute= NULL; - if (oroute) - { - assert(oroute->ort_port == port_nr); - if (oroute->ort_exp_tim && oroute->ort_exp_timort_flags &= ~ORTF_INUSE; - } - else - return oroute; - } - - bestroute= NULL; - for (oroute= oroute_head; oroute; oroute= oroute->ort_nextnw) - { - if (((dest ^ oroute->ort_dest) & oroute->ort_subnetmask) != 0) - continue; - if (oroute->ort_port != port_nr) - continue; - if (!bestroute) - { - bestroute= oroute; - continue; - } - assert(oroute->ort_dest != bestroute->ort_dest); - /* Using two ntohl macros in one expression - * is not allowed (tmp_l is modified twice) - */ - tmp_mask= ntohl(oroute->ort_subnetmask); - if (tmp_mask > ntohl(bestroute->ort_subnetmask)) - { - bestroute= oroute; - continue; - } - } - if (bestroute == NULL) - return NULL; - - oroute_hash[3]= oroute_hash[2]; - oroute_hash[2]= oroute_hash[1]; - oroute_hash[1]= oroute_hash[0]; - oroute_hash[0].orh_addr= dest; - oroute_hash[0].orh_route= bestroute; - - return bestroute; -} - - -static void oroute_del(oroute) -oroute_t *oroute; -{ - oroute_t *prev, *nw_route, *gw_route, *dist_route, *prev_route; - - DBLOCK(0x10, - printf("ip[%d]: deleting oroute to ", oroute->ort_port); - writeIpAddr(oroute->ort_dest); - printf("["); writeIpAddr(oroute->ort_subnetmask); - printf("] through "); - writeIpAddr(oroute->ort_gateway); - printf( - " timestamp %lds, timeout: %lds, distance %d pref %ld mtu %ld ", - (long)oroute->ort_timestamp/HZ, - (long)oroute->ort_exp_tim/HZ, oroute->ort_dist, - (long)oroute->ort_pref, (long)oroute->ort_mtu); - printf("flags 0x%x\n", oroute->ort_flags)); - - for (prev= NULL, nw_route= oroute_head; nw_route; - prev= nw_route, nw_route= nw_route->ort_nextnw) - { - if (oroute->ort_port == nw_route->ort_port && - oroute->ort_dest == nw_route->ort_dest && - oroute->ort_subnetmask == nw_route->ort_subnetmask) - { - break; - } - } - assert(nw_route); - if (prev) - prev->ort_nextnw= nw_route->ort_nextnw; - else - oroute_head= nw_route->ort_nextnw; - prev_route= nw_route; - for (prev= NULL, gw_route= nw_route; gw_route; - prev= gw_route, gw_route= gw_route->ort_nextgw) - { - if (oroute->ort_gateway == gw_route->ort_gateway) - break; - } - assert(gw_route); - if (prev) - prev->ort_nextgw= gw_route->ort_nextgw; - else - nw_route= gw_route->ort_nextgw; - for (prev= NULL, dist_route= gw_route; dist_route; - prev= dist_route, dist_route= dist_route->ort_nextdist) - { - if (oroute == dist_route) - break; - } - assert(dist_route); - if (prev) - prev->ort_nextdist= dist_route->ort_nextdist; - else - gw_route= dist_route->ort_nextdist; - gw_route= sort_dists(gw_route); - if (gw_route != NULL) - { - gw_route->ort_nextgw= nw_route; - nw_route= gw_route; - } - nw_route= sort_gws(nw_route); - if (nw_route != NULL) - { - nw_route->ort_nextnw= oroute_head; - oroute_head= nw_route; - } - if (nw_route != prev_route) - { - oroute_uncache_nw(prev_route->ort_dest, - prev_route->ort_subnetmask); - } -} - - -static oroute_t *sort_dists(oroute) -oroute_t *oroute; -{ - oroute_t *r, *prev, *best, *best_prev; - int best_dist, best_pref; - - best= NULL; - best_dist= best_pref= 0; - best_prev= NULL; - for (prev= NULL, r= oroute; r; prev= r, r= r->ort_nextdist) - { - if (best == NULL) - ; /* Force assignment to best */ - else if (r->ort_dist != best_dist) - { - if (r->ort_dist > best_dist) - continue; - } - else - { - if (r->ort_pref <= best_pref) - continue; - } - best= r; - best_prev= prev; - best_dist= r->ort_dist; - best_pref= r->ort_pref; - } - if (!best) - { - assert(oroute == NULL); - return oroute; - } - if (!best_prev) - { - assert(best == oroute); - return oroute; - } - best_prev->ort_nextdist= best->ort_nextdist; - best->ort_nextdist= oroute; - return best; -} - - -static oroute_t *sort_gws(oroute) -oroute_t *oroute; -{ - oroute_t *r, *prev, *best, *best_prev; - int best_dist, best_pref; - - best= NULL; - best_dist= best_pref= 0; - best_prev= NULL; - for (prev= NULL, r= oroute; r; prev= r, r= r->ort_nextgw) - { - if (best == NULL) - ; /* Force assignment to best */ - else if (r->ort_dist != best_dist) - { - if (r->ort_dist > best_dist) - continue; - } - else - { - if (r->ort_pref <= best_pref) - continue; - } - best= r; - best_prev= prev; - best_dist= r->ort_dist; - best_pref= r->ort_pref; - } - if (!best) - { - assert(oroute == NULL); - return oroute; - } - if (!best_prev) - { - assert(best == oroute); - return oroute; - } - best_prev->ort_nextgw= best->ort_nextgw; - best->ort_nextgw= oroute; - return best; -} - - -static void oroute_uncache_nw(dest, netmask) -ipaddr_t dest; -ipaddr_t netmask; -{ - int i, j; - oroute_hash_t *oroute_hash; - - for (i= 0, oroute_hash= &oroute_hash_table[0][0]; - i= IROUTE_NR) - return ENOENT; - - iroute= &iroute_table[ent_no]; - - route_ent->nwr_ent_no= ent_no; - route_ent->nwr_ent_count= IROUTE_NR; - route_ent->nwr_dest= iroute->irt_dest; - route_ent->nwr_netmask= iroute->irt_subnetmask; - route_ent->nwr_gateway= iroute->irt_gateway; - route_ent->nwr_dist= iroute->irt_dist; - route_ent->nwr_flags= NWRF_EMPTY; - if (iroute->irt_flags & IRTF_INUSE) - { - route_ent->nwr_flags |= NWRF_INUSE; - if (iroute->irt_flags & IRTF_STATIC) - route_ent->nwr_flags |= NWRF_STATIC; - if (iroute->irt_dist == IRTD_UNREACHABLE) - route_ent->nwr_flags |= NWRF_UNREACHABLE; - } - route_ent->nwr_pref= 0; - route_ent->nwr_mtu= iroute->irt_mtu; - route_ent->nwr_ifaddr= ip_get_ifaddr(iroute->irt_port); - return NW_OK; -} - - -int ipr_add_iroute(port_nr, dest, subnetmask, gateway, - dist, mtu, static_route, iroute_p) -int port_nr; -ipaddr_t dest; -ipaddr_t subnetmask; -ipaddr_t gateway; -int dist; -int mtu; -int static_route; -iroute_t **iroute_p; -{ - int i; - iroute_t *iroute, *unused_route; - ip_port_t *ip_port; - - ip_port= &ip_port_table[port_nr]; - - /* Check gateway */ - if (((gateway ^ ip_port->ip_ipaddr) & ip_port->ip_subnetmask) != 0 && - gateway != 0) - { - DBLOCK(1, printf("ip[%d] (ipr_add_iroute): invalid gateway: ", - port_nr); - writeIpAddr(gateway); printf("\n")); - return EINVAL; - } - - unused_route= NULL; - if (static_route) - { - /* Static routes are not reused automatically, so we look - * for an unused entry. - */ - for(i= 0, iroute= iroute_table; iirt_flags & IRTF_INUSE) == 0) - break; - } - if (i != IROUTE_NR) - unused_route= iroute; - } - else - { - /* Try to track down any old routes, and look for an - * unused one. - */ - for(i= 0, iroute= iroute_table; iirt_flags & IRTF_INUSE) == 0) - { - unused_route= iroute; - continue; - } - if ((iroute->irt_flags & IRTF_STATIC) != 0) - continue; - if (iroute->irt_port != port_nr || - iroute->irt_dest != dest || - iroute->irt_subnetmask != subnetmask || - iroute->irt_gateway != gateway) - { - continue; - } - break; - } - if (i != IROUTE_NR) - unused_route= iroute; - } - - if (unused_route == NULL) - return ENOMEM; - iroute= unused_route; - - iroute->irt_port= port_nr; - iroute->irt_dest= dest; - iroute->irt_subnetmask= subnetmask; - iroute->irt_gateway= gateway; - iroute->irt_dist= dist; - iroute->irt_mtu= mtu; - iroute->irt_flags= IRTF_INUSE; - if (static_route) - iroute->irt_flags |= IRTF_STATIC; - - iroute_uncache_nw(iroute->irt_dest, iroute->irt_subnetmask); - if (iroute_p != NULL) - *iroute_p= iroute; - return NW_OK; -} - - -int ipr_del_iroute(port_nr, dest, subnetmask, gateway, static_route) -int port_nr; -ipaddr_t dest; -ipaddr_t subnetmask; -ipaddr_t gateway; -int static_route; -{ - int i; - iroute_t *iroute; - - /* Try to track down any old routes, and look for an - * unused one. - */ - for(i= 0, iroute= iroute_table; iirt_flags & IRTF_INUSE) == 0) - continue; - if (iroute->irt_port != port_nr || - iroute->irt_dest != dest || - iroute->irt_subnetmask != subnetmask || - iroute->irt_gateway != gateway) - { - continue; - } - if (!!(iroute->irt_flags & IRTF_STATIC) != static_route) - continue; - break; - } - - if (i == IROUTE_NR) - return ESRCH; - - iroute_uncache_nw(iroute->irt_dest, iroute->irt_subnetmask); - iroute->irt_flags= IRTF_EMPTY; - return NW_OK; -} - - -void ipr_chk_itab(port_nr, addr, mask) -int port_nr; -ipaddr_t addr; -ipaddr_t mask; -{ - int i; - iroute_t *iroute; - - DBLOCK(1, - printf("ip[%d] (ipr_chk_itab): addr ", port_nr); - writeIpAddr(addr); - printf(" mask "); - writeIpAddr(mask); - printf("\n"); - ); - - if (addr == 0) - { - /* Special hack to flush entries for an interface that - * goes down. - */ - addr= mask= HTONL(0xffffffff); - } - - for(i= 0, iroute= iroute_table; iirt_flags & IRTF_INUSE) == 0) - continue; - if (iroute->irt_port != port_nr) - continue; - if (iroute->irt_gateway == 0) - { - /* Special case: attached network. */ - if (iroute->irt_subnetmask == mask && - iroute->irt_dest == (addr & mask)) - { - /* Nothing changed. */ - continue; - } - } - if (((iroute->irt_gateway ^ addr) & mask) == 0) - continue; - - DBLOCK(1, printf("ip[%d] (ipr_chk_itab): deleting route to ", - port_nr); - writeIpAddr(iroute->irt_dest); - printf(" gw "); - writeIpAddr(iroute->irt_gateway); - printf("\n")); - - iroute_uncache_nw(iroute->irt_dest, iroute->irt_subnetmask); - iroute->irt_flags &= ~IRTF_INUSE; - } -} - - -static void iroute_uncache_nw(dest, netmask) -ipaddr_t dest; -ipaddr_t netmask; -{ - int i, j; - iroute_hash_t *iroute_hash; - - for (i= 0, iroute_hash= &iroute_hash_table[0][0]; - ipp_flags= PPF_EMPTY; - - for (i=0, psip_fd= psip_fd_table; ipf_flags= PFF_EMPTY; - - for (i=0, psip_port= psip_port_table; ipp_flags |= PPF_CONFIGURED; - psip_port->pp_opencnt= 0; - psip_port->pp_rd_head= NULL; - psip_port->pp_promisc_head= NULL; - } - -#ifndef BUF_CONSISTENCY_CHECK - bf_logon(psip_buffree); -#else - bf_logon(psip_buffree, psip_bufcheck); -#endif -} - -int psip_enable(port_nr, ip_port_nr) -int port_nr; -int ip_port_nr; -{ - psip_port_t *psip_port; - - assert(port_nr >= 0); - if (port_nr >= psip_conf_nr) - return -1; - - psip_port= &psip_port_table[port_nr]; - if (!(psip_port->pp_flags &PPF_CONFIGURED)) - return -1; - - psip_port->pp_ipdev= ip_port_nr; - psip_port->pp_flags |= PPF_ENABLED; - - sr_add_minor(if2minor(psip_conf[port_nr].pc_ifno, PSIP_DEV_OFF), - port_nr, psip_open, psip_close, psip_read, - psip_write, psip_ioctl, psip_cancel, psip_select); - - return NW_OK; -} - -int psip_send(port_nr, dest, pack) -int port_nr; -ipaddr_t dest; -acc_t *pack; -{ - psip_port_t *psip_port; - psip_fd_t *psip_fd, *mark_fd; - int i, result, result1; - size_t buf_size, extrasize; - acc_t *hdr_pack, *acc; - psip_io_hdr_t *hdr; - - assert(port_nr >= 0 && port_nr < psip_conf_nr); - psip_port= &psip_port_table[port_nr]; - - if (psip_port->pp_opencnt == 0) - { - bf_afree(pack); - return NW_OK; - } - - for(;;) - { - mark_fd= psip_port->pp_rd_tail; - - for(i= 0; ipp_rd_head; - if (!psip_fd) - return NW_SUSPEND; - psip_port->pp_rd_head= psip_fd->pf_rd_next; - if (!(psip_fd->pf_flags & PFF_PROMISC)) - break; - psip_fd->pf_rd_next= NULL; - if (psip_port->pp_rd_head == NULL) - psip_port->pp_rd_head= psip_fd; - else - psip_port->pp_rd_tail->pf_rd_next= psip_fd; - psip_port->pp_rd_tail= psip_fd; - if (psip_fd == mark_fd) - return NW_SUSPEND; - } - if (i == PSIP_FD_NR) - ip_panic(( "psip_send: loop" )); - - assert(psip_fd->pf_flags & PFF_READ_IP); - psip_fd->pf_flags &= ~PFF_READ_IP; - - if (psip_fd->pf_flags & PFF_NEXTHOP) - extrasize= sizeof(dest); - else - extrasize= 0; - - buf_size= bf_bufsize(pack); - if (buf_size+extrasize <= psip_fd->pf_rd_count) - { - if (psip_port->pp_flags & PPF_PROMISC) - { - /* Deal with promiscuous mode. */ - hdr_pack= bf_memreq(sizeof(*hdr)); - hdr= (psip_io_hdr_t *)ptr2acc_data(hdr_pack); - memset(hdr, '\0', sizeof(*hdr)); - hdr->pih_flags |= PF_LOC2REM; - hdr->pih_nexthop= dest; - - pack->acc_linkC++; - hdr_pack->acc_next= pack; - hdr_pack->acc_ext_link= NULL; - if (psip_port->pp_promisc_head) - { - /* Append at the end. */ - psip_port->pp_promisc_tail-> - acc_ext_link= hdr_pack; - psip_port->pp_promisc_tail= hdr_pack; - } - else - { - /* First packet. */ - psip_port->pp_promisc_head= hdr_pack; - psip_port->pp_promisc_tail= hdr_pack; - if (psip_port->pp_rd_head) - promisc_restart_read(psip_port); - } - } - - if (extrasize) - { - /* Prepend nexthop address */ - acc= bf_memreq(sizeof(dest)); - *(ipaddr_t *)(ptr2acc_data(acc))= dest; - acc->acc_next= pack; - pack= acc; acc= NULL; - buf_size += extrasize; - } - - result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)0, pack, FALSE); - if (result == NW_OK) - result= buf_size; - } - else - result= EPACKSIZE; - - result1= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)result, NULL, FALSE); - assert(result1 == NW_OK); - if (result == EPACKSIZE) - continue; - return NW_OK; - } - return NW_SUSPEND; -} - -static int psip_open(port, srfd, get_userdata, put_userdata, put_pkt, - select_res) -int port; -int srfd; -get_userdata_t get_userdata; -put_userdata_t put_userdata; -put_pkt_t put_pkt; -select_res_t select_res; -{ - psip_port_t *psip_port; - psip_fd_t *psip_fd; - int i; - - assert(port >= 0 && port < psip_conf_nr); - psip_port= &psip_port_table[port]; - - if (!(psip_port->pp_flags & PPF_ENABLED)) - return ENXIO; - - for (i= 0, psip_fd= psip_fd_table; ipf_flags & PFF_INUSE) - continue; - break; - } - if (i == PSIP_FD_NR) - return ENFILE; - psip_fd->pf_flags |= PFF_INUSE; - psip_fd->pf_srfd= srfd; - psip_fd->pf_port= psip_port; - psip_fd->pf_get_userdata= get_userdata; - psip_fd->pf_put_userdata= put_userdata; - psip_port->pp_opencnt++; - - return i; -} - -static int psip_ioctl(fd, req) -int fd; -ioreq_t req; -{ - int result; - psip_fd_t *psip_fd; - acc_t *data; - nwio_ipconf_t *ipconfp; - nwio_psipopt_t *psip_opt, *newoptp; - - assert(fd >= 0 && fd < PSIP_FD_NR); - psip_fd= &psip_fd_table[fd]; - - switch(req) - { - case NWIOSIPCONF: - data= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, 0, - sizeof(*ipconfp), TRUE); - if (!data) - { - result= EFAULT; - break; - } - data= bf_packIffLess(data, sizeof(*ipconfp)); - assert (data->acc_length == sizeof(*ipconfp)); - - ipconfp= (nwio_ipconf_t *)ptr2acc_data(data); - result= ip_setconf(psip_fd->pf_port->pp_ipdev, ipconfp); - bf_afree(data); - reply_thr_get(psip_fd, result, TRUE); - break; - case NWIOSPSIPOPT: - data= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, 0, - sizeof(*psip_opt), TRUE); - if (!data) - { - result= EFAULT; - break; - } - data= bf_packIffLess(data, sizeof(*psip_opt)); - assert (data->acc_length == sizeof(*psip_opt)); - - newoptp= (nwio_psipopt_t *)ptr2acc_data(data); - result= psip_setopt(psip_fd, newoptp); - bf_afree(data); - if (result == NW_OK) - { - if (psip_fd->pf_psipopt.nwpo_flags & NWPO_EN_PROMISC) - { - psip_fd->pf_flags |= PFF_PROMISC; - psip_fd->pf_port->pp_flags |= PPF_PROMISC; - } - else - { - psip_fd->pf_flags &= ~PFF_PROMISC; - check_promisc(psip_fd->pf_port); - } - if (psip_fd->pf_psipopt.nwpo_flags & NWPO_EN_NEXTHOP) - { - psip_fd->pf_flags |= PFF_NEXTHOP; - } - else - { - psip_fd->pf_flags &= ~PFF_NEXTHOP; - } - } - reply_thr_get(psip_fd, result, TRUE); - break; - case NWIOGPSIPOPT: - data= bf_memreq(sizeof(*psip_opt)); - psip_opt= (nwio_psipopt_t *)ptr2acc_data(data); - - *psip_opt= psip_fd->pf_psipopt; - result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, 0, - data, TRUE); - if (result == NW_OK) - reply_thr_put(psip_fd, NW_OK, TRUE); - break; - default: - reply_thr_put(psip_fd, ENOTTY, TRUE); - break; - } - return NW_OK; -} - -static int psip_read(fd, count) -int fd; -size_t count; -{ - psip_port_t *psip_port; - psip_fd_t *psip_fd; - acc_t *pack; - size_t buf_size; - int result, result1; - - assert(fd >= 0 && fd < PSIP_FD_NR); - psip_fd= &psip_fd_table[fd]; - psip_port= psip_fd->pf_port; - - if ((psip_fd->pf_flags & PFF_PROMISC) && psip_port->pp_promisc_head) - { - /* Deliver a queued packet. */ - pack= psip_port->pp_promisc_head; - buf_size= bf_bufsize(pack); - if (buf_size <= count) - { - psip_port->pp_promisc_head= pack->acc_ext_link; - result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)0, pack, FALSE); - if (result == NW_OK) - result= buf_size; - } - else - result= EPACKSIZE; - - result1= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)result, NULL, FALSE); - assert(result1 == NW_OK); - return NW_OK; - } - - psip_fd->pf_rd_count= count; - if (psip_port->pp_rd_head == NULL) - psip_port->pp_rd_head= psip_fd; - else - psip_port->pp_rd_tail->pf_rd_next= psip_fd; - psip_fd->pf_rd_next= NULL; - psip_port->pp_rd_tail= psip_fd; - - psip_fd->pf_flags |= PFF_READ_IP; - if (!(psip_fd->pf_flags & PFF_PROMISC)) - ipps_get(psip_port->pp_ipdev); - if (psip_fd->pf_flags & PFF_READ_IP) - return NW_SUSPEND; - return NW_OK; -} - -static int psip_write(fd, count) -int fd; -size_t count; -{ - psip_port_t *psip_port; - psip_fd_t *psip_fd; - acc_t *pack, *hdr_pack; - psip_io_hdr_t *hdr; - size_t pack_len; - ipaddr_t nexthop; - - assert(fd >= 0 && fd < PSIP_FD_NR); - psip_fd= &psip_fd_table[fd]; - psip_port= psip_fd->pf_port; - - pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, (size_t)0, - count, FALSE); - if (pack == NULL) - { - pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, - (size_t)EFAULT, (size_t)0, FALSE); - assert(pack == NULL); - return NW_OK; - } - - if (psip_fd->pf_flags & PFF_NEXTHOP) - { - pack_len= bf_bufsize(pack); - if (pack_len <= sizeof(nexthop)) - { - /* Something strange */ - bf_afree(pack); pack= NULL; - pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, - (size_t)EPACKSIZE, (size_t)0, FALSE); - assert(pack == NULL); - return NW_OK; - } - pack= bf_packIffLess(pack, sizeof(nexthop)); - nexthop= *(ipaddr_t *)ptr2acc_data(pack); - pack= bf_delhead(pack, sizeof(nexthop)); - - /* Map multicast to broadcast */ - if ((nexthop & HTONL(0xE0000000)) == HTONL(0xE0000000)) - nexthop= HTONL(0xffffffff); - } - else - { - /* Assume point to point */ - nexthop= HTONL(0x00000000); - } - - if (psip_port->pp_flags & PPF_PROMISC) - { - /* Deal with promiscuous mode. */ - hdr_pack= bf_memreq(sizeof(*hdr)); - hdr= (psip_io_hdr_t *)ptr2acc_data(hdr_pack); - memset(hdr, '\0', sizeof(*hdr)); - hdr->pih_flags |= PF_REM2LOC; - hdr->pih_nexthop= nexthop; - - pack->acc_linkC++; - hdr_pack->acc_next= pack; - hdr_pack->acc_ext_link= NULL; - if (psip_port->pp_promisc_head) - { - /* Append at the end. */ - psip_port->pp_promisc_tail->acc_ext_link= hdr_pack; - psip_port->pp_promisc_tail= hdr_pack; - } - else - { - /* First packet. */ - psip_port->pp_promisc_head= hdr_pack; - psip_port->pp_promisc_tail= hdr_pack; - if (psip_port->pp_rd_head) - promisc_restart_read(psip_port); - } - } - ipps_put(psip_port->pp_ipdev, nexthop, pack); - pack= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, (size_t)count, - (size_t)0, FALSE); - assert(pack == NULL); - return NW_OK; -} - -static int psip_select(fd, operations) -int fd; -unsigned operations; -{ - printf("psip_select: not implemented\n"); - return 0; -} - -static void psip_close(fd) -int fd; -{ - psip_port_t *psip_port; - psip_fd_t *psip_fd; - - assert(fd >= 0 && fd < PSIP_FD_NR); - psip_fd= &psip_fd_table[fd]; - psip_port= psip_fd->pf_port; - - if (psip_fd->pf_flags & PFF_PROMISC) - { - /* Check if the port should still be in promiscuous mode. - */ - psip_fd->pf_flags &= ~PFF_PROMISC; - check_promisc(psip_fd->pf_port); - } - - assert(psip_port->pp_opencnt >0); - psip_port->pp_opencnt--; - psip_fd->pf_flags= PFF_EMPTY; - ipps_get(psip_port->pp_ipdev); - -} - -static int psip_cancel(fd, which_operation) -int fd; -int which_operation; -{ - psip_port_t *psip_port; - psip_fd_t *psip_fd, *prev_fd, *tmp_fd; - int result; - - DBLOCK(1, printf("psip_cancel(%d, %d)\n", fd, which_operation)); - - assert(fd >= 0 && fd < PSIP_FD_NR); - psip_fd= &psip_fd_table[fd]; - psip_port= psip_fd->pf_port; - - switch(which_operation) - { - case SR_CANCEL_IOCTL: - ip_panic(( "should not be here" )); - case SR_CANCEL_READ: - assert(psip_fd->pf_flags & PFF_READ_IP); - for (prev_fd= NULL, tmp_fd= psip_port->pp_rd_head; tmp_fd; - prev_fd= tmp_fd, tmp_fd= tmp_fd->pf_rd_next) - { - if (tmp_fd == psip_fd) - break; - } - if (tmp_fd == NULL) - ip_panic(( "unable to find to request to cancel" )); - if (prev_fd == NULL) - psip_port->pp_rd_head= psip_fd->pf_rd_next; - else - prev_fd->pf_rd_next= psip_fd->pf_rd_next; - if (psip_fd->pf_rd_next == NULL) - psip_port->pp_rd_tail= prev_fd; - psip_fd->pf_flags &= ~PFF_READ_IP; - result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)EINTR, NULL, FALSE); - assert(result == NW_OK); - break; - case SR_CANCEL_WRITE: - ip_panic(( "should not be here" )); - default: - ip_panic(( "invalid operation for cancel" )); - } - return NW_OK; -} - -static void promisc_restart_read(psip_port) -psip_port_t *psip_port; -{ - psip_fd_t *psip_fd, *prev, *next; - acc_t *pack; - size_t buf_size; - int result, result1; - - /* Overkill at the moment: just one reader in promiscious mode is - * allowed. - */ - pack= psip_port->pp_promisc_head; - if (!pack) - return; - assert(pack->acc_ext_link == NULL); - - for(psip_fd= psip_port->pp_rd_head, prev= NULL; psip_fd; - prev= psip_fd, psip_fd= psip_fd->pf_rd_next) - { -again: - if (!(psip_fd->pf_flags & PFF_PROMISC)) - continue; - next= psip_fd->pf_rd_next; - if (prev) - prev->pf_rd_next= next; - else - psip_port->pp_rd_head= next; - if (!next) - psip_port->pp_rd_tail= prev; - - assert(psip_fd->pf_flags & PFF_READ_IP); - psip_fd->pf_flags &= ~PFF_READ_IP; - - buf_size= bf_bufsize(pack); - if (buf_size <= psip_fd->pf_rd_count) - { - psip_port->pp_promisc_head= pack->acc_ext_link; - result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)0, pack, FALSE); - if (result == NW_OK) - result= buf_size; - } - else - result= EPACKSIZE; - - result1= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, - (size_t)result, NULL, FALSE); - assert(result1 == NW_OK); - - if (psip_port->pp_promisc_head) - { - /* Restart from the beginning */ - assert(result == EPACKSIZE); - psip_fd= psip_port->pp_rd_head; - prev= NULL; - goto again; - } - break; - } -} - -static int psip_setopt(psip_fd, newoptp) -psip_fd_t *psip_fd; -nwio_psipopt_t *newoptp; -{ - nwio_psipopt_t oldopt; - unsigned int new_en_flags, new_di_flags, old_en_flags, old_di_flags; - unsigned long new_flags; - - oldopt= psip_fd->pf_psipopt; - - old_en_flags= oldopt.nwpo_flags & 0xffff; - old_di_flags= (oldopt.nwpo_flags >> 16) & 0xffff; - - new_en_flags= newoptp->nwpo_flags & 0xffff; - new_di_flags= (newoptp->nwpo_flags >> 16) & 0xffff; - - if (new_en_flags & new_di_flags) - return EBADMODE; - - /* NWUO_LOCADDR_MASK */ - if (!((new_en_flags | new_di_flags) & NWPO_PROMISC_MASK)) - { - new_en_flags |= (old_en_flags & NWPO_PROMISC_MASK); - new_di_flags |= (old_di_flags & NWPO_PROMISC_MASK); - } - - new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags; - if ((new_flags & NWPO_EN_PROMISC) && - (psip_fd->pf_port->pp_flags & PPF_PROMISC)) - { - printf("psip_setopt: EBUSY for port %d, flags 0x%x\n", - psip_fd->pf_port - psip_port_table, - psip_fd->pf_port->pp_flags); - /* We can support only one at a time. */ - return EBUSY; - } - - psip_fd->pf_psipopt= *newoptp; - psip_fd->pf_psipopt.nwpo_flags= new_flags; - - return NW_OK; -} - -static void check_promisc(psip_port) -psip_port_t *psip_port; -{ - int i; - psip_fd_t *psip_fd; - acc_t *acc, *acc_next; - - /* Check if the port should still be in promiscuous mode. Overkill - * at the moment. - */ - if (!(psip_port->pp_flags & PPF_PROMISC)) - return; - - psip_port->pp_flags &= ~PPF_PROMISC; - for (i= 0, psip_fd= psip_fd_table; ipf_flags & (PFF_INUSE|PFF_PROMISC)) != - (PFF_INUSE|PFF_PROMISC)) - { - continue; - } - if (psip_fd->pf_port != psip_port) - continue; - printf("check_promisc: setting PROMISC for port %d\n", - psip_port-psip_port_table); - psip_port->pp_flags |= PPF_PROMISC; - break; - } - if (!(psip_port->pp_flags & PPF_PROMISC)) - { - /* Delete queued packets. */ - acc= psip_port->pp_promisc_head; - psip_port->pp_promisc_head= NULL; - while (acc) - { - acc_next= acc->acc_ext_link; - bf_afree(acc); - acc= acc_next; - } - } -} - -static void psip_buffree (priority) -int priority; -{ - int i; - psip_port_t *psip_port; - acc_t *tmp_acc, *next_acc; - - if (priority == PSIP_PRI_EXP_PROMISC) - { - for (i=0, psip_port= psip_port_table; ipp_flags & PPF_CONFIGURED) ) - continue; - if (psip_port->pp_promisc_head) - { - tmp_acc= psip_port->pp_promisc_head; - while(tmp_acc) - { - next_acc= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - tmp_acc= next_acc; - } - psip_port->pp_promisc_head= NULL; - } - } - } -} - -#ifdef BUF_CONSISTENCY_CHECK -static void psip_bufcheck() -{ - int i; - psip_port_t *psip_port; - acc_t *tmp_acc; - - for (i= 0, psip_port= psip_port_table; ipp_promisc_head; tmp_acc; - tmp_acc= tmp_acc->acc_ext_link) - { - bf_check_acc(tmp_acc); - } - } -} -#endif - -/* -reply_thr_put -*/ - -static void reply_thr_put(psip_fd, reply, for_ioctl) -psip_fd_t *psip_fd; -int reply; -int for_ioctl; -{ - int result; - - result= (*psip_fd->pf_put_userdata)(psip_fd->pf_srfd, reply, - (acc_t *)0, for_ioctl); - assert(result == NW_OK); -} - -/* -reply_thr_get -*/ - -static void reply_thr_get(psip_fd, reply, for_ioctl) -psip_fd_t *psip_fd; -int reply; -int for_ioctl; -{ - acc_t *result; - result= (*psip_fd->pf_get_userdata)(psip_fd->pf_srfd, reply, - (size_t)0, for_ioctl); - assert (!result); -} - - -/* - * $PchId: psip.c,v 1.15 2005/06/28 14:19:29 philip Exp $ - */ diff --git a/minix/net/inet/generic/psip.h b/minix/net/inet/generic/psip.h deleted file mode 100644 index 22f38d359..000000000 --- a/minix/net/inet/generic/psip.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -generic/psip.h - -Public interface to the pseudo IP module - -Created: Apr 22, 1993 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef PSIP_H -#define PSIP_H - -void psip_prep ARGS(( void )); -void psip_init ARGS(( void )); -int psip_enable ARGS(( int port_nr, int ip_port_nr )); -int psip_send ARGS(( int port_nr, ipaddr_t dest, acc_t *pack )); - -#endif /* PSIP_H */ - -/* - * $PchId: psip.h,v 1.6 2001/04/19 21:16:22 philip Exp $ - */ diff --git a/minix/net/inet/generic/rand256.c b/minix/net/inet/generic/rand256.c deleted file mode 100644 index 631cbe0fa..000000000 --- a/minix/net/inet/generic/rand256.c +++ /dev/null @@ -1,37 +0,0 @@ -/* -rand256.c - -Created: Oct 2000 by Philip Homburg - -Generate 256-bit random numbers -*/ - -#include -#include "inet.h" -#include "rand256.h" - -static u32_t base_bits[8]; - -void init_rand256(bits) -u8_t bits[32]; -{ - memcpy(base_bits, bits, sizeof(base_bits)); -} - -void rand256(bits) -u8_t bits[32]; -{ - u32_t a; - SHA256_CTX ctx; - - a= ++base_bits[0]; - if (a == 0) - base_bits[1]++; - SHA256_Init(&ctx); - SHA256_Update(&ctx, (unsigned char *)base_bits, sizeof(base_bits)); - SHA256_Final(bits, &ctx); -} - -/* - * $PchId: rand256.c,v 1.1 2005/06/28 14:13:43 philip Exp $ - */ diff --git a/minix/net/inet/generic/rand256.h b/minix/net/inet/generic/rand256.h deleted file mode 100644 index ff686121f..000000000 --- a/minix/net/inet/generic/rand256.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -rand256.h - -Created: Oct 2000 by Philip Homburg - -Provide 256-bit random numbers -*/ - -#define RAND256_BUFSIZE 32 - -void init_rand256 ARGS(( u8_t bits[RAND256_BUFSIZE] )); -void rand256 ARGS(( u8_t bits[RAND256_BUFSIZE] )); - -/* - * $PchId: rand256.h,v 1.1 2005/06/28 14:14:05 philip Exp $ - */ diff --git a/minix/net/inet/generic/sr.h b/minix/net/inet/generic/sr.h deleted file mode 100644 index 86cdaf2ba..000000000 --- a/minix/net/inet/generic/sr.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -sr.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef SR_H -#define SR_H - -#define MAX_IOCTL_S 512 - -#define SR_CANCEL_IOCTL 1 -#define SR_CANCEL_READ 2 -#define SR_CANCEL_WRITE 3 - -#define SR_SELECT_READ 0x01 -#define SR_SELECT_WRITE 0x02 -#define SR_SELECT_EXCEPTION 0x04 -#define SR_SELECT_POLL 0x10 - -/* Forward struct declarations */ - -struct acc; - -/* prototypes */ - -typedef int (*sr_open_t) ARGS(( int port, int srfd, - get_userdata_t get_userdata, put_userdata_t put_userdata, - put_pkt_t put_pkt, select_res_t select_res )); -typedef void (*sr_close_t) ARGS(( int fd )); -typedef int (*sr_read_t) ARGS(( int fd, size_t count )); -typedef int (*sr_write_t) ARGS(( int fd, size_t count )); -typedef int (*sr_ioctl_t) ARGS(( int fd, ioreq_t req )); -typedef int (*sr_cancel_t) ARGS(( int fd, int which_operation )); -typedef int (*sr_select_t) ARGS(( int fd, unsigned operations )); - -void sr_init ARGS(( void )); -void sr_add_minor ARGS(( int minor, int port, sr_open_t openf, - sr_close_t closef, sr_read_t sr_read, sr_write_t sr_write, - sr_ioctl_t ioctlf, sr_cancel_t cancelf, sr_select_t selectf )); - -#endif /* SR_H */ - -/* Track TCP connections back into sr (for lsof, identd, etc.) */ -EXTERN sr_cancel_t tcp_cancel_f; - -/* - * $PchId: sr.h,v 1.9 2005/06/28 14:19:51 philip Exp $ - */ diff --git a/minix/net/inet/generic/tcp.c b/minix/net/inet/generic/tcp.c deleted file mode 100644 index 6827e65f8..000000000 --- a/minix/net/inet/generic/tcp.c +++ /dev/null @@ -1,2727 +0,0 @@ -/* -tcp.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "type.h" - -#include "io.h" -#include "ip.h" -#include "sr.h" -#include "assert.h" -#include "rand256.h" -#include "tcp.h" -#include "tcp_int.h" - -THIS_FILE - -tcp_port_t *tcp_port_table; -tcp_fd_t tcp_fd_table[TCP_FD_NR]; -tcp_conn_t tcp_conn_table[TCP_CONN_NR]; -sr_cancel_t tcp_cancel_f; - -static void tcp_main ARGS(( tcp_port_t *port )); -static int tcp_select ARGS(( int fd, unsigned operations )); -static acc_t *tcp_get_data ARGS(( int fd, size_t offset, - size_t count, int for_ioctl )); -static int tcp_put_data ARGS(( int fd, size_t offset, - acc_t *data, int for_ioctl )); -static void tcp_put_pkt ARGS(( int fd, acc_t *data, size_t datalen )); -static void read_ip_packets ARGS(( tcp_port_t *port )); -static int tcp_setconf ARGS(( tcp_fd_t *tcp_fd )); -static int tcp_setopt ARGS(( tcp_fd_t *tcp_fd )); -static int tcp_connect ARGS(( tcp_fd_t *tcp_fd )); -static int tcp_listen ARGS(( tcp_fd_t *tcp_fd, int do_listenq )); -static int tcp_acceptto ARGS(( tcp_fd_t *tcp_fd )); -static tcpport_t find_unused_port ARGS(( int fd )); -static int is_unused_port ARGS(( tcpport_t port )); -static int reply_thr_put ARGS(( tcp_fd_t *tcp_fd, int reply, - int for_ioctl )); -static void reply_thr_get ARGS(( tcp_fd_t *tcp_fd, int reply, - int for_ioctl )); -static tcp_conn_t *find_conn_entry ARGS(( tcpport_t locport, - ipaddr_t locaddr, tcpport_t remport, ipaddr_t readaddr )); -static tcp_conn_t *find_empty_conn ARGS(( void )); -static tcp_conn_t *find_best_conn ARGS(( ip_hdr_t *ip_hdr, - tcp_hdr_t *tcp_hdr )); -static tcp_conn_t *new_conn_for_queue ARGS(( tcp_fd_t *tcp_fd )); -static int maybe_listen ARGS(( ipaddr_t locaddr, tcpport_t locport, - ipaddr_t remaddr, tcpport_t remport )); -static int tcp_su4connect ARGS(( tcp_fd_t *tcp_fd )); -static void tcp_buffree ARGS(( int priority )); -#ifdef BUF_CONSISTENCY_CHECK -static void tcp_bufcheck ARGS(( void )); -#endif -static void tcp_setup_conn ARGS(( tcp_port_t *tcp_port, - tcp_conn_t *tcp_conn )); -static u32_t tcp_rand32 ARGS(( void )); - -void tcp_prep() -{ - tcp_port_table= alloc(tcp_conf_nr * sizeof(tcp_port_table[0])); -} - -void tcp_init() -{ - int i, j, k, ifno; - tcp_fd_t *tcp_fd; - tcp_port_t *tcp_port; - tcp_conn_t *tcp_conn; - - assert (BUF_S >= sizeof(struct nwio_ipopt)); - assert (BUF_S >= sizeof(struct nwio_ipconf)); - assert (BUF_S >= sizeof(struct nwio_tcpconf)); - assert (BUF_S >= IP_MAX_HDR_SIZE + TCP_MAX_HDR_SIZE); - - for (i=0, tcp_fd= tcp_fd_table; itf_flags= TFF_EMPTY; - } - - for (i=0, tcp_conn= tcp_conn_table; itc_flags= TCF_EMPTY; - tcp_conn->tc_busy= 0; - } - -#ifndef BUF_CONSISTENCY_CHECK - bf_logon(tcp_buffree); -#else - bf_logon(tcp_buffree, tcp_bufcheck); -#endif - - for (i=0, tcp_port= tcp_port_table; itp_ipdev= tcp_conf[i].tc_port; - - tcp_port->tp_flags= TPF_EMPTY; - tcp_port->tp_state= TPS_EMPTY; - tcp_port->tp_snd_head= NULL; - tcp_port->tp_snd_tail= NULL; - ev_init(&tcp_port->tp_snd_event); - for (j= 0; jtp_conn_hash[j][k]= - &tcp_conn_table[0]; - } - } - - ifno= ip_conf[tcp_port->tp_ipdev].ic_ifno; - sr_add_minor(if2minor(ifno, TCP_DEV_OFF), - i, tcp_open, tcp_close, tcp_read, - tcp_write, tcp_ioctl, tcp_cancel, tcp_select); - - tcp_main(tcp_port); - } - tcp_cancel_f= tcp_cancel; -} - -static void tcp_main(tcp_port) -tcp_port_t *tcp_port; -{ - int result, i; - tcp_conn_t *tcp_conn; - tcp_fd_t *tcp_fd; - - switch (tcp_port->tp_state) - { - case TPS_EMPTY: - tcp_port->tp_state= TPS_SETPROTO; - tcp_port->tp_ipfd= ip_open(tcp_port->tp_ipdev, - tcp_port->tp_ipdev, tcp_get_data, - tcp_put_data, tcp_put_pkt, 0 /* no select_res */); - if (tcp_port->tp_ipfd < 0) - { - tcp_port->tp_state= TPS_ERROR; - DBLOCK(1, printf("%s, %d: unable to open ip port\n", - __FILE__, __LINE__)); - return; - } - - result= ip_ioctl(tcp_port->tp_ipfd, NWIOSIPOPT); - if (result == NW_SUSPEND) - tcp_port->tp_flags |= TPF_SUSPEND; - if (result < 0) - { - return; - } - if (tcp_port->tp_state != TPS_GETCONF) - return; - /* drops through */ - case TPS_GETCONF: - tcp_port->tp_flags &= ~TPF_SUSPEND; - - result= ip_ioctl(tcp_port->tp_ipfd, NWIOGIPCONF); - if (result == NW_SUSPEND) - tcp_port->tp_flags |= TPF_SUSPEND; - if (result < 0) - { - return; - } - if (tcp_port->tp_state != TPS_MAIN) - return; - /* drops through */ - case TPS_MAIN: - tcp_port->tp_flags &= ~TPF_SUSPEND; - tcp_port->tp_pack= 0; - - tcp_conn= &tcp_conn_table[tcp_port->tp_ipdev]; - tcp_conn->tc_flags= TCF_INUSE; - assert(!tcp_conn->tc_busy); - tcp_conn->tc_locport= 0; - tcp_conn->tc_locaddr= tcp_port->tp_ipaddr; - tcp_conn->tc_remport= 0; - tcp_conn->tc_remaddr= 0; - tcp_conn->tc_state= TCS_CLOSED; - tcp_conn->tc_fd= 0; - tcp_conn->tc_connInprogress= 0; - tcp_conn->tc_orglisten= FALSE; - tcp_conn->tc_senddis= 0; - tcp_conn->tc_ISS= 0; - tcp_conn->tc_SND_UNA= tcp_conn->tc_ISS; - tcp_conn->tc_SND_TRM= tcp_conn->tc_ISS; - tcp_conn->tc_SND_NXT= tcp_conn->tc_ISS; - tcp_conn->tc_SND_UP= tcp_conn->tc_ISS; - tcp_conn->tc_IRS= 0; - tcp_conn->tc_RCV_LO= tcp_conn->tc_IRS; - tcp_conn->tc_RCV_NXT= tcp_conn->tc_IRS; - tcp_conn->tc_RCV_HI= tcp_conn->tc_IRS; - tcp_conn->tc_RCV_UP= tcp_conn->tc_IRS; - tcp_conn->tc_port= tcp_port; - tcp_conn->tc_rcvd_data= NULL; - tcp_conn->tc_adv_data= NULL; - tcp_conn->tc_send_data= 0; - tcp_conn->tc_remipopt= NULL; - tcp_conn->tc_tcpopt= NULL; - tcp_conn->tc_frag2send= 0; - tcp_conn->tc_tos= TCP_DEF_TOS; - tcp_conn->tc_ttl= IP_MAX_TTL; - tcp_conn->tc_rcv_wnd= TCP_MAX_RCV_WND_SIZE; - tcp_conn->tc_rt_dead= TCP_DEF_RT_DEAD; - tcp_conn->tc_stt= 0; - tcp_conn->tc_0wnd_to= 0; - tcp_conn->tc_artt= TCP_DEF_RTT*TCP_RTT_SCALE; - tcp_conn->tc_drtt= 0; - tcp_conn->tc_rtt= TCP_DEF_RTT; - tcp_conn->tc_max_mtu= tcp_port->tp_mtu; - tcp_conn->tc_mtu= tcp_conn->tc_max_mtu; - tcp_conn->tc_mtutim= 0; - tcp_conn->tc_error= NW_OK; - tcp_conn->tc_snd_wnd= TCP_MAX_SND_WND_SIZE; - tcp_conn->tc_snd_cinc= - (long)TCP_DEF_MSS*TCP_DEF_MSS/TCP_MAX_SND_WND_SIZE+1; - - tcp_conn->tc_rt_time= 0; - tcp_conn->tc_rt_seq= 0; - tcp_conn->tc_rt_threshold= tcp_conn->tc_ISS; - - for (i=0, tcp_fd= tcp_fd_table; itf_flags & TFF_INUSE)) - continue; - if (tcp_fd->tf_port != tcp_port) - continue; - if (tcp_fd->tf_flags & TFF_IOC_INIT_SP) - { - tcp_fd->tf_flags &= ~TFF_IOC_INIT_SP; - tcp_ioctl(i, tcp_fd->tf_ioreq); - } - } - read_ip_packets(tcp_port); - return; - - default: - ip_panic(( "unknown state" )); - break; - } -} - -static int tcp_select(fd, operations) -int fd; -unsigned operations; -{ - int i; - unsigned resops; - tcp_fd_t *tcp_fd; - tcp_conn_t *tcp_conn; - - tcp_fd= &tcp_fd_table[fd]; - assert (tcp_fd->tf_flags & TFF_INUSE); - - resops= 0; - if (tcp_fd->tf_flags & TFF_LISTENQ) - { - /* Special case for LISTENQ */ - if (operations & SR_SELECT_READ) - { - for (i= 0; itf_listenq[i] == NULL) - continue; - if (tcp_fd->tf_listenq[i]->tc_connInprogress - == 0) - { - break; - } - } - if (i >= TFL_LISTEN_MAX) - tcp_fd->tf_flags |= TFF_SEL_READ; - else - resops |= SR_SELECT_READ; - } - if (operations & SR_SELECT_WRITE) - { - /* We can't handles writes. Just return the error - * when the user tries to write. - */ - resops |= SR_SELECT_WRITE; - } - return resops; - } - if (tcp_fd->tf_flags & TFF_CONNECTING) - { - /* Special case for CONNECTING */ - if (operations & SR_SELECT_WRITE) - tcp_fd->tf_flags |= TFF_SEL_WRITE; - return 0; - } - if (operations & SR_SELECT_READ) - { - tcp_conn= tcp_fd->tf_conn; - - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - { - /* We can't handle reads until a connection has been - * established. Return the error when the user tries - * to read. - */ - resops |= SR_SELECT_READ; - } - else if (tcp_conn->tc_state == TCS_CLOSED || - tcp_sel_read(tcp_conn)) - { - resops |= SR_SELECT_READ; - } - else if (!(operations & SR_SELECT_POLL)) - tcp_fd->tf_flags |= TFF_SEL_READ; - } - if (operations & SR_SELECT_WRITE) - { - tcp_conn= tcp_fd->tf_conn; - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - { - /* We can't handle writes until a connection has been - * established. Return the error when the user tries - * to write. - */ - resops |= SR_SELECT_WRITE; - } - else if (tcp_conn->tc_state == TCS_CLOSED || - tcp_conn->tc_flags & TCF_FIN_SENT || - tcp_sel_write(tcp_conn)) - { - resops |= SR_SELECT_WRITE; - } - else if (!(operations & SR_SELECT_POLL)) - tcp_fd->tf_flags |= TFF_SEL_WRITE; - } - if (operations & SR_SELECT_EXCEPTION) - { - /* Should add code for exceptions */ - } - return resops; -} - -static acc_t *tcp_get_data (port, offset, count, for_ioctl) -int port; -size_t offset; -size_t count; -int for_ioctl; -{ - tcp_port_t *tcp_port; - int result; - - tcp_port= &tcp_port_table[port]; - - switch (tcp_port->tp_state) - { - case TPS_SETPROTO: - if (!count) - { - result= (int)offset; - if (result<0) - { - tcp_port->tp_state= TPS_ERROR; - break; - } - tcp_port->tp_state= TPS_GETCONF; - if (tcp_port->tp_flags & TPF_SUSPEND) - tcp_main(tcp_port); - return NW_OK; - } -assert (!offset); -assert (count == sizeof(struct nwio_ipopt)); - { - struct nwio_ipopt *ipopt; - acc_t *acc; - - acc= bf_memreq(sizeof(*ipopt)); - ipopt= (struct nwio_ipopt *)ptr2acc_data(acc); - ipopt->nwio_flags= NWIO_COPY | - NWIO_EN_LOC | NWIO_DI_BROAD | - NWIO_REMANY | NWIO_PROTOSPEC | - NWIO_HDR_O_ANY | NWIO_RWDATALL; - ipopt->nwio_proto= IPPROTO_TCP; - return acc; - } - case TPS_MAIN: - assert(tcp_port->tp_flags & TPF_WRITE_IP); - if (!count) - { - result= (int)offset; - if (result<0) - { - if (result == EHOSTUNREACH || - result == ENETUNREACH || - result == ENETDOWN) - { - if (tcp_port->tp_snd_head) - { - tcp_notreach(tcp_port-> - tp_snd_head, result); - } - } - else - { - ip_warning(( - "ip_write failed with error: %d\n", - result )); - } - } - assert (tcp_port->tp_pack); - bf_afree (tcp_port->tp_pack); - tcp_port->tp_pack= 0; - - if (tcp_port->tp_flags & TPF_WRITE_SP) - { - tcp_port->tp_flags &= ~(TPF_WRITE_SP| - TPF_WRITE_IP); - if (tcp_port->tp_snd_head) - tcp_port_write(tcp_port); - } - else - tcp_port->tp_flags &= ~TPF_WRITE_IP; - } - else - { - return bf_cut (tcp_port->tp_pack, offset, - count); - } - break; - default: - printf("tcp_get_data(%d, 0x%x, 0x%x) called but tp_state= 0x%x\n", - port, offset, count, tcp_port->tp_state); - break; - } - return NW_OK; -} - -static int tcp_put_data (fd, offset, data, for_ioctl) -int fd; -size_t offset; -acc_t *data; -int for_ioctl; -{ - tcp_port_t *tcp_port; - int result; - - tcp_port= &tcp_port_table[fd]; - - switch (tcp_port->tp_state) - { - case TPS_GETCONF: - if (!data) - { - result= (int)offset; - if (result<0) - { - tcp_port->tp_state= TPS_ERROR; - return NW_OK; - } - tcp_port->tp_state= TPS_MAIN; - if (tcp_port->tp_flags & TPF_SUSPEND) - tcp_main(tcp_port); - } - else - { - struct nwio_ipconf *ipconf; - - data= bf_packIffLess(data, sizeof(*ipconf)); - ipconf= (struct nwio_ipconf *)ptr2acc_data(data); -assert (ipconf->nwic_flags & NWIC_IPADDR_SET); - tcp_port->tp_ipaddr= ipconf->nwic_ipaddr; - tcp_port->tp_subnetmask= ipconf->nwic_netmask; - tcp_port->tp_mtu= ipconf->nwic_mtu; - bf_afree(data); - } - break; - case TPS_MAIN: - assert(tcp_port->tp_flags & TPF_READ_IP); - if (!data) - { - result= (int)offset; - if (result<0) - ip_panic(( "ip_read() failed" )); - - if (tcp_port->tp_flags & TPF_READ_SP) - { - tcp_port->tp_flags &= ~(TPF_READ_SP| - TPF_READ_IP); - read_ip_packets(tcp_port); - } - else - tcp_port->tp_flags &= ~TPF_READ_IP; - } - else - { - assert(!offset); - /* this is an invalid assertion but ip sends - * only whole datagrams up */ - tcp_put_pkt(fd, data, bf_bufsize(data)); - } - break; - default: - printf( - "tcp_put_data(%d, 0x%x, %p) called but tp_state= 0x%x\n", - fd, offset, data, tcp_port->tp_state); - break; - } - return NW_OK; -} - -/* -tcp_put_pkt -*/ - -static void tcp_put_pkt(fd, data, datalen) -int fd; -acc_t *data; -size_t datalen; -{ - tcp_port_t *tcp_port; - tcp_conn_t *tcp_conn, **conn_p; - ip_hdr_t *ip_hdr; - tcp_hdr_t *tcp_hdr; - acc_t *ip_pack, *tcp_pack; - size_t ip_datalen, tcp_datalen, ip_hdr_len, tcp_hdr_len; - u16_t sum, mtu; - u32_t bits; - int i, hash; - ipaddr_t srcaddr, dstaddr, ipaddr, mask; - tcpport_t srcport, dstport; - - tcp_port= &tcp_port_table[fd]; - - /* Extract the IP header. */ - ip_hdr= (ip_hdr_t *)ptr2acc_data(data); - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - ip_datalen= datalen - ip_hdr_len; - if (ip_datalen == 0) - { - if (ip_hdr->ih_proto == 0) - { - /* IP layer reports new IP address */ - ipaddr= ip_hdr->ih_src; - mask= ip_hdr->ih_dst; - mtu= ntohs(ip_hdr->ih_length); - tcp_port->tp_ipaddr= ipaddr; - tcp_port->tp_subnetmask= mask; - tcp_port->tp_mtu= mtu; - DBLOCK(1, printf("tcp_put_pkt: using address "); - writeIpAddr(ipaddr); - printf(", netmask "); - writeIpAddr(mask); - printf(", mtu %u\n", mtu)); - for (i= 0, tcp_conn= tcp_conn_table+i; - itc_flags & TCF_INUSE)) - continue; - if (tcp_conn->tc_port != tcp_port) - continue; - tcp_conn->tc_locaddr= ipaddr; - } - } - else - DBLOCK(1, printf("tcp_put_pkt: no TCP header\n")); - bf_afree(data); - return; - } - data->acc_linkC++; - ip_pack= data; - ip_pack= bf_align(ip_pack, ip_hdr_len, 4); - ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_pack); - data= bf_delhead(data, ip_hdr_len); - - /* Compute the checksum */ - sum= tcp_pack_oneCsum(ip_hdr, data); - - /* Extract the TCP header */ - if (ip_datalen < TCP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("truncated TCP header\n")); - bf_afree(ip_pack); - bf_afree(data); - return; - } - data= bf_packIffLess(data, TCP_MIN_HDR_SIZE); - tcp_hdr= (tcp_hdr_t *)ptr2acc_data(data); - tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2; - /* actualy (>> 4) << 2 */ - if (ip_datalen < tcp_hdr_len || tcp_hdr_len < TCP_MIN_HDR_SIZE) - { - if (tcp_hdr_len < TCP_MIN_HDR_SIZE) - { - DBLOCK(1, printf("strange tcp header length %d\n", - tcp_hdr_len)); - } - else - { - DBLOCK(1, printf("truncated TCP header\n")); - } - bf_afree(ip_pack); - bf_afree(data); - return; - } - data->acc_linkC++; - tcp_pack= data; - tcp_pack= bf_align(tcp_pack, tcp_hdr_len, 4); - tcp_hdr= (tcp_hdr_t *)ptr2acc_data(tcp_pack); - if (ip_datalen == tcp_hdr_len) - { - bf_afree(data); - data= NULL; - } - else - data= bf_delhead(data, tcp_hdr_len); - tcp_datalen= ip_datalen-tcp_hdr_len; - - if ((u16_t)~sum) - { - DBLOCK(1, printf("checksum error in tcp packet\n"); - printf("tcp_pack_oneCsum(...)= 0x%x length= %d\n", - (u16_t)~sum, tcp_datalen); - printf("src ip_addr= "); writeIpAddr(ip_hdr->ih_src); - printf("\n")); - bf_afree(ip_pack); - bf_afree(tcp_pack); - bf_afree(data); - return; - } - - srcaddr= ip_hdr->ih_src; - dstaddr= ip_hdr->ih_dst; - srcport= tcp_hdr->th_srcport; - dstport= tcp_hdr->th_dstport; - bits= srcaddr ^ dstaddr ^ srcport ^ dstport; - bits= (bits >> 16) ^ bits; - bits= (bits >> 8) ^ bits; - hash= ((bits >> TCP_CONN_HASH_SHIFT) ^ bits) & (TCP_CONN_HASH_NR-1); - conn_p= tcp_port->tp_conn_hash[hash]; - if (conn_p[0]->tc_locport == dstport && - conn_p[0]->tc_remport == srcport && - conn_p[0]->tc_remaddr == srcaddr && - conn_p[0]->tc_locaddr == dstaddr) - { - tcp_conn= conn_p[0]; - } - else if (conn_p[1]->tc_locport == dstport && - conn_p[1]->tc_remport == srcport && - conn_p[1]->tc_remaddr == srcaddr && - conn_p[1]->tc_locaddr == dstaddr) - { - tcp_conn= conn_p[1]; - conn_p[1]= conn_p[0]; - conn_p[0]= tcp_conn; - } - else if (conn_p[2]->tc_locport == dstport && - conn_p[2]->tc_remport == srcport && - conn_p[2]->tc_remaddr == srcaddr && - conn_p[2]->tc_locaddr == dstaddr) - { - tcp_conn= conn_p[2]; - conn_p[2]= conn_p[1]; - conn_p[1]= conn_p[0]; - conn_p[0]= tcp_conn; - } - else if (conn_p[3]->tc_locport == dstport && - conn_p[3]->tc_remport == srcport && - conn_p[3]->tc_remaddr == srcaddr && - conn_p[3]->tc_locaddr == dstaddr) - { - tcp_conn= conn_p[3]; - conn_p[3]= conn_p[2]; - conn_p[2]= conn_p[1]; - conn_p[1]= conn_p[0]; - conn_p[0]= tcp_conn; - } - else - tcp_conn= NULL; - if ((tcp_conn != NULL && tcp_conn->tc_state == TCS_CLOSED) || - (tcp_hdr->th_flags & THF_SYN)) - { - tcp_conn= NULL; - } - - if (tcp_conn == NULL) - { - tcp_conn= find_best_conn(ip_hdr, tcp_hdr); - if (!tcp_conn) - { - /* listen backlog hack */ - bf_afree(ip_pack); - bf_afree(tcp_pack); - bf_afree(data); - return; - } - if (tcp_conn->tc_state != TCS_CLOSED) - { - conn_p[3]= conn_p[2]; - conn_p[2]= conn_p[1]; - conn_p[1]= conn_p[0]; - conn_p[0]= tcp_conn; - } - } - assert(tcp_conn->tc_busy == 0); - tcp_conn->tc_busy++; - tcp_frag2conn(tcp_conn, ip_hdr, tcp_hdr, data, tcp_datalen); - tcp_conn->tc_busy--; - bf_afree(ip_pack); - bf_afree(tcp_pack); -} - - -int tcp_open (port, srfd, get_userdata, put_userdata, put_pkt, - select_res) -int port; -int srfd; -get_userdata_t get_userdata; -put_userdata_t put_userdata; -put_pkt_t put_pkt; -select_res_t select_res; -{ - int i, j; - - tcp_fd_t *tcp_fd; - - for (i=0; i=TCP_FD_NR) - { - return EAGAIN; - } - - tcp_fd= &tcp_fd_table[i]; - - tcp_fd->tf_flags= TFF_INUSE; - tcp_fd->tf_flags |= TFF_PUSH_DATA; - - tcp_fd->tf_port= &tcp_port_table[port]; - tcp_fd->tf_srfd= srfd; - tcp_fd->tf_tcpconf.nwtc_flags= TCP_DEF_CONF; - tcp_fd->tf_tcpconf.nwtc_remaddr= 0; - tcp_fd->tf_tcpconf.nwtc_remport= 0; - tcp_fd->tf_tcpopt.nwto_flags= TCP_DEF_OPT; - tcp_fd->tf_get_userdata= get_userdata; - tcp_fd->tf_put_userdata= put_userdata; - tcp_fd->tf_select_res= select_res; - tcp_fd->tf_conn= 0; - tcp_fd->tf_error= 0; - for (j= 0; jtf_listenq[j]= NULL; - return i; -} - -/* -tcp_ioctl -*/ -int tcp_ioctl (fd, req) -int fd; -ioreq_t req; -{ - tcp_fd_t *tcp_fd; - tcp_port_t *tcp_port; - tcp_conn_t *tcp_conn; - nwio_tcpconf_t *io_tcp_conf; - nwio_tcpopt_t *tcp_opt; - tcp_cookie_t *cookiep; - acc_t *acc, *conf_acc, *opt_acc; - int result, *bytesp; - u8_t rndbits[RAND256_BUFSIZE]; - - tcp_fd= &tcp_fd_table[fd]; - - assert (tcp_fd->tf_flags & TFF_INUSE); - - tcp_port= tcp_fd->tf_port; - tcp_fd->tf_flags |= TFF_IOCTL_IP; - tcp_fd->tf_ioreq= req; - - if (tcp_port->tp_state != TPS_MAIN) - { - tcp_fd->tf_flags |= TFF_IOC_INIT_SP; - return NW_SUSPEND; - } - - switch (req) - { - case NWIOSTCPCONF: - if ((tcp_fd->tf_flags & TFF_CONNECTED) || - (tcp_fd->tf_flags & TFF_CONNECTING) || - (tcp_fd->tf_flags & TFF_LISTENQ)) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, EISCONN, TRUE); - result= NW_OK; - break; - } - result= tcp_setconf(tcp_fd); - break; - case NWIOGTCPCONF: - conf_acc= bf_memreq(sizeof(*io_tcp_conf)); -assert (conf_acc->acc_length == sizeof(*io_tcp_conf)); - io_tcp_conf= (nwio_tcpconf_t *)ptr2acc_data(conf_acc); - - *io_tcp_conf= tcp_fd->tf_tcpconf; - if (tcp_fd->tf_flags & TFF_CONNECTED) - { - tcp_conn= tcp_fd->tf_conn; - io_tcp_conf->nwtc_locport= tcp_conn->tc_locport; - io_tcp_conf->nwtc_remaddr= tcp_conn->tc_remaddr; - io_tcp_conf->nwtc_remport= tcp_conn->tc_remport; - } - io_tcp_conf->nwtc_locaddr= tcp_fd->tf_port->tp_ipaddr; - result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd, - 0, conf_acc, TRUE); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_put(tcp_fd, result, TRUE); - result= NW_OK; - break; - case NWIOSTCPOPT: - result= tcp_setopt(tcp_fd); - break; - case NWIOGTCPOPT: - opt_acc= bf_memreq(sizeof(*tcp_opt)); - assert (opt_acc->acc_length == sizeof(*tcp_opt)); - tcp_opt= (nwio_tcpopt_t *)ptr2acc_data(opt_acc); - - *tcp_opt= tcp_fd->tf_tcpopt; - result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd, - 0, opt_acc, TRUE); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_put(tcp_fd, result, TRUE); - result= NW_OK; - break; - case NWIOTCPCONN: - if (tcp_fd->tf_flags & TFF_CONNECTING) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, EALREADY, TRUE); - result= NW_OK; - break; - } - if (tcp_fd->tf_flags & TFF_CONNECTED) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, EISCONN, TRUE); - result= NW_OK; - break; - } - result= tcp_connect(tcp_fd); - if (result == NW_OK) - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - break; - case NWIOTCPLISTEN: - case NWIOTCPLISTENQ: - if ((tcp_fd->tf_flags & TFF_CONNECTED) || - (tcp_fd->tf_flags & TFF_LISTENQ) || - (tcp_fd->tf_flags & TFF_CONNECTING)) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, EISCONN, TRUE); - result= NW_OK; - break; - } - result= tcp_listen(tcp_fd, (req == NWIOTCPLISTENQ)); - break; - case NWIOTCPSHUTDOWN: - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, ENOTCONN, TRUE); - result= NW_OK; - break; - } - tcp_fd->tf_flags |= TFF_IOCTL_IP; - tcp_fd->tf_ioreq= req; - tcp_conn= tcp_fd->tf_conn; - - tcp_conn->tc_busy++; - tcp_fd_write(tcp_conn); - tcp_conn->tc_busy--; - tcp_conn_write(tcp_conn, 0); - if (!(tcp_fd->tf_flags & TFF_IOCTL_IP)) - result= NW_OK; - else - result= NW_SUSPEND; - break; - case NWIOTCPPUSH: - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, ENOTCONN, TRUE); - result= NW_OK; - break; - } - tcp_conn= tcp_fd->tf_conn; - tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT; - tcp_conn->tc_flags &= ~TCF_NO_PUSH; - tcp_conn->tc_flags |= TCF_PUSH_NOW; - - /* Start the timer (if necessary) */ - if (tcp_conn->tc_SND_TRM == tcp_conn->tc_SND_UNA) - tcp_set_send_timer(tcp_conn); - - tcp_conn_write(tcp_conn, 0); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, NW_OK, TRUE); - result= NW_OK; - break; - case NWIOGTCPCOOKIE: - if (!(tcp_fd->tf_flags & TFF_COOKIE)) - { - tcp_fd->tf_cookie.tc_ref= fd; - rand256(rndbits); - assert(sizeof(tcp_fd->tf_cookie.tc_secret) <= - RAND256_BUFSIZE); - memcpy(tcp_fd->tf_cookie.tc_secret, - rndbits, sizeof(tcp_fd->tf_cookie.tc_secret)); - tcp_fd->tf_flags |= TFF_COOKIE; - } - acc= bf_memreq(sizeof(*cookiep)); - cookiep= (tcp_cookie_t *)ptr2acc_data(acc); - - *cookiep= tcp_fd->tf_cookie; - result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd, - 0, acc, TRUE); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_put(tcp_fd, result, TRUE); - result= NW_OK; - break; - case NWIOTCPACCEPTTO: - result= tcp_acceptto(tcp_fd); - break; - case FIONREAD: - acc= bf_memreq(sizeof(*bytesp)); - bytesp= (int *)ptr2acc_data(acc); - tcp_bytesavailable(tcp_fd, bytesp); - result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd, - 0, acc, TRUE); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_put(tcp_fd, result, TRUE); - result= NW_OK; - break; - - case NWIOTCPGERROR: - acc= bf_memreq(sizeof(*bytesp)); - bytesp= (int *)ptr2acc_data(acc); - *bytesp= -tcp_fd->tf_error; /* Errors are positive in - * user space. - */ - tcp_fd->tf_error= 0; - result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd, - 0, acc, TRUE); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_put(tcp_fd, result, TRUE); - result= NW_OK; - break; - - default: - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, ENOTTY, TRUE); - result= NW_OK; - break; - } - return result; -} - - -/* -tcp_setconf -*/ - -static int tcp_setconf(tcp_fd) -tcp_fd_t *tcp_fd; -{ - nwio_tcpconf_t *tcpconf; - nwio_tcpconf_t oldconf, newconf; - acc_t *data; - tcp_fd_t *fd_ptr; - unsigned int new_en_flags, new_di_flags, - old_en_flags, old_di_flags, all_flags, flags; - int i; - - data= (*tcp_fd->tf_get_userdata) - (tcp_fd->tf_srfd, 0, - sizeof(nwio_tcpconf_t), TRUE); - - if (!data) - return EFAULT; - - data= bf_packIffLess(data, sizeof(nwio_tcpconf_t)); -assert (data->acc_length == sizeof(nwio_tcpconf_t)); - - tcpconf= (nwio_tcpconf_t *)ptr2acc_data(data); - oldconf= tcp_fd->tf_tcpconf; - newconf= *tcpconf; - - old_en_flags= oldconf.nwtc_flags & 0xffff; - old_di_flags= (oldconf.nwtc_flags >> 16) & - 0xffff; - new_en_flags= newconf.nwtc_flags & 0xffff; - new_di_flags= (newconf.nwtc_flags >> 16) & - 0xffff; - if (new_en_flags & new_di_flags) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - bf_afree(data); - return NW_OK; - } - - /* NWTC_ACC_MASK */ - if (new_di_flags & NWTC_ACC_MASK) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - bf_afree(data); - return NW_OK; - /* access modes can't be disabled */ - } - - if (!(new_en_flags & NWTC_ACC_MASK)) - new_en_flags |= (old_en_flags & NWTC_ACC_MASK); - - /* NWTC_LOCPORT_MASK */ - if (new_di_flags & NWTC_LOCPORT_MASK) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - bf_afree(data); - return NW_OK; - /* the loc ports can't be disabled */ - } - if (!(new_en_flags & NWTC_LOCPORT_MASK)) - { - new_en_flags |= (old_en_flags & - NWTC_LOCPORT_MASK); - newconf.nwtc_locport= oldconf.nwtc_locport; - } - else if ((new_en_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SEL) - { - newconf.nwtc_locport= find_unused_port(tcp_fd- - tcp_fd_table); - } - else if ((new_en_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SET) - { - if (!newconf.nwtc_locport) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - bf_afree(data); - return NW_OK; - } - } - - /* NWTC_REMADDR_MASK */ - if (!((new_en_flags | new_di_flags) & - NWTC_REMADDR_MASK)) - { - new_en_flags |= (old_en_flags & - NWTC_REMADDR_MASK); - new_di_flags |= (old_di_flags & - NWTC_REMADDR_MASK); - newconf.nwtc_remaddr= oldconf.nwtc_remaddr; - } - else if (new_en_flags & NWTC_SET_RA) - { - if (!newconf.nwtc_remaddr) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - bf_afree(data); - return NW_OK; - } - } - else - { -assert (new_di_flags & NWTC_REMADDR_MASK); - newconf.nwtc_remaddr= 0; - } - - /* NWTC_REMPORT_MASK */ - if (!((new_en_flags | new_di_flags) & NWTC_REMPORT_MASK)) - { - new_en_flags |= (old_en_flags & - NWTC_REMPORT_MASK); - new_di_flags |= (old_di_flags & - NWTC_REMPORT_MASK); - newconf.nwtc_remport= - oldconf.nwtc_remport; - } - else if (new_en_flags & NWTC_SET_RP) - { - if (!newconf.nwtc_remport) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - bf_afree(data); - return NW_OK; - } - } - else - { -assert (new_di_flags & NWTC_REMPORT_MASK); - newconf.nwtc_remport= 0; - } - - newconf.nwtc_flags= ((unsigned long)new_di_flags - << 16) | new_en_flags; - all_flags= new_en_flags | new_di_flags; - - /* check the access modes */ - if ((all_flags & NWTC_LOCPORT_MASK) != NWTC_LP_UNSET) - { - for (i=0, fd_ptr= tcp_fd_table; itf_flags & TFF_INUSE)) - continue; - if (fd_ptr->tf_port != tcp_fd->tf_port) - continue; - flags= fd_ptr->tf_tcpconf.nwtc_flags; - if ((flags & NWTC_LOCPORT_MASK) == NWTC_LP_UNSET) - continue; - if (fd_ptr->tf_tcpconf.nwtc_locport != - newconf.nwtc_locport) - continue; - if ((flags & NWTC_ACC_MASK) != (all_flags & - NWTC_ACC_MASK) || - (all_flags & NWTC_ACC_MASK) == NWTC_EXCL) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EADDRINUSE, TRUE); - bf_afree(data); - return NW_OK; - } - } - } - - tcp_fd->tf_tcpconf= newconf; - - if ((all_flags & NWTC_ACC_MASK) && - ((all_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SET || - (all_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SEL) && - (all_flags & NWTC_REMADDR_MASK) && - (all_flags & NWTC_REMPORT_MASK)) - tcp_fd->tf_flags |= TFF_CONF_SET; - else - { - tcp_fd->tf_flags &= ~TFF_CONF_SET; - } - bf_afree(data); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, NW_OK, TRUE); - return NW_OK; -} - - -/* -tcp_setopt -*/ - -static int tcp_setopt(tcp_fd) -tcp_fd_t *tcp_fd; -{ - nwio_tcpopt_t *tcpopt; - nwio_tcpopt_t oldopt, newopt; - acc_t *data; - unsigned int new_en_flags, new_di_flags, - old_en_flags, old_di_flags; - - data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0, - sizeof(nwio_tcpopt_t), TRUE); - - if (!data) - return EFAULT; - - data= bf_packIffLess(data, sizeof(nwio_tcpopt_t)); -assert (data->acc_length == sizeof(nwio_tcpopt_t)); - - tcpopt= (nwio_tcpopt_t *)ptr2acc_data(data); - oldopt= tcp_fd->tf_tcpopt; - newopt= *tcpopt; - - old_en_flags= oldopt.nwto_flags & 0xffff; - old_di_flags= (oldopt.nwto_flags >> 16) & 0xffff; - new_en_flags= newopt.nwto_flags & 0xffff; - new_di_flags= (newopt.nwto_flags >> 16) & 0xffff; - if (new_en_flags & new_di_flags) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - return NW_OK; - } - - /* NWTO_SND_URG_MASK */ - if (!((new_en_flags | new_di_flags) & NWTO_SND_URG_MASK)) - { - new_en_flags |= (old_en_flags & NWTO_SND_URG_MASK); - new_di_flags |= (old_di_flags & NWTO_SND_URG_MASK); - } - - /* NWTO_RCV_URG_MASK */ - if (!((new_en_flags | new_di_flags) & NWTO_RCV_URG_MASK)) - { - new_en_flags |= (old_en_flags & NWTO_RCV_URG_MASK); - new_di_flags |= (old_di_flags & NWTO_RCV_URG_MASK); - } - - /* NWTO_BSD_URG_MASK */ - if (!((new_en_flags | new_di_flags) & NWTO_BSD_URG_MASK)) - { - new_en_flags |= (old_en_flags & NWTO_BSD_URG_MASK); - new_di_flags |= (old_di_flags & NWTO_BSD_URG_MASK); - } - else - { - if (tcp_fd->tf_conn == NULL) - { - bf_afree(data); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EINVAL, TRUE); - return NW_OK; - } - } - - /* NWTO_DEL_RST_MASK */ - if (!((new_en_flags | new_di_flags) & NWTO_DEL_RST_MASK)) - { - new_en_flags |= (old_en_flags & NWTO_DEL_RST_MASK); - new_di_flags |= (old_di_flags & NWTO_DEL_RST_MASK); - } - - /* NWTO_BULK_MASK */ - if (!((new_en_flags | new_di_flags) & NWTO_BULK_MASK)) - { - new_en_flags |= (old_en_flags & NWTO_BULK_MASK); - new_di_flags |= (old_di_flags & NWTO_BULK_MASK); - } - - newopt.nwto_flags= ((unsigned long)new_di_flags << 16) | - new_en_flags; - tcp_fd->tf_tcpopt= newopt; - if (newopt.nwto_flags & NWTO_SND_URG) - tcp_fd->tf_flags |= TFF_WR_URG; - else - tcp_fd->tf_flags &= ~TFF_WR_URG; - - if (newopt.nwto_flags & NWTO_RCV_URG) - tcp_fd->tf_flags |= TFF_RECV_URG; - else - tcp_fd->tf_flags &= ~TFF_RECV_URG; - - if (tcp_fd->tf_conn) - { - if (newopt.nwto_flags & NWTO_BSD_URG) - tcp_fd->tf_conn->tc_flags |= TCF_BSD_URG; - else - tcp_fd->tf_conn->tc_flags &= ~TCF_BSD_URG; - } - - if (newopt.nwto_flags & NWTO_DEL_RST) - tcp_fd->tf_flags |= TFF_DEL_RST; - else - tcp_fd->tf_flags &= ~TFF_DEL_RST; - - if (newopt.nwto_flags & NWTO_BULK) - tcp_fd->tf_flags &= ~TFF_PUSH_DATA; - else - tcp_fd->tf_flags |= TFF_PUSH_DATA; - - bf_afree(data); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, NW_OK, TRUE); - return NW_OK; -} - - -static tcpport_t find_unused_port(int fd) -{ - tcpport_t port, nw_port; - - for (port= 0x8000+fd; port < 0xffff-TCP_FD_NR; port+= TCP_FD_NR) - { - nw_port= htons(port); - if (is_unused_port(nw_port)) - return nw_port; - } - for (port= 0x8000; port < 0xffff; port++) - { - nw_port= htons(port); - if (is_unused_port(nw_port)) - return nw_port; - } - ip_panic(( "unable to find unused port (shouldn't occur)" )); - return 0; -} - -static int is_unused_port(tcpport_t port) -{ - int i; - tcp_fd_t *tcp_fd; - tcp_conn_t *tcp_conn; - - for (i= 0, tcp_fd= tcp_fd_table; itf_flags & TFF_CONF_SET)) - continue; - if (tcp_fd->tf_tcpconf.nwtc_locport == port) - return FALSE; - } - for (i= tcp_conf_nr, tcp_conn= tcp_conn_table+i; - itc_flags & TCF_INUSE)) - continue; - if (tcp_conn->tc_locport == port) - return FALSE; - } - return TRUE; -} - -static int reply_thr_put(tcp_fd, reply, for_ioctl) -tcp_fd_t *tcp_fd; -int reply; -int for_ioctl; -{ - assert (tcp_fd); - - return (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd, reply, - (acc_t *)0, for_ioctl); -} - -static void reply_thr_get(tcp_fd, reply, for_ioctl) -tcp_fd_t *tcp_fd; -int reply; -int for_ioctl; -{ - acc_t *result; - - result= (*tcp_fd->tf_get_userdata)(tcp_fd->tf_srfd, reply, - (size_t)0, for_ioctl); - assert (!result); -} - -int tcp_su4listen(tcp_fd, tcp_conn, do_listenq) -tcp_fd_t *tcp_fd; -tcp_conn_t *tcp_conn; -int do_listenq; -{ - tcp_conn->tc_locport= tcp_fd->tf_tcpconf.nwtc_locport; - tcp_conn->tc_locaddr= tcp_fd->tf_port->tp_ipaddr; - if (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RP) - tcp_conn->tc_remport= tcp_fd->tf_tcpconf.nwtc_remport; - else - tcp_conn->tc_remport= 0; - if (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RA) - tcp_conn->tc_remaddr= tcp_fd->tf_tcpconf.nwtc_remaddr; - else - tcp_conn->tc_remaddr= 0; - - tcp_setup_conn(tcp_fd->tf_port, tcp_conn); - tcp_conn->tc_fd= tcp_fd; - tcp_conn->tc_connInprogress= 1; - tcp_conn->tc_orglisten= TRUE; - tcp_conn->tc_state= TCS_LISTEN; - tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_LISTEN; - if (do_listenq) - { - tcp_fd->tf_flags |= TFF_LISTENQ; - tcp_reply_ioctl(tcp_fd, NW_OK); - return NW_OK; - } - return NW_SUSPEND; -} - -/* -find_empty_conn - -This function returns a connection that is not inuse. -This includes connections that are never used, and connections without a -user that are not used for a while. -*/ - -static tcp_conn_t *find_empty_conn() -{ - int i; - tcp_conn_t *tcp_conn; - - for (i=tcp_conf_nr, tcp_conn= tcp_conn_table+i; - itc_flags == TCF_EMPTY) - { - tcp_conn->tc_connInprogress= 0; - tcp_conn->tc_fd= NULL; - return tcp_conn; - } - if (tcp_conn->tc_fd) - continue; - if (tcp_conn->tc_senddis > get_time()) - continue; - if (tcp_conn->tc_state != TCS_CLOSED) - { - tcp_close_connection (tcp_conn, ENOCONN); - } - tcp_conn->tc_flags= 0; - return tcp_conn; - } - return NULL; -} - - -/* -find_conn_entry - -This function return a connection matching locport, locaddr, remport, remaddr. -If no such connection exists NULL is returned. -If a connection exists without mainuser it is closed. -*/ - -static tcp_conn_t *find_conn_entry( - tcpport_t locport, - ipaddr_t locaddr, - tcpport_t remport, - ipaddr_t remaddr -) -{ - tcp_conn_t *tcp_conn; - int i, state; - - assert(remport); - assert(remaddr); - for (i=tcp_conf_nr, tcp_conn= tcp_conn_table+i; itc_flags == TCF_EMPTY) - continue; - if (tcp_conn->tc_locport != locport || - tcp_conn->tc_locaddr != locaddr || - tcp_conn->tc_remport != remport || - tcp_conn->tc_remaddr != remaddr) - continue; - if (tcp_conn->tc_fd) - return tcp_conn; - state= tcp_conn->tc_state; - if (state != TCS_CLOSED) - { - tcp_close_connection(tcp_conn, ENOCONN); - } - return tcp_conn; - } - return NULL; -} - -static void read_ip_packets(tcp_port) -tcp_port_t *tcp_port; -{ - int result; - - do - { - tcp_port->tp_flags |= TPF_READ_IP; - result= ip_read(tcp_port->tp_ipfd, TCP_MAX_DATAGRAM); - if (result == NW_SUSPEND) - { - tcp_port->tp_flags |= TPF_READ_SP; - return; - } - assert(result == NW_OK); - tcp_port->tp_flags &= ~TPF_READ_IP; - } while(!(tcp_port->tp_flags & TPF_READ_IP)); -} - -/* -find_best_conn -*/ - -static tcp_conn_t *find_best_conn(ip_hdr, tcp_hdr) -ip_hdr_t *ip_hdr; -tcp_hdr_t *tcp_hdr; -{ - - int best_level, new_level; - tcp_conn_t *best_conn, *listen_conn, *tcp_conn; - tcp_fd_t *tcp_fd; - int i; - ipaddr_t locaddr; - ipaddr_t remaddr; - tcpport_t locport; - tcpport_t remport; - - locaddr= ip_hdr->ih_dst; - remaddr= ip_hdr->ih_src; - locport= tcp_hdr->th_dstport; - remport= tcp_hdr->th_srcport; - if (!remport) /* This can interfere with a listen, so we reject it - * by clearing the requested port - */ - locport= 0; - - best_level= 0; - best_conn= NULL; - listen_conn= NULL; - for (i= tcp_conf_nr, tcp_conn= tcp_conn_table+i; - itc_flags & TCF_INUSE)) - continue; - /* First fast check for open connections. */ - if (tcp_conn->tc_locaddr == locaddr && - tcp_conn->tc_locport == locport && - tcp_conn->tc_remport == remport && - tcp_conn->tc_remaddr == remaddr && - tcp_conn->tc_fd) - { - return tcp_conn; - } - - /* Now check for listens and abandoned connections. */ - if (tcp_conn->tc_locaddr != locaddr) - { - continue; - } - new_level= 0; - if (tcp_conn->tc_locport) - { - if (tcp_conn->tc_locport != locport) - { - continue; - } - new_level += 4; - } - if (tcp_conn->tc_remport) - { - if (tcp_conn->tc_remport != remport) - { - continue; - } - new_level += 1; - } - if (tcp_conn->tc_remaddr) - { - if (tcp_conn->tc_remaddr != remaddr) - { - continue; - } - new_level += 2; - } - if (new_leveltc_state != TCS_LISTEN) - continue; - if (new_level == 7) - /* We found an abandoned connection */ - { - assert(!tcp_conn->tc_fd); - if (best_conn && tcp_Lmod4G(tcp_conn->tc_ISS, - best_conn->tc_ISS)) - { - continue; - } - best_conn= tcp_conn; - continue; - } - if (!(tcp_hdr->th_flags & THF_SYN)) - continue; - best_level= new_level; - listen_conn= tcp_conn; - assert(listen_conn->tc_fd != NULL); - } - - if (listen_conn && listen_conn->tc_fd->tf_flags & TFF_LISTENQ && - listen_conn->tc_fd->tf_conn == listen_conn) - { - /* Special processing for listen queues. Only accept the - * connection if there is empty space in the queue and - * there are empty connections as well. - */ - listen_conn= new_conn_for_queue(listen_conn->tc_fd); - - if (listen_conn) - return listen_conn; - } - - if (!best_conn && !listen_conn) - { - if ((tcp_hdr->th_flags & THF_SYN) && - maybe_listen(locaddr, locport, remaddr, remport)) - { - /* Quick hack to implement listen back logs: - * if a SYN arrives and there is no listen waiting - * for that packet, then no reply is sent. - */ - return NULL; - } - - for (i=0, tcp_conn= tcp_conn_table; itc_flags & TCF_INUSE) && - tcp_conn->tc_locaddr==locaddr) - { - break; - } - } - assert (tcp_conn); - assert (tcp_conn->tc_state == TCS_CLOSED); - - tcp_conn->tc_locport= locport; - tcp_conn->tc_locaddr= locaddr; - tcp_conn->tc_remport= remport; - tcp_conn->tc_remaddr= remaddr; - assert (!tcp_conn->tc_fd); - return tcp_conn; - } - - if (best_conn) - { - if (!listen_conn) - { - assert(!best_conn->tc_fd); - return best_conn; - } - - assert(listen_conn->tc_connInprogress); - tcp_fd= listen_conn->tc_fd; - assert(tcp_fd); - assert((tcp_fd->tf_flags & TFF_LISTENQ) || - tcp_fd->tf_conn == listen_conn); - - if (best_conn->tc_state != TCS_CLOSED) - tcp_close_connection(best_conn, ENOCONN); - - listen_conn->tc_ISS= best_conn->tc_ISS; - if (best_conn->tc_senddis > listen_conn->tc_senddis) - listen_conn->tc_senddis= best_conn->tc_senddis; - return listen_conn; - } - assert (listen_conn); - return listen_conn; -} - -/* -new_conn_for_queue -*/ -static tcp_conn_t *new_conn_for_queue(tcp_fd) -tcp_fd_t *tcp_fd; -{ - int i; - tcp_conn_t *tcp_conn; - - assert(tcp_fd->tf_flags & TFF_LISTENQ); - - for (i= 0; itf_listenq[i] == NULL) - break; - } - if (i >= TFL_LISTEN_MAX) - return NULL; - - tcp_conn= find_empty_conn(); - if (!tcp_conn) - return NULL; - tcp_fd->tf_listenq[i]= tcp_conn; - (void)tcp_su4listen(tcp_fd, tcp_conn, 0 /* !do_listenq */); - return tcp_conn; -} - -/* -maybe_listen -*/ -static int maybe_listen( - ipaddr_t locaddr, - tcpport_t locport, - ipaddr_t remaddr, - tcpport_t remport -) -{ - int i; - tcp_conn_t *tcp_conn; - tcp_fd_t *fd; - - for (i= tcp_conf_nr, tcp_conn= tcp_conn_table+i; - itc_flags & TCF_INUSE)) - continue; - - if (tcp_conn->tc_locaddr != locaddr) - { - continue; - } - if (tcp_conn->tc_locport != locport ) - { - continue; - } - if (!tcp_conn->tc_orglisten) - continue; - fd= tcp_conn->tc_fd; - if (!fd) - continue; - if ((fd->tf_tcpconf.nwtc_flags & NWTC_SET_RP) && - tcp_conn->tc_remport != remport) - { - continue; - } - if ((fd->tf_tcpconf.nwtc_flags & NWTC_SET_RA) && - tcp_conn->tc_remaddr != remaddr) - { - continue; - } - if (!(fd->tf_flags & TFF_DEL_RST)) - continue; - return 1; - - } - return 0; -} - - -void tcp_reply_ioctl(tcp_fd, reply) -tcp_fd_t *tcp_fd; -int reply; -{ - assert (tcp_fd->tf_flags & TFF_IOCTL_IP); - assert (tcp_fd->tf_ioreq == NWIOTCPSHUTDOWN || - tcp_fd->tf_ioreq == NWIOTCPLISTEN || - tcp_fd->tf_ioreq == NWIOTCPLISTENQ || - tcp_fd->tf_ioreq == NWIOTCPACCEPTTO || - tcp_fd->tf_ioreq == NWIOTCPCONN); - - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, reply, TRUE); -} - -void tcp_reply_write(tcp_fd, reply) -tcp_fd_t *tcp_fd; -size_t reply; -{ - assert (tcp_fd->tf_flags & TFF_WRITE_IP); - - tcp_fd->tf_flags &= ~TFF_WRITE_IP; - reply_thr_get (tcp_fd, reply, FALSE); -} - -void tcp_reply_read(tcp_fd, reply) -tcp_fd_t *tcp_fd; -size_t reply; -{ - assert (tcp_fd->tf_flags & TFF_READ_IP); - - tcp_fd->tf_flags &= ~TFF_READ_IP; - reply_thr_put (tcp_fd, reply, FALSE); -} - -int tcp_write(fd, count) -int fd; -size_t count; -{ - tcp_fd_t *tcp_fd; - tcp_conn_t *tcp_conn; - - tcp_fd= &tcp_fd_table[fd]; - - assert (tcp_fd->tf_flags & TFF_INUSE); - - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - { - reply_thr_get (tcp_fd, ENOTCONN, FALSE); - return NW_OK; - } - tcp_conn= tcp_fd->tf_conn; - if (tcp_conn->tc_state == TCS_CLOSED) - { - reply_thr_get(tcp_fd, tcp_conn->tc_error, FALSE); - return NW_OK; - } - if (tcp_conn->tc_flags & TCF_FIN_SENT) - { - reply_thr_get (tcp_fd, ESHUTDOWN, FALSE); - return NW_OK; - } - - tcp_fd->tf_flags |= TFF_WRITE_IP; - tcp_fd->tf_write_offset= 0; - tcp_fd->tf_write_count= count; - - /* New data may cause a segment to be sent. Clear PUSH_NOW - * from last NWIOTCPPUSH ioctl. - */ - tcp_conn->tc_flags &= ~(TCF_NO_PUSH|TCF_PUSH_NOW); - - /* Start the timer (if necessary) */ - if (tcp_conn->tc_SND_TRM == tcp_conn->tc_SND_UNA) - tcp_set_send_timer(tcp_conn); - - assert(tcp_conn->tc_busy == 0); - tcp_conn->tc_busy++; - tcp_fd_write(tcp_conn); - tcp_conn->tc_busy--; - tcp_conn_write(tcp_conn, 0); - - if (!(tcp_fd->tf_flags & TFF_WRITE_IP)) - return NW_OK; - else - return NW_SUSPEND; -} - -int -tcp_read(fd, count) -int fd; -size_t count; -{ - tcp_fd_t *tcp_fd; - tcp_conn_t *tcp_conn; - - tcp_fd= &tcp_fd_table[fd]; - - assert (tcp_fd->tf_flags & TFF_INUSE); - - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - { - reply_thr_put (tcp_fd, ENOTCONN, FALSE); - return NW_OK; - } - tcp_conn= tcp_fd->tf_conn; - - tcp_fd->tf_flags |= TFF_READ_IP; - tcp_fd->tf_read_offset= 0; - tcp_fd->tf_read_count= count; - - assert(tcp_conn->tc_busy == 0); - tcp_conn->tc_busy++; - tcp_fd_read(tcp_conn, 0); - tcp_conn->tc_busy--; - if (!(tcp_fd->tf_flags & TFF_READ_IP)) - return NW_OK; - else - return NW_SUSPEND; -} - -/* -tcp_restart_connect - -reply the success or failure of a connect to the user. -*/ - - -void tcp_restart_connect(tcp_conn) -tcp_conn_t *tcp_conn; -{ - tcp_fd_t *tcp_fd; - int reply; - - assert(tcp_conn->tc_connInprogress); - tcp_conn->tc_connInprogress= 0; - - tcp_fd= tcp_conn->tc_fd; - assert(tcp_fd); - if (tcp_fd->tf_flags & TFF_LISTENQ) - { - /* Special code for listen queues */ - assert(tcp_conn->tc_state != TCS_CLOSED); - - /* Reply for select */ - if ((tcp_fd->tf_flags & TFF_SEL_READ) && - tcp_fd->tf_select_res) - { - tcp_fd->tf_flags &= ~TFF_SEL_READ; - tcp_fd->tf_select_res(tcp_fd->tf_srfd, - SR_SELECT_READ); - } - - /* Reply for acceptto */ - if (tcp_fd->tf_flags & TFF_IOCTL_IP) - (void) tcp_acceptto(tcp_fd); - - return; - } - - if (tcp_conn->tc_state == TCS_CLOSED) - { - reply= tcp_conn->tc_error; - assert(tcp_conn->tc_fd == tcp_fd); - tcp_fd->tf_conn= NULL; - tcp_conn->tc_fd= NULL; - tcp_fd->tf_error= reply; - } - else - { - tcp_fd->tf_flags |= TFF_CONNECTED; - reply= NW_OK; - } - - if (tcp_fd->tf_flags & TFF_CONNECTING) - { - /* Special code for asynchronous connects */ - tcp_fd->tf_flags &= ~TFF_CONNECTING; - - /* Reply for select */ - if ((tcp_fd->tf_flags & TFF_SEL_WRITE) && - tcp_fd->tf_select_res) - { - tcp_fd->tf_flags &= ~TFF_SEL_WRITE; - tcp_fd->tf_select_res(tcp_fd->tf_srfd, - SR_SELECT_WRITE); - } - - return; - } - - assert(tcp_fd->tf_flags & TFF_IOCTL_IP); - assert(tcp_fd->tf_ioreq == NWIOTCPLISTEN || - tcp_fd->tf_ioreq == NWIOTCPCONN); - - tcp_reply_ioctl (tcp_fd, reply); -} - -/* -tcp_close -*/ - -void tcp_close(fd) -int fd; -{ - int i; - tcp_fd_t *tcp_fd; - tcp_conn_t *tcp_conn; - - tcp_fd= &tcp_fd_table[fd]; - - assert (tcp_fd->tf_flags & TFF_INUSE); - assert (!(tcp_fd->tf_flags & - (TFF_IOCTL_IP|TFF_READ_IP|TFF_WRITE_IP))); - - if (tcp_fd->tf_flags & TFF_LISTENQ) - { - /* Special code for listen queues */ - for (i= 0; itf_listenq[i]; - if (!tcp_conn) - continue; - - tcp_fd->tf_listenq[i]= NULL; - assert(tcp_conn->tc_fd == tcp_fd); - tcp_conn->tc_fd= NULL; - - if (tcp_conn->tc_connInprogress) - { - tcp_conn->tc_connInprogress= 0; - tcp_close_connection(tcp_conn, ENOCONN); - continue; - } - - tcp_shutdown (tcp_conn); - if (tcp_conn->tc_state == TCS_ESTABLISHED) - tcp_conn->tc_state= TCS_CLOSING; - - /* Set the retransmission timeout a bit smaller. */ - tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_CLOSING; - - /* If all data has been acknowledged, close the connection. */ - if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT) - tcp_close_connection(tcp_conn, ENOTCONN); - } - - tcp_conn= tcp_fd->tf_conn; - assert(tcp_conn->tc_fd == tcp_fd); - assert (tcp_conn->tc_connInprogress); - tcp_conn->tc_connInprogress= 0; - tcp_conn->tc_fd= NULL; - tcp_fd->tf_conn= NULL; - tcp_close_connection(tcp_conn, ENOCONN); - } - for (i= 0; itf_listenq[i] == NULL); - } - - if (tcp_fd->tf_flags & TFF_CONNECTING) - { - tcp_conn= tcp_fd->tf_conn; - assert(tcp_conn != NULL); - - assert (tcp_conn->tc_connInprogress); - tcp_conn->tc_connInprogress= 0; - tcp_conn->tc_fd= NULL; - tcp_fd->tf_conn= NULL; - tcp_close_connection(tcp_conn, ENOCONN); - - tcp_fd->tf_flags &= ~TFF_CONNECTING; - } - - tcp_fd->tf_flags &= ~TFF_INUSE; - if (!tcp_fd->tf_conn) - return; - - - tcp_conn= tcp_fd->tf_conn; - assert(tcp_conn->tc_fd == tcp_fd); - tcp_conn->tc_fd= NULL; - - assert (!tcp_conn->tc_connInprogress); - - tcp_shutdown (tcp_conn); - if (tcp_conn->tc_state == TCS_ESTABLISHED) - { - tcp_conn->tc_state= TCS_CLOSING; - } - - /* Set the retransmission timeout a bit smaller. */ - tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_CLOSING; - - /* If all data has been acknowledged, close the connection. */ - if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT) - tcp_close_connection(tcp_conn, ENOTCONN); -} - -int tcp_cancel(fd, which_operation) -int fd; -int which_operation; -{ - tcp_fd_t *tcp_fd; - tcp_conn_t *tcp_conn; - - tcp_fd= &tcp_fd_table[fd]; - - assert (tcp_fd->tf_flags & TFF_INUSE); - - tcp_conn= tcp_fd->tf_conn; - - switch (which_operation) - { - case SR_CANCEL_WRITE: - assert (tcp_fd->tf_flags & TFF_WRITE_IP); - tcp_fd->tf_flags &= ~TFF_WRITE_IP; - - if (tcp_fd->tf_write_offset) - reply_thr_get (tcp_fd, tcp_fd->tf_write_offset, FALSE); - else - reply_thr_get (tcp_fd, EINTR, FALSE); - break; - case SR_CANCEL_READ: - assert (tcp_fd->tf_flags & TFF_READ_IP); - tcp_fd->tf_flags &= ~TFF_READ_IP; - if (tcp_fd->tf_read_offset) - reply_thr_put (tcp_fd, tcp_fd->tf_read_offset, FALSE); - else - reply_thr_put (tcp_fd, EINTR, FALSE); - break; - case SR_CANCEL_IOCTL: -assert (tcp_fd->tf_flags & TFF_IOCTL_IP); - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - - if (tcp_fd->tf_flags & TFF_IOC_INIT_SP) - { - tcp_fd->tf_flags &= ~TFF_IOC_INIT_SP; - reply_thr_put (tcp_fd, EINTR, TRUE); - break; - } - - switch (tcp_fd->tf_ioreq) - { - case NWIOGTCPCONF: - reply_thr_put (tcp_fd, EINTR, TRUE); - break; - case NWIOSTCPCONF: - case NWIOTCPSHUTDOWN: - reply_thr_get (tcp_fd, EINTR, TRUE); - break; - case NWIOTCPCONN: - case NWIOTCPLISTEN: - assert (tcp_conn->tc_connInprogress); - tcp_conn->tc_connInprogress= 0; - tcp_conn->tc_fd= NULL; - tcp_fd->tf_conn= NULL; - tcp_close_connection(tcp_conn, ENOCONN); - reply_thr_get (tcp_fd, EINTR, TRUE); - break; - default: - ip_warning(( "unknown ioctl inprogress: 0x%x", - tcp_fd->tf_ioreq )); - reply_thr_get (tcp_fd, EINTR, TRUE); - break; - } - break; - default: - ip_panic(( "unknown cancel request" )); - break; - } - return NW_OK; -} - -/* -tcp_connect -*/ - -static int tcp_connect(tcp_fd) -tcp_fd_t *tcp_fd; -{ - tcp_conn_t *tcp_conn; - nwio_tcpcl_t *tcpcl; - long nwtcl_flags; - int r, do_asynch; - acc_t *data; - - if (!(tcp_fd->tf_flags & TFF_CONF_SET)) - { - tcp_reply_ioctl(tcp_fd, EBADMODE); - return NW_OK; - } - assert (!(tcp_fd->tf_flags & TFF_CONNECTED) && - !(tcp_fd->tf_flags & TFF_CONNECTING) && - !(tcp_fd->tf_flags & TFF_LISTENQ)); - if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP)) - != (NWTC_SET_RA|NWTC_SET_RP)) - { - tcp_reply_ioctl(tcp_fd, EBADMODE); - return NW_OK; - } - - data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0, - sizeof(*tcpcl), TRUE); - if (!data) - return EFAULT; - - data= bf_packIffLess(data, sizeof(*tcpcl)); - assert (data->acc_length == sizeof(*tcpcl)); - tcpcl= (nwio_tcpcl_t *)ptr2acc_data(data); - - nwtcl_flags= tcpcl->nwtcl_flags; - bf_afree(data); data= NULL; tcpcl= NULL; - - if (nwtcl_flags == TCF_ASYNCH) - do_asynch= 1; - else if (nwtcl_flags == TCF_DEFAULT) - do_asynch= 0; - else - { - tcp_reply_ioctl(tcp_fd, EINVAL); - return NW_OK; - } - - assert(!tcp_fd->tf_conn); - tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport, - tcp_fd->tf_port->tp_ipaddr, - tcp_fd->tf_tcpconf.nwtc_remport, - tcp_fd->tf_tcpconf.nwtc_remaddr); - if (tcp_conn) - { - if (tcp_conn->tc_fd) - { - tcp_reply_ioctl(tcp_fd, EADDRINUSE); - return NW_OK; - } - } - else - { - tcp_conn= find_empty_conn(); - if (!tcp_conn) - { - tcp_reply_ioctl(tcp_fd, EAGAIN); - return NW_OK; - } - } - tcp_fd->tf_conn= tcp_conn; - - r= tcp_su4connect(tcp_fd); - if (r == NW_SUSPEND && do_asynch) - { - tcp_fd->tf_flags |= TFF_CONNECTING; - tcp_reply_ioctl(tcp_fd, EINPROGRESS); - r= NW_OK; - } - return r; -} - -/* -tcp_su4connect -*/ - -static int tcp_su4connect(tcp_fd) -tcp_fd_t *tcp_fd; -{ - tcp_conn_t *tcp_conn; - - tcp_conn= tcp_fd->tf_conn; - - tcp_conn->tc_locport= tcp_fd->tf_tcpconf.nwtc_locport; - tcp_conn->tc_locaddr= tcp_fd->tf_port->tp_ipaddr; - - assert (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RP); - assert (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RA); - tcp_conn->tc_remport= tcp_fd->tf_tcpconf.nwtc_remport; - tcp_conn->tc_remaddr= tcp_fd->tf_tcpconf.nwtc_remaddr; - - tcp_setup_conn(tcp_fd->tf_port, tcp_conn); - - tcp_conn->tc_fd= tcp_fd; - tcp_conn->tc_connInprogress= 1; - tcp_conn->tc_orglisten= FALSE; - tcp_conn->tc_state= TCS_SYN_SENT; - tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_CONNECT; - - /* Start the timer (if necessary) */ - tcp_set_send_timer(tcp_conn); - - tcp_conn_write(tcp_conn, 0); - - if (tcp_conn->tc_connInprogress) - return NW_SUSPEND; - else - return NW_OK; -} - - -/* -tcp_listen -*/ - -static int tcp_listen(tcp_fd, do_listenq) -tcp_fd_t *tcp_fd; -int do_listenq; -{ - tcp_conn_t *tcp_conn; - - if (!(tcp_fd->tf_flags & TFF_CONF_SET)) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get(tcp_fd, EBADMODE, TRUE); - return NW_OK; - } - assert (!(tcp_fd->tf_flags & TFF_CONNECTED) && - !(tcp_fd->tf_flags & TFF_CONNECTING) && - !(tcp_fd->tf_flags & TFF_LISTENQ)); - tcp_conn= tcp_fd->tf_conn; - assert(!tcp_conn); - - if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP)) - == (NWTC_SET_RA|NWTC_SET_RP)) - { - tcp_conn= find_conn_entry( - tcp_fd->tf_tcpconf.nwtc_locport, - tcp_fd->tf_port->tp_ipaddr, - tcp_fd->tf_tcpconf.nwtc_remport, - tcp_fd->tf_tcpconf.nwtc_remaddr); - if (tcp_conn) - { - if (tcp_conn->tc_fd) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, EADDRINUSE, TRUE); - return NW_OK; - } - tcp_fd->tf_conn= tcp_conn; - return tcp_su4listen(tcp_fd, tcp_conn, do_listenq); - } - } - tcp_conn= find_empty_conn(); - if (!tcp_conn) - { - tcp_fd->tf_flags &= ~TFF_IOCTL_IP; - reply_thr_get (tcp_fd, EAGAIN, TRUE); - return NW_OK; - } - tcp_fd->tf_conn= tcp_conn; - return tcp_su4listen(tcp_fd, tcp_conn, do_listenq); -} - -/* -tcp_acceptto -*/ - -static int tcp_acceptto(tcp_fd) -tcp_fd_t *tcp_fd; -{ - int i, dst_nr; - tcp_fd_t *dst_fd; - tcp_conn_t *tcp_conn; - tcp_cookie_t *cookiep; - acc_t *data; - tcp_cookie_t cookie; - - if (!(tcp_fd->tf_flags & TFF_LISTENQ)) - { - tcp_reply_ioctl(tcp_fd, EINVAL); - return NW_OK; - } - for (i= 0; itf_listenq[i]; - if (tcp_conn && !tcp_conn->tc_connInprogress) - break; - } - if (i >= TFL_LISTEN_MAX) - { - /* Nothing, suspend caller */ - return NW_SUSPEND; - } - - data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0, - sizeof(*cookiep), TRUE); - if (!data) - return EFAULT; - - data= bf_packIffLess(data, sizeof(*cookiep)); - cookiep= (tcp_cookie_t *)ptr2acc_data(data); - cookie= *cookiep; - - bf_afree(data); data= NULL; - - dst_nr= cookie.tc_ref; - if (dst_nr < 0 || dst_nr >= TCP_FD_NR) - { - printf("tcp_acceptto: bad fd %d\n", dst_nr); - tcp_reply_ioctl(tcp_fd, EINVAL); - return NW_OK; - } - dst_fd= &tcp_fd_table[dst_nr]; - if (!(dst_fd->tf_flags & TFF_INUSE) || - (dst_fd->tf_flags & (TFF_READ_IP|TFF_WRITE_IP|TFF_IOCTL_IP)) || - dst_fd->tf_conn != NULL || - !(dst_fd->tf_flags & TFF_COOKIE)) - { - printf("tcp_acceptto: bad flags 0x%lx or conn %p for fd %d\n", - dst_fd->tf_flags, dst_fd->tf_conn, dst_nr); - tcp_reply_ioctl(tcp_fd, EINVAL); - return NW_OK; - } - if (memcmp(&cookie, &dst_fd->tf_cookie, sizeof(cookie)) != 0) - { - printf("tcp_acceptto: bad cookie\n"); - return NW_OK; - } - - /* Move connection */ - tcp_fd->tf_listenq[i]= NULL; - tcp_conn->tc_fd= dst_fd; - dst_fd->tf_conn= tcp_conn; - dst_fd->tf_flags |= TFF_CONNECTED; - - tcp_reply_ioctl(tcp_fd, NW_OK); - return NW_OK; -} - - -static void tcp_buffree (priority) -int priority; -{ - int i; - tcp_conn_t *tcp_conn; - - if (priority == TCP_PRI_FRAG2SEND) - { - for (i=0, tcp_conn= tcp_conn_table; itc_flags & TCF_INUSE)) - continue; - if (!tcp_conn->tc_frag2send) - continue; - if (tcp_conn->tc_busy) - continue; - bf_afree(tcp_conn->tc_frag2send); - tcp_conn->tc_frag2send= 0; - } - } - - if (priority == TCP_PRI_CONN_EXTRA) - { - for (i=0, tcp_conn= tcp_conn_table; itc_flags & TCF_INUSE)) - continue; - if (tcp_conn->tc_busy) - continue; - if (tcp_conn->tc_adv_data) - { - bf_afree(tcp_conn->tc_adv_data); - tcp_conn->tc_adv_data= NULL; - } - } - } - - if (priority == TCP_PRI_CONNwoUSER) - { - for (i=0, tcp_conn= tcp_conn_table; itc_flags & TCF_INUSE)) - continue; - if (tcp_conn->tc_busy) - continue; - if (tcp_conn->tc_fd) - continue; - if (tcp_conn->tc_state == TCS_CLOSED) - continue; - if (tcp_conn->tc_rcvd_data == NULL && - tcp_conn->tc_send_data == NULL) - { - continue; - } - tcp_close_connection (tcp_conn, ENOBUFS); - } - } - - if (priority == TCP_PRI_CONN_INUSE) - { - for (i=0, tcp_conn= tcp_conn_table; itc_flags & TCF_INUSE)) - continue; - if (tcp_conn->tc_busy) - continue; - if (tcp_conn->tc_state == TCS_CLOSED) - continue; - if (tcp_conn->tc_rcvd_data == NULL && - tcp_conn->tc_send_data == NULL) - { - continue; - } - tcp_close_connection (tcp_conn, ENOBUFS); - } - } -} - -#ifdef BUF_CONSISTENCY_CHECK -static void tcp_bufcheck() -{ - int i; - tcp_conn_t *tcp_conn; - tcp_port_t *tcp_port; - - for (i= 0, tcp_port= tcp_port_table; itp_pack) - bf_check_acc(tcp_port->tp_pack); - } - for (i= 0, tcp_conn= tcp_conn_table; itc_busy); - if (tcp_conn->tc_rcvd_data) - bf_check_acc(tcp_conn->tc_rcvd_data); - if (tcp_conn->tc_adv_data) - bf_check_acc(tcp_conn->tc_adv_data); - if (tcp_conn->tc_send_data) - bf_check_acc(tcp_conn->tc_send_data); - if (tcp_conn->tc_remipopt) - bf_check_acc(tcp_conn->tc_remipopt); - if (tcp_conn->tc_tcpopt) - bf_check_acc(tcp_conn->tc_tcpopt); - if (tcp_conn->tc_frag2send) - bf_check_acc(tcp_conn->tc_frag2send); - } -} -#endif - -void tcp_notreach(tcp_conn, error) -tcp_conn_t *tcp_conn; -int error; -{ - int new_ttl; - - new_ttl= tcp_conn->tc_ttl; - if (new_ttl == IP_MAX_TTL) - { - if (tcp_conn->tc_state == TCS_SYN_SENT) - tcp_close_connection(tcp_conn, error); - return; - } - else if (new_ttl < TCP_DEF_TTL_NEXT) - new_ttl= TCP_DEF_TTL_NEXT; - else - { - new_ttl *= 2; - if (new_ttl> IP_MAX_TTL) - new_ttl= IP_MAX_TTL; - } - tcp_conn->tc_ttl= new_ttl; - tcp_conn->tc_stt= 0; - tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA; - tcp_conn_write(tcp_conn, 1); -} - -static u32_t mtu_table[]= -{ /* From RFC-1191 */ -/* Plateau MTU Comments Reference */ -/* ------ --- -------- --------- */ -/* 65535 Official maximum MTU RFC 791 */ -/* 65535 Hyperchannel RFC 1044 */ - 65535, - 32000, /* Just in case */ -/* 17914 16Mb IBM Token Ring ref. [6] */ - 17914, -/* 8166 IEEE 802.4 RFC 1042 */ - 8166, -/* 4464 IEEE 802.5 (4Mb max) RFC 1042 */ -/* 4352 FDDI (Revised) RFC 1188 */ - 4352, /* (1%) */ -/* 2048 Wideband Network RFC 907 */ -/* 2002 IEEE 802.5 (4Mb recommended) RFC 1042 */ - 2002, /* (2%) */ -/* 1536 Exp. Ethernet Nets RFC 895 */ -/* 1500 Ethernet Networks RFC 894 */ -/* 1500 Point-to-Point (default) RFC 1134 */ -/* 1492 IEEE 802.3 RFC 1042 */ - 1492, /* (3%) */ -/* 1006 SLIP RFC 1055 */ -/* 1006 ARPANET BBN 1822 */ - 1006, -/* 576 X.25 Networks RFC 877 */ -/* 544 DEC IP Portal ref. [10] */ -/* 512 NETBIOS RFC 1088 */ -/* 508 IEEE 802/Source-Rt Bridge RFC 1042 */ -/* 508 ARCNET RFC 1051 */ - 508, /* (13%) */ -/* 296 Point-to-Point (low delay) RFC 1144 */ - 296, - 68, /* Official minimum MTU RFC 791 */ - 0, /* End of list */ -}; - -void tcp_mtu_exceeded(tcp_conn) -tcp_conn_t *tcp_conn; -{ - u16_t mtu; - int i; - clock_t curr_time; - - if (!(tcp_conn->tc_flags & TCF_PMTU)) - { - /* Strange, got MTU exceeded but DF is not set. Ignore - * the error. If the problem persists, the connection will - * time-out. - */ - return; - } - curr_time= get_time(); - - /* We get here in cases. Either were are trying to find an MTU - * that works at all, or we are trying see how far we can increase - * the current MTU. If the last change to the MTU was a long time - * ago, we assume the second case. - */ - if (curr_time >= tcp_conn->tc_mtutim + TCP_PMTU_INCR_IV) - { - mtu= tcp_conn->tc_mtu; - mtu -= mtu/TCP_PMTU_INCR_FRAC; - tcp_conn->tc_mtu= mtu; - tcp_conn->tc_mtutim= curr_time; - DBLOCK(1, printf( - "tcp_mtu_exceeded: new (lowered) mtu %d for conn %d\n", - mtu, tcp_conn-tcp_conn_table)); - tcp_conn->tc_stt= 0; - tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA; - tcp_conn_write(tcp_conn, 1); - return; - } - - tcp_conn->tc_mtutim= curr_time; - mtu= tcp_conn->tc_mtu; - for (i= 0; mtu_table[i] >= mtu; i++) - ; /* Nothing to do */ - mtu= mtu_table[i]; - if (mtu >= TCP_MIN_PATH_MTU) - { - tcp_conn->tc_mtu= mtu; - } - else - { - /* Small MTUs can be used for denial-of-service attacks. - * Switch-off PMTU if the MTU becomes too small. - */ - tcp_conn->tc_flags &= ~TCF_PMTU; - tcp_conn->tc_mtu= TCP_MIN_PATH_MTU; - DBLOCK(1, printf( - "tcp_mtu_exceeded: clearing TCF_PMTU for conn %d\n", - tcp_conn-tcp_conn_table);); - - } - DBLOCK(1, printf("tcp_mtu_exceeded: new mtu %d for conn %d\n", - mtu, tcp_conn-tcp_conn_table);); - tcp_conn->tc_stt= 0; - tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA; - tcp_conn_write(tcp_conn, 1); -} - -void tcp_mtu_incr(tcp_conn) -tcp_conn_t *tcp_conn; -{ - clock_t curr_time; - u32_t mtu; - - assert(tcp_conn->tc_mtu < tcp_conn->tc_max_mtu); - if (!(tcp_conn->tc_flags & TCF_PMTU)) - { - /* Use a much longer time-out for retrying PMTU discovery - * after is has been disabled. Note that PMTU discovery - * can be disabled during a short loss of connectivity. - */ - curr_time= get_time(); - if (curr_time > tcp_conn->tc_mtutim+TCP_PMTU_EN_IV) - { - tcp_conn->tc_flags |= TCF_PMTU; - DBLOCK(1, printf( - "tcp_mtu_incr: setting TCF_PMTU for conn %d\n", - tcp_conn-tcp_conn_table);); - } - return; - } - - mtu= tcp_conn->tc_mtu; - mtu += mtu/TCP_PMTU_INCR_FRAC; - if (mtu > tcp_conn->tc_max_mtu) - mtu= tcp_conn->tc_max_mtu; - tcp_conn->tc_mtu= mtu; - DBLOCK(0x1, printf("tcp_mtu_incr: new mtu %u for conn %u\n", - mtu, tcp_conn-tcp_conn_table);); -} - -/* -tcp_setup_conn -*/ - -static void tcp_setup_conn(tcp_port, tcp_conn) -tcp_port_t *tcp_port; -tcp_conn_t *tcp_conn; -{ - u16_t mss; - - assert(!tcp_conn->tc_connInprogress); - tcp_conn->tc_port= tcp_port; - if (tcp_conn->tc_flags & TCF_INUSE) - { - assert (tcp_conn->tc_state == TCS_CLOSED); - assert (!tcp_conn->tc_send_data); - if (tcp_conn->tc_senddis < get_time()) - tcp_conn->tc_ISS= 0; - } - else - { - assert(!tcp_conn->tc_busy); - tcp_conn->tc_senddis= 0; - tcp_conn->tc_ISS= 0; - tcp_conn->tc_tos= TCP_DEF_TOS; - tcp_conn->tc_ttl= TCP_DEF_TTL; - tcp_conn->tc_rcv_wnd= TCP_MAX_RCV_WND_SIZE; - tcp_conn->tc_fd= NULL; - } - if (!tcp_conn->tc_ISS) - { - tcp_conn->tc_ISS= tcp_rand32(); - } - tcp_conn->tc_SND_UNA= tcp_conn->tc_ISS; - tcp_conn->tc_SND_TRM= tcp_conn->tc_ISS; - tcp_conn->tc_SND_NXT= tcp_conn->tc_ISS+1; - tcp_conn->tc_SND_UP= tcp_conn->tc_ISS; - tcp_conn->tc_SND_PSH= tcp_conn->tc_ISS+1; - tcp_conn->tc_IRS= 0; - tcp_conn->tc_RCV_LO= tcp_conn->tc_IRS; - tcp_conn->tc_RCV_NXT= tcp_conn->tc_IRS; - tcp_conn->tc_RCV_HI= tcp_conn->tc_IRS; - tcp_conn->tc_RCV_UP= tcp_conn->tc_IRS; - - assert(tcp_conn->tc_rcvd_data == NULL); - assert(tcp_conn->tc_adv_data == NULL); - assert(tcp_conn->tc_send_data == NULL); - - tcp_conn->tc_ka_time= TCP_DEF_KEEPALIVE; - - tcp_conn->tc_remipopt= NULL; - tcp_conn->tc_tcpopt= NULL; - - assert(tcp_conn->tc_frag2send == NULL); - - tcp_conn->tc_stt= 0; - tcp_conn->tc_rt_dead= TCP_DEF_RT_DEAD; - tcp_conn->tc_0wnd_to= 0; - tcp_conn->tc_artt= TCP_DEF_RTT*TCP_RTT_SCALE; - tcp_conn->tc_drtt= 0; - tcp_conn->tc_rtt= TCP_DEF_RTT; - tcp_conn->tc_max_mtu= tcp_conn->tc_port->tp_mtu; - tcp_conn->tc_mtu= tcp_conn->tc_max_mtu; - tcp_conn->tc_mtutim= 0; - tcp_conn->tc_error= NW_OK; - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + 2*mss; - tcp_conn->tc_snd_cthresh= TCP_MAX_SND_WND_SIZE; - tcp_conn->tc_snd_cinc= - (long)TCP_DEF_MSS*TCP_DEF_MSS/TCP_MAX_SND_WND_SIZE+1; - tcp_conn->tc_snd_wnd= TCP_MAX_SND_WND_SIZE; - tcp_conn->tc_rt_time= 0; - tcp_conn->tc_rt_seq= 0; - tcp_conn->tc_rt_threshold= tcp_conn->tc_ISS; - tcp_conn->tc_flags= TCF_INUSE; - tcp_conn->tc_flags |= TCF_PMTU; - - clck_untimer(&tcp_conn->tc_transmit_timer); - tcp_conn->tc_transmit_seq= 0; -} - -static u32_t tcp_rand32() -{ - u8_t bits[RAND256_BUFSIZE]; - - rand256(bits); - return bits[0] | (bits[1] << 8) | (bits[2] << 16) | (bits[3] << 24); -} - -/* - * $PchId: tcp.c,v 1.34 2005/06/28 14:20:27 philip Exp $ - */ diff --git a/minix/net/inet/generic/tcp.h b/minix/net/inet/generic/tcp.h deleted file mode 100644 index 7b96d44e1..000000000 --- a/minix/net/inet/generic/tcp.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -tcp.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef TCP_H -#define TCP_H - -#define TCP_MAX_DATAGRAM 8192 - -#ifndef TCP_MAX_SND_WND_SIZE -#define TCP_MAX_SND_WND_SIZE (32*1024) -#endif - -#ifndef TCP_MIN_RCV_WND_SIZE -#define TCP_MIN_RCV_WND_SIZE (4*1024) -#endif - -#ifndef TCP_MAX_RCV_WND_SIZE -#define TCP_MAX_RCV_WND_SIZE (TCP_MIN_RCV_WND_SIZE + 28*1024) -#endif - -#define TCP_DEF_TOS 0 -#define TCP_DEF_TTL 5 /* hops/seconds */ -#define TCP_DEF_TTL_NEXT 30 /* hops/seconds */ - -/* An established TCP connection times out if no communication is possible - * for TCP_DEF_RT_DEAD clock ticks - */ -#ifndef TCP_DEF_RT_DEAD -#define TCP_DEF_RT_DEAD (20L*60*HZ) -#endif - -#define TCP_DEF_RT_MAX_CONNECT (5L*60*HZ) /* 5 minutes in ticks */ -#define TCP_DEF_RT_MAX_LISTEN (1L*60*HZ) /* 1 minute in ticks */ -#define TCP_DEF_RT_MAX_CLOSING (1L*60*HZ) /* 1 minute in ticks */ - -/* Minimum and maximum intervals for zero window probes. */ -#define TCP_0WND_MIN (HZ) -#define TCP_0WND_MAX (5*60*HZ) - -#define TCP_DEF_RTT 15 /* initial retransmission time in - * ticks - */ -#define TCP_RTT_GRAN 5 /* minimal value of the rtt is - * TCP_RTT_GRAN * CLOCK_GRAN - */ -#define TCP_RTT_MAX (10*HZ) /* The maximum retransmission interval - * is TCP_RTT_MAX ticks - */ -#define TCP_RTT_SMOOTH 16 /* weight is 15/16 */ -#define TCP_DRTT_MULT 4 /* weight of the deviation */ -#define TCP_RTT_SCALE 256 /* Scaled values for more accuracy */ - -#ifndef TCP_DEF_KEEPALIVE -#define TCP_DEF_KEEPALIVE (20L*60*HZ) /* Keepalive interval */ -#endif - -#ifndef TCP_DEF_MSS -#define TCP_DEF_MSS 1400 -#endif - -#define TCP_MIN_PATH_MTU 500 -#define TCP_PMTU_INCR_IV (1L*60*HZ) /* 1 minute in ticks */ -#define TCP_PMTU_EN_IV (10L*60*HZ) /* 10 minutes in ticks */ -#define TCP_PMTU_INCR_FRAC 100 /* Add 1% each time */ -#define TCP_PMTU_BLACKHOLE (10*HZ) /* Assume a PMTU blackhole - * after 10 seconds. - */ - -#define TCP_DEF_CONF (NWTC_COPY | NWTC_LP_UNSET | NWTC_UNSET_RA | \ - NWTC_UNSET_RP) -#define TCP_DEF_OPT (NWTO_NOFLAG) - -#define TCP_DACK_RETRANS 3 /* # dup ACKs to start fast retrans. */ - -struct acc; - -void tcp_prep ARGS(( void )); -void tcp_init ARGS(( void )); -int tcp_open ARGS(( int port, int srfd, - get_userdata_t get_userdata, put_userdata_t put_userdata, - put_pkt_t put_pkt, select_res_t select_res )); -int tcp_read ARGS(( int fd, size_t count)); -int tcp_write ARGS(( int fd, size_t count)); -int tcp_ioctl ARGS(( int fd, ioreq_t req)); -int tcp_cancel ARGS(( int fd, int which_operation )); -void tcp_close ARGS(( int fd)); - -#endif /* TCP_H */ - -/* - * $PchId: tcp.h,v 1.17 2005/06/28 14:20:54 philip Exp $ - */ diff --git a/minix/net/inet/generic/tcp_int.h b/minix/net/inet/generic/tcp_int.h deleted file mode 100644 index b20e74f24..000000000 --- a/minix/net/inet/generic/tcp_int.h +++ /dev/null @@ -1,266 +0,0 @@ -/* -tcp_int.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef TCP_INT_H -#define TCP_INT_H - -#define IP_TCP_MIN_HDR_SIZE (IP_MIN_HDR_SIZE+TCP_MIN_HDR_SIZE) - -#define TCP_CONN_HASH_SHIFT 4 -#define TCP_CONN_HASH_NR (1 << TCP_CONN_HASH_SHIFT) - -typedef struct tcp_port -{ - int tp_ipdev; - int tp_flags; - int tp_state; - int tp_ipfd; - acc_t *tp_pack; - ipaddr_t tp_ipaddr; - ipaddr_t tp_subnetmask; - u16_t tp_mtu; - struct tcp_conn *tp_snd_head; - struct tcp_conn *tp_snd_tail; - event_t tp_snd_event; - struct tcp_conn *tp_conn_hash[TCP_CONN_HASH_NR][4]; -} tcp_port_t; - -#define TPF_EMPTY 0x0 -#define TPF_SUSPEND 0x1 -#define TPF_READ_IP 0x2 -#define TPF_READ_SP 0x4 -#define TPF_WRITE_IP 0x8 -#define TPF_WRITE_SP 0x10 -#define TPF_DELAY_TCP 0x40 - -#define TPS_EMPTY 0 -#define TPS_SETPROTO 1 -#define TPS_GETCONF 2 -#define TPS_MAIN 3 -#define TPS_ERROR 4 - -#define TFL_LISTEN_MAX 5 - -typedef struct tcp_fd -{ - unsigned long tf_flags; - tcp_port_t *tf_port; - int tf_srfd; - ioreq_t tf_ioreq; - nwio_tcpconf_t tf_tcpconf; - nwio_tcpopt_t tf_tcpopt; - get_userdata_t tf_get_userdata; - put_userdata_t tf_put_userdata; - select_res_t tf_select_res; - struct tcp_conn *tf_conn; - struct tcp_conn *tf_listenq[TFL_LISTEN_MAX]; - size_t tf_write_offset; - size_t tf_write_count; - size_t tf_read_offset; - size_t tf_read_count; - int tf_error; /* Error for nonblocking connect */ - tcp_cookie_t tf_cookie; -} tcp_fd_t; - -#define TFF_EMPTY 0x0 -#define TFF_INUSE 0x1 -#define TFF_READ_IP 0x2 -#define TFF_WRITE_IP 0x4 -#define TFF_IOCTL_IP 0x8 -#define TFF_CONF_SET 0x10 -#define TFF_IOC_INIT_SP 0x20 -#define TFF_LISTENQ 0x40 -#define TFF_CONNECTING 0x80 -#define TFF_CONNECTED 0x100 -#define TFF_WR_URG 0x200 -#define TFF_PUSH_DATA 0x400 -#define TFF_RECV_URG 0x800 -#define TFF_SEL_READ 0x1000 -#define TFF_SEL_WRITE 0x2000 -#define TFF_SEL_EXCEPT 0x4000 -#define TFF_DEL_RST 0x8000 -#define TFF_COOKIE 0x10000 - -typedef struct tcp_conn -{ - int tc_flags; - int tc_state; - int tc_busy; /* do not steal buffer when a connection is - * busy - */ - tcp_port_t *tc_port; - tcp_fd_t *tc_fd; - - tcpport_t tc_locport; - ipaddr_t tc_locaddr; - tcpport_t tc_remport; - ipaddr_t tc_remaddr; - - int tc_connInprogress; - int tc_orglisten; - clock_t tc_senddis; - - /* Sending side */ - u32_t tc_ISS; /* initial sequence number */ - u32_t tc_SND_UNA; /* least unacknowledged sequence number */ - u32_t tc_SND_TRM; /* next sequence number to be transmitted */ - u32_t tc_SND_NXT; /* next sequence number for new data */ - u32_t tc_SND_UP; /* urgent pointer, first sequence number not - * urgent */ - u32_t tc_SND_PSH; /* push pointer, data should be pushed until - * the push pointer is reached */ - - u32_t tc_snd_cwnd; /* highest sequence number to be sent */ - u32_t tc_snd_cthresh; /* threshold for send window */ - u32_t tc_snd_cinc; /* increment for send window threshold */ - u16_t tc_snd_wnd; /* max send queue size */ - u16_t tc_snd_dack; /* # of duplicate ACKs */ - - /* round trip calculation. */ - clock_t tc_rt_time; - u32_t tc_rt_seq; - u32_t tc_rt_threshold; - clock_t tc_artt; /* Avg. retransmission time. Scaled. */ - clock_t tc_drtt; /* Diviation, also scaled. */ - clock_t tc_rtt; /* Computed retrans time */ - - acc_t *tc_send_data; - acc_t *tc_frag2send; - struct tcp_conn *tc_send_link; - - /* Receiving side */ - u32_t tc_IRS; - u32_t tc_RCV_LO; - u32_t tc_RCV_NXT; - u32_t tc_RCV_HI; - u32_t tc_RCV_UP; - - u16_t tc_rcv_wnd; - acc_t *tc_rcvd_data; - acc_t *tc_adv_data; - u32_t tc_adv_seq; - - /* Keep alive. Record SDN_NXT and RCV_NXT in tc_ka_snd and - * tc_ka_rcv when setting the keepalive timer to detect - * any activity that may have happend before the timer - * expired. - */ - u32_t tc_ka_snd; - u32_t tc_ka_rcv; - clock_t tc_ka_time; - - acc_t *tc_remipopt; - acc_t *tc_tcpopt; - u8_t tc_tos; - u8_t tc_ttl; - u16_t tc_max_mtu; /* Max. negotiated (or selected) MTU */ - u16_t tc_mtu; /* discovered PMTU */ - clock_t tc_mtutim; /* Last time MTU/TCF_PMTU flag was changed */ - - minix_timer_t tc_transmit_timer; - u32_t tc_transmit_seq; - clock_t tc_0wnd_to; - clock_t tc_stt; /* time of first send after last ack */ - clock_t tc_rt_dead; - - int tc_error; - int tc_inconsistent; -} tcp_conn_t; - -#define TCF_EMPTY 0x0 -#define TCF_INUSE 0x1 -#define TCF_FIN_RECV 0x2 -#define TCF_RCV_PUSH 0x4 -#define TCF_MORE2WRITE 0x8 -#define TCF_SEND_ACK 0x10 -#define TCF_FIN_SENT 0x20 -#define TCF_BSD_URG 0x40 -#define TCF_NO_PUSH 0x80 -#define TCF_PUSH_NOW 0x100 -#define TCF_PMTU 0x200 - -#if DEBUG & 0x200 -#define TCF_DEBUG 0x1000 -#endif - -#define TCS_CLOSED 0 -#define TCS_LISTEN 1 -#define TCS_SYN_RECEIVED 2 -#define TCS_SYN_SENT 3 -#define TCS_ESTABLISHED 4 -#define TCS_CLOSING 5 - -/* tcp_recv.c */ -void tcp_frag2conn ARGS(( tcp_conn_t *tcp_conn, ip_hdr_t *ip_hdr, - tcp_hdr_t *tcp_hdr, acc_t *tcp_data, size_t data_len )); -void tcp_fd_read ARGS(( tcp_conn_t *tcp_conn, int enq )); -unsigned tcp_sel_read ARGS(( tcp_conn_t *tcp_conn )); -void tcp_rsel_read ARGS(( tcp_conn_t *tcp_conn )); -void tcp_bytesavailable ARGS(( tcp_fd_t *tcp_fd, int *bytesp )); - -/* tcp_send.c */ -void tcp_conn_write ARGS(( tcp_conn_t *tcp_conn, int enq )); -void tcp_release_retrans ARGS(( tcp_conn_t *tcp_conn, u32_t seg_ack, - u16_t new_win )); -void tcp_fast_retrans ARGS(( tcp_conn_t *tcp_conn )); -void tcp_set_send_timer ARGS(( tcp_conn_t *tcp_conn )); -void tcp_fd_write ARGS(( tcp_conn_t *tcp_conn )); -unsigned tcp_sel_write ARGS(( tcp_conn_t *tcp_conn )); -void tcp_rsel_write ARGS(( tcp_conn_t *tcp_conn )); -void tcp_close_connection ARGS(( tcp_conn_t *tcp_conn, - int error )); -void tcp_port_write ARGS(( tcp_port_t *tcp_port )); -void tcp_shutdown ARGS(( tcp_conn_t *tcp_conn )); - -/* tcp_lib.c */ -void tcp_extract_ipopt ARGS(( tcp_conn_t *tcp_conn, - ip_hdr_t *ip_hdr )); -void tcp_extract_tcpopt ARGS(( tcp_conn_t *tcp_conn, - tcp_hdr_t *tcp_hdr, size_t *mssp )); -void tcp_get_ipopt ARGS(( tcp_conn_t *tcp_conn, ip_hdropt_t - *ip_hdropt )); -void tcp_get_tcpopt ARGS(( tcp_conn_t *tcp_conn, tcp_hdropt_t - *tcp_hdropt )); -acc_t *tcp_make_header ARGS(( tcp_conn_t *tcp_conn, - ip_hdr_t **ref_ip_hdr, tcp_hdr_t **ref_tcp_hdr, acc_t *data )); -u16_t tcp_pack_oneCsum ARGS(( ip_hdr_t *ip_hdr, acc_t *tcp_pack )); -int tcp_check_conn ARGS(( tcp_conn_t *tcp_conn )); -void tcp_print_pack ARGS(( ip_hdr_t *ip_hdr, tcp_hdr_t *tcp_hdr )); -void tcp_print_state ARGS(( tcp_conn_t *tcp_conn )); -void tcp_print_conn ARGS(( tcp_conn_t *tcp_conn )); -int tcp_LEmod4G ARGS(( u32_t n1, u32_t n2 )); -int tcp_Lmod4G ARGS(( u32_t n1, u32_t n2 )); -int tcp_GEmod4G ARGS(( u32_t n1, u32_t n2 )); -int tcp_Gmod4G ARGS(( u32_t n1, u32_t n2 )); - -/* tcp.c */ -void tcp_restart_connect ARGS(( tcp_conn_t *tcp_conn )); -int tcp_su4listen ARGS(( tcp_fd_t *tcp_fd, tcp_conn_t *tcp_conn, - int do_listenq )); -void tcp_reply_ioctl ARGS(( tcp_fd_t *tcp_fd, int reply )); -void tcp_reply_write ARGS(( tcp_fd_t *tcp_fd, size_t reply )); -void tcp_reply_read ARGS(( tcp_fd_t *tcp_fd, size_t reply )); -void tcp_notreach ARGS(( tcp_conn_t *tcp_conn, int error )); -void tcp_mtu_exceeded ARGS(( tcp_conn_t *tcp_conn )); -void tcp_mtu_incr ARGS(( tcp_conn_t *tcp_conn )); - -#define TCP_FD_NR (10*IP_PORT_MAX) -#define TCP_CONN_NR (2*TCP_FD_NR) - -EXTERN tcp_port_t *tcp_port_table; -EXTERN tcp_conn_t tcp_conn_table[TCP_CONN_NR]; -EXTERN tcp_fd_t tcp_fd_table[TCP_FD_NR]; - -#define tcp_Lmod4G(n1,n2) (!!(((n1)-(n2)) & 0x80000000L)) -#define tcp_GEmod4G(n1,n2) (!(((n1)-(n2)) & 0x80000000L)) -#define tcp_Gmod4G(n1,n2) (!!(((n2)-(n1)) & 0x80000000L)) -#define tcp_LEmod4G(n1,n2) (!(((n2)-(n1)) & 0x80000000L)) - -#endif /* TCP_INT_H */ - -/* - * $PchId: tcp_int.h,v 1.17 2005/06/28 14:21:08 philip Exp $ - */ diff --git a/minix/net/inet/generic/tcp_lib.c b/minix/net/inet/generic/tcp_lib.c deleted file mode 100644 index 0306e6d3a..000000000 --- a/minix/net/inet/generic/tcp_lib.c +++ /dev/null @@ -1,594 +0,0 @@ -/* -tcp_lib.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "io.h" -#include "type.h" - -#include "assert.h" -#include "tcp_int.h" - -THIS_FILE - -#undef tcp_LEmod4G -int tcp_LEmod4G(n1, n2) -u32_t n1; -u32_t n2; -{ - return !((u32_t)(n2-n1) & 0x80000000L); -} - -#undef tcp_GEmod4G -int tcp_GEmod4G(n1, n2) -u32_t n1; -u32_t n2; -{ - return !((u32_t)(n1-n2) & 0x80000000L); -} - -#undef tcp_Lmod4G -int tcp_Lmod4G(n1, n2) -u32_t n1; -u32_t n2; -{ - return !!((u32_t)(n1-n2) & 0x80000000L); -} - -#undef tcp_Gmod4G -int tcp_Gmod4G(n1, n2) -u32_t n1; -u32_t n2; -{ - return !!((u32_t)(n2-n1) & 0x80000000L); -} - -void tcp_extract_ipopt(tcp_conn, ip_hdr) -tcp_conn_t *tcp_conn; -ip_hdr_t *ip_hdr; -{ - int ip_hdr_len; - - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - if (ip_hdr_len == IP_MIN_HDR_SIZE) - return; - - DBLOCK(1, printf("ip_hdr options NOT supported (yet?)\n")); -} - -void tcp_extract_tcpopt(tcp_conn, tcp_hdr, mssp) -tcp_conn_t *tcp_conn; -tcp_hdr_t *tcp_hdr; -size_t *mssp; -{ - int i, tcp_hdr_len, type, len; - u8_t *cp; - u16_t mss; - - *mssp= 0; /* No mss */ - - tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2; - if (tcp_hdr_len == TCP_MIN_HDR_SIZE) - return; - i= TCP_MIN_HDR_SIZE; - while (i tcp_hdr_len) - break; /* No length field */ - len= cp[1]; - if (len < 2) - break; /* Length too short */ - if (i+len > tcp_hdr_len) - break; /* Truncated option */ - i += len; - switch(type) - { - case TCP_OPT_MSS: - if (len != 4) - break; - mss= (cp[2] << 8) | cp[3]; - DBLOCK(1, printf("tcp_extract_tcpopt: got mss %d\n", - mss);); - *mssp= mss; - break; - case TCP_OPT_WSOPT: /* window scale option */ - case TCP_OPT_SACKOK: /* SACK permitted */ - case TCP_OPT_TS: /* Timestamps option */ - case TCP_OPT_CCNEW: /* new connection count */ - /* Ignore this option. */ - break; - default: - DBLOCK(0x1, - printf( - "tcp_extract_tcpopt: unknown option %d, len %d\n", - type, len)); - break; - } - } -} - -u16_t tcp_pack_oneCsum(ip_hdr, tcp_pack) -ip_hdr_t *ip_hdr; -acc_t *tcp_pack; -{ - size_t ip_hdr_len; - acc_t *pack; - u16_t sum; - u16_t word_buf[6]; - int odd_length; - char *data_ptr; - int length; - - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - word_buf[0]= ip_hdr->ih_src & 0xffff; - word_buf[1]= (ip_hdr->ih_src >> 16) & 0xffff; - word_buf[2]= ip_hdr->ih_dst & 0xffff; - word_buf[3]= (ip_hdr->ih_dst >> 16) & 0xffff; - word_buf[4]= HTONS(IPPROTO_TCP); - word_buf[5]= htons(ntohs(ip_hdr->ih_length)-ip_hdr_len); - sum= oneC_sum(0, word_buf, sizeof(word_buf)); - - pack= tcp_pack; - odd_length= 0; - for (; pack; pack= pack->acc_next) - { - - data_ptr= ptr2acc_data(pack); - length= pack->acc_length; - - if (!length) - continue; - sum= oneC_sum (sum, (u16_t *)data_ptr, length); - if (length & 1) - { - odd_length= !odd_length; - sum= ((sum >> 8) & 0xff) | ((sum & 0xff) << 8); - } - } - if (odd_length) - { - /* Undo the last swap */ - sum= ((sum >> 8) & 0xff) | ((sum & 0xff) << 8); - } - return sum; -} - -void tcp_get_ipopt(tcp_conn, ip_hdropt) -tcp_conn_t *tcp_conn; -ip_hdropt_t *ip_hdropt; -{ - if (!tcp_conn->tc_remipopt) - { - ip_hdropt->iho_opt_siz= 0; - return; - } - DBLOCK(1, printf("ip_hdr options NOT supported (yet?)\n")); - ip_hdropt->iho_opt_siz= 0; - return; -} - -void tcp_get_tcpopt(tcp_conn, tcp_hdropt) -tcp_conn_t *tcp_conn; -tcp_hdropt_t *tcp_hdropt; -{ - int optsiz; - - if (!tcp_conn->tc_tcpopt) - { - tcp_hdropt->tho_opt_siz= 0; - return; - } - tcp_conn->tc_tcpopt= bf_pack(tcp_conn->tc_tcpopt); - optsiz= bf_bufsize(tcp_conn->tc_tcpopt); - memcpy(tcp_hdropt->tho_data, ptr2acc_data(tcp_conn->tc_tcpopt), - optsiz); - if ((optsiz & 3) != 0) - { - tcp_hdropt->tho_data[optsiz]= TCP_OPT_EOL; - optsiz= (optsiz+3) & ~3; - } - tcp_hdropt->tho_opt_siz= optsiz; - - return; -} - -acc_t *tcp_make_header(tcp_conn, ref_ip_hdr, ref_tcp_hdr, data) -tcp_conn_t *tcp_conn; -ip_hdr_t **ref_ip_hdr; -tcp_hdr_t **ref_tcp_hdr; -acc_t *data; -{ - ip_hdropt_t ip_hdropt; - tcp_hdropt_t tcp_hdropt; - ip_hdr_t *ip_hdr; - tcp_hdr_t *tcp_hdr; - acc_t *hdr_acc; - char *ptr2hdr; - int closed_connection; - - closed_connection= (tcp_conn->tc_state == TCS_CLOSED); - - if (tcp_conn->tc_remipopt || tcp_conn->tc_tcpopt) - { - tcp_get_ipopt (tcp_conn, &ip_hdropt); - tcp_get_tcpopt (tcp_conn, &tcp_hdropt); - assert (!(ip_hdropt.iho_opt_siz & 3)); - assert (!(tcp_hdropt.tho_opt_siz & 3)); - - hdr_acc= bf_memreq(IP_MIN_HDR_SIZE+ - ip_hdropt.iho_opt_siz+TCP_MIN_HDR_SIZE+ - tcp_hdropt.tho_opt_siz); - ptr2hdr= ptr2acc_data(hdr_acc); - - ip_hdr= (ip_hdr_t *)ptr2hdr; - ptr2hdr += IP_MIN_HDR_SIZE; - - if (ip_hdropt.iho_opt_siz) - { - memcpy(ptr2hdr, (char *)ip_hdropt.iho_data, - ip_hdropt.iho_opt_siz); - } - ptr2hdr += ip_hdropt.iho_opt_siz; - - tcp_hdr= (tcp_hdr_t *)ptr2hdr; - ptr2hdr += TCP_MIN_HDR_SIZE; - - if (tcp_hdropt.tho_opt_siz) - { - memcpy (ptr2hdr, (char *)tcp_hdropt.tho_data, - tcp_hdropt.tho_opt_siz); - } - hdr_acc->acc_next= data; - - ip_hdr->ih_vers_ihl= (IP_MIN_HDR_SIZE+ - ip_hdropt.iho_opt_siz) >> 2; - tcp_hdr->th_data_off= (TCP_MIN_HDR_SIZE+ - tcp_hdropt.tho_opt_siz) << 2; - } - else - { - hdr_acc= bf_memreq(IP_MIN_HDR_SIZE+TCP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(hdr_acc); - tcp_hdr= (tcp_hdr_t *)&ip_hdr[1]; - hdr_acc->acc_next= data; - - ip_hdr->ih_vers_ihl= IP_MIN_HDR_SIZE >> 2; - tcp_hdr->th_data_off= TCP_MIN_HDR_SIZE << 2; - } - - if (!closed_connection && (tcp_conn->tc_state == TCS_CLOSED)) - { - DBLOCK(1, printf("connection closed while inuse\n")); - bf_afree(hdr_acc); - return 0; - } - - ip_hdr->ih_tos= tcp_conn->tc_tos; - ip_hdr->ih_ttl= tcp_conn->tc_ttl; - ip_hdr->ih_proto= IPPROTO_TCP; - ip_hdr->ih_src= tcp_conn->tc_locaddr; - ip_hdr->ih_dst= tcp_conn->tc_remaddr; - ip_hdr->ih_flags_fragoff= 0; - if (tcp_conn->tc_flags & TCF_PMTU) - ip_hdr->ih_flags_fragoff |= HTONS(IH_DONT_FRAG); - - tcp_hdr->th_srcport= tcp_conn->tc_locport; - tcp_hdr->th_dstport= tcp_conn->tc_remport; - tcp_hdr->th_seq_nr= tcp_conn->tc_RCV_NXT; - tcp_hdr->th_flags= 0; - tcp_hdr->th_window= htons(tcp_conn->tc_RCV_HI-tcp_conn->tc_RCV_LO); - tcp_hdr->th_chksum= 0; - *ref_ip_hdr= ip_hdr; - *ref_tcp_hdr= tcp_hdr; - return hdr_acc; -} - -void tcp_print_state (tcp_conn) -tcp_conn_t *tcp_conn; -{ -#if DEBUG - printf("tcp_conn_table[%d]->tc_state= ", tcp_conn- - tcp_conn_table); - if (!(tcp_conn->tc_flags & TCF_INUSE)) - { - printf("not inuse\n"); - return; - } - switch (tcp_conn->tc_state) - { - case TCS_CLOSED: printf("CLOSED"); break; - case TCS_LISTEN: printf("LISTEN"); break; - case TCS_SYN_RECEIVED: printf("SYN_RECEIVED"); break; - case TCS_SYN_SENT: printf("SYN_SENT"); break; - case TCS_ESTABLISHED: printf("ESTABLISHED"); break; - case TCS_CLOSING: printf("CLOSING"); break; - default: printf("unknown (=%d)", tcp_conn->tc_state); break; - } -#endif -} - -int tcp_check_conn(tcp_conn) -tcp_conn_t *tcp_conn; -{ - int allright; - u32_t lo_queue, hi_queue; - int size; - - allright= TRUE; - if (tcp_conn->tc_inconsistent) - { - assert(tcp_conn->tc_inconsistent == 1); - printf("tcp_check_conn: connection is inconsistent\n"); - return allright; - } - - /* checking receive queue */ - lo_queue= tcp_conn->tc_RCV_LO; - if (lo_queue == tcp_conn->tc_IRS) - lo_queue++; - if (lo_queue == tcp_conn->tc_RCV_NXT && (tcp_conn->tc_flags & - TCF_FIN_RECV)) - lo_queue--; - hi_queue= tcp_conn->tc_RCV_NXT; - if (hi_queue == tcp_conn->tc_IRS) - hi_queue++; - if (tcp_conn->tc_flags & TCF_FIN_RECV) - hi_queue--; - - size= hi_queue-lo_queue; - if (size<0) - { - printf("rcv hi_queue-lo_queue < 0\n"); - printf("SND_NXT= 0x%lx, SND_UNA= 0x%lx\n", - (unsigned long)tcp_conn->tc_SND_NXT, - (unsigned long)tcp_conn->tc_SND_UNA); - printf("lo_queue= 0x%lx, hi_queue= 0x%lx\n", - (unsigned long)lo_queue, - (unsigned long)hi_queue); - printf("size= %d\n", size); - allright= FALSE; - } - else if (!tcp_conn->tc_rcvd_data) - { - if (size) - { - printf("RCV_NXT-RCV_LO != 0\n"); - tcp_print_conn(tcp_conn); - printf("lo_queue= %u, hi_queue= %u\n", - lo_queue, hi_queue); - allright= FALSE; - } - } - else if (size != bf_bufsize(tcp_conn->tc_rcvd_data)) - { - printf("RCV_NXT-RCV_LO != sizeof tc_rcvd_data\n"); - tcp_print_conn(tcp_conn); - printf( - "lo_queue= %u, hi_queue= %u, sizeof tc_rcvd_data= %d\n", - lo_queue, hi_queue, bf_bufsize(tcp_conn->tc_rcvd_data)); - allright= FALSE; - } - else if (size != 0 && (tcp_conn->tc_state == TCS_CLOSED || - tcp_conn->tc_state == TCS_LISTEN || - tcp_conn->tc_state == TCS_SYN_RECEIVED || - tcp_conn->tc_state == TCS_SYN_SENT)) - { - printf("received data but not connected\n"); - tcp_print_conn(tcp_conn); - allright= FALSE; - } - if (tcp_Lmod4G(tcp_conn->tc_RCV_HI, tcp_conn->tc_RCV_NXT)) - { - printf("tc_RCV_HI (0x%lx) < tc_RCV_NXT (0x%lx)\n", - (unsigned long)tcp_conn->tc_RCV_HI, - (unsigned long)tcp_conn->tc_RCV_NXT); - allright= FALSE; - } - - /* checking send data */ - lo_queue= tcp_conn->tc_SND_UNA; - if (lo_queue == tcp_conn->tc_ISS) - lo_queue++; - if (lo_queue == tcp_conn->tc_SND_NXT && - (tcp_conn->tc_flags & TCF_FIN_SENT)) - { - lo_queue--; - } - hi_queue= tcp_conn->tc_SND_NXT; - if (hi_queue == tcp_conn->tc_ISS) - hi_queue++; - if (tcp_conn->tc_flags & TCF_FIN_SENT) - hi_queue--; - - size= hi_queue-lo_queue; - if (size<0) - { - printf("snd hi_queue-lo_queue < 0\n"); - printf("SND_ISS= 0x%lx, SND_UNA= 0x%lx, SND_NXT= 0x%lx\n", - (unsigned long)tcp_conn->tc_ISS, - (unsigned long)tcp_conn->tc_SND_UNA, - (unsigned long)tcp_conn->tc_SND_NXT); - printf("hi_queue= 0x%lx, lo_queue= 0x%lx, size= %d\n", - (unsigned long)hi_queue, (unsigned long)lo_queue, - size); - allright= FALSE; - } - else if (!tcp_conn->tc_send_data) - { - if (size) - { - printf("SND_NXT-SND_UNA != 0\n"); - printf("SND_NXT= 0x%lx, SND_UNA= 0x%lx\n", - (unsigned long)tcp_conn->tc_SND_NXT, - (unsigned long)tcp_conn->tc_SND_UNA); - printf("lo_queue= 0x%lx, hi_queue= 0x%lx\n", - (unsigned long)lo_queue, - (unsigned long)hi_queue); - allright= FALSE; - } - } - else if (size != bf_bufsize(tcp_conn->tc_send_data)) - { - printf("SND_NXT-SND_UNA != sizeof tc_send_data\n"); - printf("SND_NXT= 0x%lx, SND_UNA= 0x%lx\n", - (unsigned long)tcp_conn->tc_SND_NXT, - (unsigned long)tcp_conn->tc_SND_UNA); - printf("lo_queue= 0x%lx, lo_queue= 0x%lx\n", - (unsigned long)lo_queue, - (unsigned long)hi_queue); - printf("bf_bufsize(data)= %d\n", - bf_bufsize(tcp_conn->tc_send_data)); - - allright= FALSE; - } - - /* checking counters */ - if (!tcp_GEmod4G(tcp_conn->tc_SND_UNA, tcp_conn->tc_ISS)) - { - printf("SND_UNA < ISS\n"); - allright= FALSE; - } - if (!tcp_GEmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_UNA)) - { - printf("SND_NXTtc_SND_TRM, tcp_conn->tc_SND_UNA)) - { - printf("SND_TRMtc_SND_NXT, tcp_conn->tc_SND_TRM)) - { - printf("SND_NXTih_src); - else - printf("???"); - printf(",%u ", ntohs(tcp_hdr->th_srcport)); - if (ip_hdr) - writeIpAddr(ip_hdr->ih_dst); - else - printf("???"); - printf(",%u ", ntohs(tcp_hdr->th_dstport)); - printf(" 0x%x", ntohl(tcp_hdr->th_seq_nr)); - if (tcp_hdr->th_flags & THF_FIN) - printf(" "); - if (tcp_hdr->th_flags & THF_SYN) - printf(" "); - if (tcp_hdr->th_flags & THF_RST) - printf(" "); - if (tcp_hdr->th_flags & THF_PSH) - printf(" "); - if (tcp_hdr->th_flags & THF_ACK) - printf(" ", ntohl(tcp_hdr->th_ack_nr), - ntohs(tcp_hdr->th_window)); - if (tcp_hdr->th_flags & THF_URG) - printf(" ", tcp_hdr->th_urgptr); - tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2; - if (tcp_hdr_len != TCP_MIN_HDR_SIZE) - printf(" ", tcp_hdr_len-TCP_MIN_HDR_SIZE); -} - -void tcp_print_conn(tcp_conn) -tcp_conn_t *tcp_conn; -{ - u32_t iss, irs; - tcp_fd_t *tcp_fd; - - iss= tcp_conn->tc_ISS; - irs= tcp_conn->tc_IRS; - - tcp_print_state (tcp_conn); - printf( - " ISS 0x%x UNA +0x%x(0x%x) TRM +0x%x(0x%x) NXT +0x%x(0x%x)", - iss, tcp_conn->tc_SND_UNA-iss, tcp_conn->tc_SND_UNA, - tcp_conn->tc_SND_TRM-iss, tcp_conn->tc_SND_TRM, - tcp_conn->tc_SND_NXT-iss, tcp_conn->tc_SND_NXT); - printf( - " UP +0x%x(0x%x) PSH +0x%x(0x%x) ", - tcp_conn->tc_SND_UP-iss, tcp_conn->tc_SND_UP, - tcp_conn->tc_SND_PSH-iss, tcp_conn->tc_SND_PSH); - printf(" snd_cwnd +0x%x(0x%x)", - tcp_conn->tc_snd_cwnd-tcp_conn->tc_SND_UNA, - tcp_conn->tc_snd_cwnd); - printf(" transmit_seq "); - if (tcp_conn->tc_transmit_seq == 0) - printf("0"); - else - { - printf("+0x%x(0x%x)", tcp_conn->tc_transmit_seq-iss, - tcp_conn->tc_transmit_seq); - } - printf(" IRS 0x%x LO +0x%x(0x%x) NXT +0x%x(0x%x) HI +0x%x(0x%x)", - irs, tcp_conn->tc_RCV_LO-irs, tcp_conn->tc_RCV_LO, - tcp_conn->tc_RCV_NXT-irs, tcp_conn->tc_RCV_NXT, - tcp_conn->tc_RCV_HI-irs, tcp_conn->tc_RCV_HI); - if (tcp_conn->tc_flags & TCF_INUSE) - printf(" TCF_INUSE"); - if (tcp_conn->tc_flags & TCF_FIN_RECV) - printf(" TCF_FIN_RECV"); - if (tcp_conn->tc_flags & TCF_RCV_PUSH) - printf(" TCF_RCV_PUSH"); - if (tcp_conn->tc_flags & TCF_MORE2WRITE) - printf(" TCF_MORE2WRITE"); - if (tcp_conn->tc_flags & TCF_SEND_ACK) - printf(" TCF_SEND_ACK"); - if (tcp_conn->tc_flags & TCF_FIN_SENT) - printf(" TCF_FIN_SENT"); - if (tcp_conn->tc_flags & TCF_BSD_URG) - printf(" TCF_BSD_URG"); - if (tcp_conn->tc_flags & TCF_NO_PUSH) - printf(" TCF_NO_PUSH"); - if (tcp_conn->tc_flags & TCF_PUSH_NOW) - printf(" TCF_PUSH_NOW"); - if (tcp_conn->tc_flags & TCF_PMTU) - printf(" TCF_PMTU"); - printf("\n"); - writeIpAddr(tcp_conn->tc_locaddr); - printf(", %u -> ", ntohs(tcp_conn->tc_locport)); - writeIpAddr(tcp_conn->tc_remaddr); - printf(", %u\n", ntohs(tcp_conn->tc_remport)); - tcp_fd= tcp_conn->tc_fd; - if (!tcp_fd) - printf("tc_fd NULL"); - else - { - printf("tc_fd #%d: flags 0x%lx, r %u@%u, w %u@%u", - tcp_fd-tcp_fd_table, tcp_fd->tf_flags, - tcp_fd->tf_read_count, tcp_fd->tf_read_offset, - tcp_fd->tf_write_count, tcp_fd->tf_write_offset); - } -} - -/* - * $PchId: tcp_lib.c,v 1.14 2005/01/31 21:41:38 philip Exp $ - */ diff --git a/minix/net/inet/generic/tcp_recv.c b/minix/net/inet/generic/tcp_recv.c deleted file mode 100644 index 8178899b8..000000000 --- a/minix/net/inet/generic/tcp_recv.c +++ /dev/null @@ -1,1475 +0,0 @@ -/* -tcp_recv.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "type.h" -#include "sr.h" - -#include "io.h" -#include "tcp_int.h" -#include "tcp.h" -#include "assert.h" - -THIS_FILE - -static void create_RST ARGS(( tcp_conn_t *tcp_conn, - ip_hdr_t *ip_hdr, tcp_hdr_t *tcp_hdr, int data_len )); -static void process_data ARGS(( tcp_conn_t *tcp_conn, - tcp_hdr_t *tcp_hdr, acc_t *tcp_data, int data_len )); -static void process_advanced_data ARGS(( tcp_conn_t *tcp_conn, - tcp_hdr_t *tcp_hdr, acc_t *tcp_data, int data_len )); - -void tcp_frag2conn(tcp_conn, ip_hdr, tcp_hdr, tcp_data, data_len) -tcp_conn_t *tcp_conn; -ip_hdr_t *ip_hdr; -tcp_hdr_t *tcp_hdr; -acc_t *tcp_data; -size_t data_len; -{ - tcp_fd_t *connuser; - int tcp_hdr_flags; - u32_t seg_ack, seg_seq, rcv_hi, snd_una, snd_nxt; - u16_t seg_wnd, mtu; - size_t mss; - int acceptable_ACK, segm_acceptable, send_rst, close_connection; - - tcp_hdr_flags= tcp_hdr->th_flags & TH_FLAGS_MASK; - seg_ack= ntohl(tcp_hdr->th_ack_nr); - seg_seq= ntohl(tcp_hdr->th_seq_nr); - seg_wnd= ntohs(tcp_hdr->th_window); - -#if 0 - { where(); tcp_print_conn(tcp_conn); printf("\n"); - tcp_print_pack(ip_hdr, tcp_hdr); printf("\n"); } -#endif - - switch (tcp_conn->tc_state) - { - case TCS_CLOSED: -/* -CLOSED: - discard all data. - !RST ? - ACK ? - - exit - : - - exit - : - discard packet - exit -*/ - - if (!(tcp_hdr_flags & THF_RST)) - { - create_RST(tcp_conn, ip_hdr, tcp_hdr, data_len); - tcp_conn_write(tcp_conn, 1); - } - break; - case TCS_LISTEN: -/* -LISTEN: - RST ? - discard packet - exit - ACK ? - - exit - SYN ? - BUG: no security check - RCV.NXT= SEG.SEQ+1 - IRS= SEG.SEQ - ISS should already be selected - - SND.NXT=ISS+1 - SND.UNA=ISS - state= SYN-RECEIVED - exit - : - shouldnot occur - discard packet - exit -*/ - if (tcp_hdr_flags & THF_RST) - break; - if (tcp_hdr_flags & THF_ACK) - { - create_RST (tcp_conn, ip_hdr, tcp_hdr, data_len); - tcp_conn_write(tcp_conn, 1); - break; - } - if (tcp_hdr_flags & THF_SYN) - { - tcp_extract_ipopt(tcp_conn, ip_hdr); - tcp_extract_tcpopt(tcp_conn, tcp_hdr, &mss); - mtu= mss+IP_TCP_MIN_HDR_SIZE; - if (mtu < IP_MIN_MTU) - { - /* No or unrealistic mss, use default MTU */ - mtu= IP_DEF_MTU; - } - if (mtu < tcp_conn->tc_max_mtu) - { - tcp_conn->tc_max_mtu= mtu; - tcp_conn->tc_mtu= mtu; - DBLOCK(1, printf( - "tcp[%d]: conn[%d]: mtu = %d\n", - tcp_conn->tc_port-tcp_port_table, - tcp_conn-tcp_conn_table, - mtu);); - } - - tcp_conn->tc_RCV_LO= seg_seq+1; - tcp_conn->tc_RCV_NXT= seg_seq+1; - tcp_conn->tc_RCV_HI= tcp_conn->tc_RCV_LO+ - tcp_conn->tc_rcv_wnd; - tcp_conn->tc_RCV_UP= seg_seq; - tcp_conn->tc_IRS= seg_seq; - tcp_conn->tc_SND_UNA= tcp_conn->tc_ISS; - tcp_conn->tc_SND_TRM= tcp_conn->tc_ISS; - tcp_conn->tc_SND_NXT= tcp_conn->tc_ISS+1; - tcp_conn->tc_SND_UP= tcp_conn->tc_ISS-1; - tcp_conn->tc_SND_PSH= tcp_conn->tc_ISS-1; - tcp_conn->tc_state= TCS_SYN_RECEIVED; - tcp_conn->tc_stt= 0; - assert (tcp_check_conn(tcp_conn)); - tcp_conn->tc_locaddr= ip_hdr->ih_dst; - tcp_conn->tc_locport= tcp_hdr->th_dstport; - tcp_conn->tc_remaddr= ip_hdr->ih_src; - tcp_conn->tc_remport= tcp_hdr->th_srcport; - tcp_conn_write(tcp_conn, 1); - - DIFBLOCK(0x10, seg_seq == 0, - printf("warning got 0 IRS from "); - writeIpAddr(tcp_conn->tc_remaddr); - printf("\n")); - - /* Start the timer (if necessary) */ - tcp_set_send_timer(tcp_conn); - - break; - } - /* do nothing */ - break; - case TCS_SYN_SENT: -/* -SYN-SENT: - ACK ? - SEG.ACK <= ISS || SEG.ACK > SND.NXT ? - RST ? - discard packet - exit - : - - exit - SND.UNA <= SEG.ACK && SEG.ACK <= SND.NXT ? - ACK is acceptable - : - ACK is !acceptable - : - ACK is !acceptable - RST ? - ACK acceptable ? - discard segment - state= CLOSED - error "connection refused" - exit - : - discard packet - exit - BUG: no security check - SYN ? - IRS= SEG.SEQ - RCV.NXT= IRS+1 - ACK ? - SND.UNA= SEG.ACK - SND.UNA > ISS ? - state= ESTABLISHED - - process ev. URG and text - exit - : - state= SYN-RECEIVED - SND.WND= SEG.WND - SND.WL1= SEG.SEQ - SND.WL2= SEG.ACK - - exit - : - discard segment - exit -*/ - if (tcp_hdr_flags & THF_ACK) - { - if (tcp_LEmod4G(seg_ack, tcp_conn->tc_ISS) || - tcp_Gmod4G(seg_ack, tcp_conn->tc_SND_NXT)) { - if (tcp_hdr_flags & THF_RST) - break; - else - { - /* HACK: force sending a RST, - * normally, RSTs are not send - * if the segment is an ACK. - */ - create_RST (tcp_conn, ip_hdr, - tcp_hdr, data_len+1); - tcp_conn_write(tcp_conn, 1); - break; - } - } - acceptable_ACK= (tcp_LEmod4G(tcp_conn->tc_SND_UNA, - seg_ack) && tcp_LEmod4G(seg_ack, - tcp_conn->tc_SND_NXT)); - } - else - acceptable_ACK= FALSE; - if (tcp_hdr_flags & THF_RST) - { - if (acceptable_ACK) - { - DBLOCK(1, printf( - "calling tcp_close_connection\n")); - - tcp_close_connection(tcp_conn, - ECONNREFUSED); - } - break; - } - if (tcp_hdr_flags & THF_SYN) - { - tcp_extract_ipopt(tcp_conn, ip_hdr); - tcp_extract_tcpopt(tcp_conn, tcp_hdr, &mss); - mtu= mss+IP_TCP_MIN_HDR_SIZE; - if (mtu < IP_MIN_MTU) - { - /* No or unrealistic mss, use default MTU */ - mtu= IP_DEF_MTU; - } - if (mtu < tcp_conn->tc_max_mtu) - { - tcp_conn->tc_max_mtu= mtu; - tcp_conn->tc_mtu= mtu; - DBLOCK(1, printf( - "tcp[%d]: conn[%d]: mtu = %d\n", - tcp_conn->tc_port-tcp_port_table, - tcp_conn-tcp_conn_table, - mtu);); - } - tcp_conn->tc_RCV_LO= seg_seq+1; - tcp_conn->tc_RCV_NXT= seg_seq+1; - tcp_conn->tc_RCV_HI= tcp_conn->tc_RCV_LO + - tcp_conn->tc_rcv_wnd; - tcp_conn->tc_RCV_UP= seg_seq; - tcp_conn->tc_IRS= seg_seq; - if (tcp_hdr_flags & THF_ACK) - tcp_conn->tc_SND_UNA= seg_ack; - if (tcp_Gmod4G(tcp_conn->tc_SND_UNA, - tcp_conn->tc_ISS)) - { - tcp_conn->tc_state= TCS_ESTABLISHED; - tcp_conn->tc_rt_dead= TCP_DEF_RT_DEAD; - - assert (tcp_check_conn(tcp_conn)); - assert(tcp_conn->tc_connInprogress); - - tcp_restart_connect(tcp_conn); - - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - if (data_len != 0) - { - tcp_frag2conn(tcp_conn, ip_hdr, - tcp_hdr, tcp_data, data_len); - /* tcp_data is already freed */ - return; - } - break; - } - tcp_conn->tc_state= TCS_SYN_RECEIVED; - - assert (tcp_check_conn(tcp_conn)); - - tcp_conn->tc_SND_TRM= tcp_conn->tc_ISS; - tcp_conn_write(tcp_conn, 1); - } - break; - - case TCS_SYN_RECEIVED: -/* -SYN-RECEIVED: - test if segment is acceptable: - - Segment Receive Test - Length Window - 0 0 SEG.SEQ == RCV.NXT - 0 >0 RCV.NXT <= SEG.SEQ && SEG.SEQ < RCV.NXT+RCV.WND - >0 0 not acceptable - >0 >0 (RCV.NXT <= SEG.SEQ && SEG.SEQ < RCV.NXT+RCV.WND) - || (RCV.NXT <= SEG.SEQ+SEG.LEN-1 && - SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND) - for urgent data: use RCV.WND+1 for RCV.WND - - Special: Send RST if SEG.SEQ < IRS or SEG.SEQ > RCV.NXT+64K (and - the packet is not a RST packet itself). -*/ - rcv_hi= tcp_conn->tc_RCV_HI; - if (tcp_hdr_flags & THF_URG) - rcv_hi++; - send_rst= tcp_Lmod4G(seg_seq, tcp_conn->tc_IRS) || - tcp_Gmod4G(seg_seq, tcp_conn->tc_RCV_NXT+0x10000); - close_connection= 0; - - if (!data_len) - { - if (rcv_hi == tcp_conn->tc_RCV_NXT) - segm_acceptable= (seg_seq == rcv_hi); - else - { - assert (tcp_Gmod4G(rcv_hi, - tcp_conn->tc_RCV_NXT)); - segm_acceptable= (tcp_LEmod4G(tcp_conn-> - tc_RCV_NXT, seg_seq) && - tcp_Lmod4G(seg_seq, rcv_hi)); - } - } - else - { - if (tcp_Gmod4G(rcv_hi, tcp_conn->tc_RCV_NXT)) - { - segm_acceptable= (tcp_LEmod4G(tcp_conn-> - tc_RCV_NXT, seg_seq) && - tcp_Lmod4G(seg_seq, rcv_hi)) || - (tcp_LEmod4G(tcp_conn->tc_RCV_NXT, - seg_seq+data_len-1) && - tcp_Lmod4G(seg_seq+data_len-1, - rcv_hi)); - } - else - { - segm_acceptable= FALSE; - } - } -/* - !segment acceptable ? - RST ? - discard packet - exit - : - - exit -*/ - if (!segm_acceptable) - { - if (tcp_hdr_flags & THF_RST) - ; /* do nothing */ - else if (send_rst) - { - create_RST(tcp_conn, ip_hdr, tcp_hdr, - data_len); - tcp_conn_write(tcp_conn, 1); - } - else - { - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - } - break; - } -/* - RST ? - initiated by a LISTEN ? - state= LISTEN - exit - : - state= CLOSED - error "connection refused" - exit -*/ - - if (tcp_hdr_flags & THF_RST) - close_connection= 1; - -/* - SYN in window ? - initiated by a LISTEN ? - state= LISTEN - exit - : - state= CLOSED - error "connection reset" - exit -*/ - if ((tcp_hdr_flags & THF_SYN) && tcp_GEmod4G(seg_seq, - tcp_conn->tc_RCV_NXT)) - { - close_connection= 1; - } - - if (close_connection) - { - if (!tcp_conn->tc_orglisten) - { - tcp_close_connection(tcp_conn, ECONNREFUSED); - break; - } - - connuser= tcp_conn->tc_fd; - assert(connuser); - if (connuser->tf_flags & TFF_LISTENQ) - { - tcp_close_connection (tcp_conn, - ECONNREFUSED); - } - else - { - tcp_conn->tc_connInprogress= 0; - tcp_conn->tc_fd= NULL; - - tcp_close_connection (tcp_conn, - ECONNREFUSED); - - /* Pick a new ISS next time */ - tcp_conn->tc_ISS= 0; - - (void)tcp_su4listen(connuser, tcp_conn, - 0 /* !do_listenq */); - } - break; - } -/* - !ACK ? - discard packet - exit -*/ - if (!(tcp_hdr_flags & THF_ACK)) - break; -/* - SND.UNA < SEG.ACK <= SND.NXT ? - state= ESTABLISHED - : - - exit -*/ - if (tcp_Lmod4G(tcp_conn->tc_SND_UNA, seg_ack) && - tcp_LEmod4G(seg_ack, tcp_conn->tc_SND_NXT)) - { - tcp_conn->tc_state= TCS_ESTABLISHED; - tcp_conn->tc_rt_dead= TCP_DEF_RT_DEAD; - - tcp_release_retrans(tcp_conn, seg_ack, seg_wnd); - - assert (tcp_check_conn(tcp_conn)); - assert(tcp_conn->tc_connInprogress); - - tcp_restart_connect(tcp_conn); - tcp_frag2conn(tcp_conn, ip_hdr, tcp_hdr, tcp_data, - data_len); - /* tcp_data is already freed */ - return; - } - else - { - create_RST (tcp_conn, ip_hdr, tcp_hdr, data_len); - tcp_conn_write(tcp_conn, 1); - break; - } - break; - - case TCS_ESTABLISHED: - case TCS_CLOSING: -/* -ESTABLISHED: -FIN-WAIT-1: -FIN-WAIT-2: -CLOSE-WAIT: -CLOSING: -LAST-ACK: -TIME-WAIT: - test if segment is acceptable: - Segment Receive Test - Length Window - 0 0 SEG.SEQ == RCV.NXT - 0 >0 RCV.NXT <= SEG.SEQ && SEG.SEQ < RCV.NXT+RCV.WND - >0 0 not acceptable - >0 >0 (RCV.NXT <= SEG.SEQ && SEG.SEQ < RCV.NXT+RCV.WND) - || (RCV.NXT <= SEG.SEQ+SEG.LEN-1 && - SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND) - for urgent data: use RCV.WND+1 for RCV.WND -*/ - rcv_hi= tcp_conn->tc_RCV_HI; - if (tcp_hdr_flags & THF_URG) - rcv_hi++; - if (!data_len) - { - if (rcv_hi == tcp_conn->tc_RCV_NXT) - segm_acceptable= (seg_seq == rcv_hi); - else - { - assert (tcp_Gmod4G(rcv_hi, - tcp_conn->tc_RCV_NXT)); - segm_acceptable= (tcp_LEmod4G(tcp_conn-> - tc_RCV_NXT, seg_seq) && - tcp_Lmod4G(seg_seq, rcv_hi)); - } - } - else - { - if (tcp_Gmod4G(rcv_hi, tcp_conn->tc_RCV_NXT)) - { - segm_acceptable= (tcp_LEmod4G(tcp_conn-> - tc_RCV_NXT, seg_seq) && - tcp_Lmod4G(seg_seq, rcv_hi)) || - (tcp_LEmod4G(tcp_conn->tc_RCV_NXT, - seg_seq+data_len-1) && - tcp_Lmod4G(seg_seq+data_len-1, - rcv_hi)); - } - else - { - segm_acceptable= FALSE; - } - } -/* - !segment acceptable ? - RST ? - discard packet - exit - : - - exit -*/ - if (!segm_acceptable) - { - if (!(tcp_hdr_flags & THF_RST)) - { - DBLOCK(0x20, - printf("segment is not acceptable\n"); - printf("\t"); - tcp_print_pack(ip_hdr, tcp_hdr); - printf("\n\t"); - tcp_print_conn(tcp_conn); - printf("\n")); - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - - /* Sometimes, a retransmission sets the PSH - * flag (Solaris 2.4) - */ - if (tcp_conn->tc_rcvd_data != NULL && - (tcp_hdr_flags & THF_PSH)) - { - tcp_conn->tc_flags |= TCF_RCV_PUSH; - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & - TFF_READ_IP)) - { - tcp_fd_read(tcp_conn, 1); - } - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & - TFF_SEL_READ)) - { - tcp_rsel_read(tcp_conn); - } - } - } - break; - } -/* - RST ? - state == CLOSING || state == LAST-ACK || - state == TIME-WAIT ? - state= CLOSED - exit - : - state= CLOSED - error "connection reset" - exit -*/ - if (tcp_hdr_flags & THF_RST) - { - if ((tcp_conn->tc_flags & - (TCF_FIN_SENT|TCF_FIN_RECV)) == - (TCF_FIN_SENT|TCF_FIN_RECV) && - tcp_conn->tc_send_data == NULL) - { - /* Clean shutdown, but the other side - * doesn't want to ACK our FIN. - */ - tcp_close_connection (tcp_conn, 0); - } - else - tcp_close_connection(tcp_conn, ECONNRESET); - break; - } -/* - SYN in window ? - state= CLOSED - error "connection reset" - exit -*/ - if ((tcp_hdr_flags & THF_SYN) && tcp_GEmod4G(seg_seq, - tcp_conn->tc_RCV_NXT)) - { - tcp_close_connection(tcp_conn, ECONNRESET); - break; - } -/* - !ACK ? - discard packet - exit -*/ - if (!(tcp_hdr_flags & THF_ACK)) - break; - -/* - SND.UNA < SEG.ACK <= SND.NXT ? - SND.UNA= SEG.ACK - reply "send ok" - SND.WL1 < SEG.SEQ || (SND.WL1 == SEG.SEQ && - SND.WL2 <= SEG.ACK ? - SND.WND= SEG.WND - SND.Wl1= SEG.SEQ - SND.WL2= SEG.ACK - SEG.ACK <= SND.UNA ? - ignore ACK - SEG.ACK > SND.NXT ? - - discard packet - exit -*/ - - /* Always reset the send timer after a valid ack is - * received. The assumption is that either the ack really - * acknowledges some data (normal case), contains a zero - * window, or the remote host has another reason not - * to accept any data. In all cases, the remote host is - * alive, so the connection should stay alive too. - * Do not reset stt if the state is CLOSING, i.e. if - * the user closed the connection and we still have - * some data to deliver. We don't want a zero window - * to keep us from closing the connection. - */ - if (tcp_conn->tc_state != TCS_CLOSING) - tcp_conn->tc_stt= 0; - - snd_una= tcp_conn->tc_SND_UNA; - snd_nxt= tcp_conn->tc_SND_NXT; - if (seg_ack == snd_una) - { - - if (tcp_Gmod4G(snd_nxt, snd_una)) - { - /* Duplicate ACK */ - if (++tcp_conn->tc_snd_dack == - TCP_DACK_RETRANS) - { - tcp_fast_retrans(tcp_conn); - } - } - - /* This ACK doesn't acknowledge any new data, this - * is a likely situation if we are only receiving - * data. We only update the window if we are - * actually sending or if we currently have a - * zero window. - */ - if (tcp_conn->tc_snd_cwnd == snd_una && - seg_wnd != 0) - { - DBLOCK(2, printf("zero window opened\n")); - /* The other side opened up its receive - * window. */ - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - if (seg_wnd > 2*mss) - seg_wnd= 2*mss; - tcp_conn->tc_snd_cwnd= snd_una+seg_wnd; - tcp_conn_write(tcp_conn, 1); - } - if (seg_wnd == 0) - { - tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_TRM= - snd_una; - } - } - else if (tcp_Lmod4G(snd_una, seg_ack) && - tcp_LEmod4G(seg_ack, snd_nxt)) - { - tcp_release_retrans(tcp_conn, seg_ack, seg_wnd); - if (tcp_conn->tc_state == TCS_CLOSED) - break; - } - else if (tcp_Gmod4G(seg_ack, - snd_nxt)) - { - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - DBLOCK(1, printf( - "got an ack of something I haven't send\n"); - printf( "seg_ack= %u, SND_NXT= %u\n", - seg_ack, snd_nxt)); - break; - } - -/* - process data... -*/ - tcp_extract_ipopt(tcp_conn, ip_hdr); - tcp_extract_tcpopt(tcp_conn, tcp_hdr, &mss); - - if (data_len) - { - if (tcp_LEmod4G(seg_seq, tcp_conn->tc_RCV_NXT)) - { - process_data (tcp_conn, tcp_hdr, - tcp_data, data_len); - } - else - { - process_advanced_data (tcp_conn, - tcp_hdr, tcp_data, data_len); - } - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - - /* Don't process a FIN if we got new data */ - break; - } -/* - FIN ? - reply pending receives - advace RCV.NXT over the FIN - - - state == ESTABLISHED ? - state= CLOSE-WAIT - state == FIN-WAIT-1 ? - state= CLOSING - state == FIN-WAIT-2 ? - state= TIME-WAIT - state == TIME-WAIT ? - restart the TIME-WAIT timer - exit -*/ - if ((tcp_hdr_flags & THF_FIN) && tcp_LEmod4G(seg_seq, - tcp_conn->tc_RCV_NXT)) - { - if (!(tcp_conn->tc_flags & TCF_FIN_RECV) && - tcp_Lmod4G(tcp_conn->tc_RCV_NXT, - tcp_conn->tc_RCV_HI)) - { - tcp_conn->tc_RCV_NXT++; - tcp_conn->tc_flags |= TCF_FIN_RECV; - } - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & TFF_READ_IP)) - { - tcp_fd_read(tcp_conn, 1); - } - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & TFF_SEL_READ)) - { - tcp_rsel_read(tcp_conn); - } - } - break; - default: - printf("tcp_frag2conn: unknown state "); - tcp_print_state(tcp_conn); - break; - } - if (tcp_data != NULL) - bf_afree(tcp_data); -} - - -static void -process_data(tcp_conn, tcp_hdr, tcp_data, data_len) -tcp_conn_t *tcp_conn; -tcp_hdr_t *tcp_hdr; -acc_t *tcp_data; -int data_len; -{ - u32_t lo_seq, hi_seq, urg_seq, seq_nr, adv_seq, nxt; - u32_t urgptr; - int tcp_hdr_flags; - unsigned int offset; - acc_t *tmp_data, *rcvd_data, *adv_data; - int len_diff; - - assert(tcp_conn->tc_busy); - - /* Note, tcp_data will be freed by the caller. */ - assert (!(tcp_hdr->th_flags & THF_SYN)); - - seq_nr= ntohl(tcp_hdr->th_seq_nr); - urgptr= ntohs(tcp_hdr->th_urgptr); - - tcp_data->acc_linkC++; - - lo_seq= seq_nr; - tcp_hdr_flags= tcp_hdr->th_flags & TH_FLAGS_MASK; - - if (tcp_Lmod4G(lo_seq, tcp_conn->tc_RCV_NXT)) - { - DBLOCK(0x10, - printf("segment is a retransmission\n")); - offset= tcp_conn->tc_RCV_NXT-lo_seq; - tcp_data= bf_delhead(tcp_data, offset); - lo_seq += offset; - data_len -= offset; - if (tcp_hdr_flags & THF_URG) - { - printf("process_data: updating urgent pointer\n"); - if (urgptr >= offset) - urgptr -= offset; - else - tcp_hdr_flags &= ~THF_URG; - } - } - assert (lo_seq == tcp_conn->tc_RCV_NXT); - - if (tcp_hdr_flags & THF_URG) - { - if (!(tcp_conn->tc_flags & TCF_BSD_URG)) - { - /* Update urgent pointer to point past the urgent - * data - */ - urgptr++; - } - if (urgptr == 0) - tcp_hdr_flags &= ~THF_URG; - } - - if (tcp_hdr_flags & THF_URG) - { - if (urgptr > data_len) - urgptr= data_len; - urg_seq= lo_seq+urgptr; - - if (tcp_GEmod4G(urg_seq, tcp_conn->tc_RCV_HI)) - urg_seq= tcp_conn->tc_RCV_HI; - if (tcp_conn->tc_flags & TCF_BSD_URG) - { - if (tcp_Gmod4G(tcp_conn->tc_RCV_NXT, - tcp_conn->tc_RCV_LO)) - { - DBLOCK(1, printf( - "ignoring urgent data\n")); - - bf_afree(tcp_data); - /* Should set advertised window to - * zero */ - - /* Flush */ - tcp_conn->tc_flags |= TCF_RCV_PUSH; - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & - TFF_READ_IP)) - { - tcp_fd_read(tcp_conn, 1); - } - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & - TFF_SEL_READ)) - { - tcp_rsel_read(tcp_conn); - } - return; - } - } - if (tcp_Gmod4G(urg_seq, tcp_conn->tc_RCV_UP)) - tcp_conn->tc_RCV_UP= urg_seq; -#if 0 - if (urgptr < data_len) - { - data_len= urgptr; - tmp_data= bf_cut(tcp_data, 0, data_len); - bf_afree(tcp_data); - tcp_data= tmp_data; - tcp_hdr_flags &= ~THF_FIN; - } -#endif - tcp_conn->tc_flags |= TCF_RCV_PUSH; - } - else - { - /* Normal data. */ - } - - if (tcp_hdr_flags & THF_PSH) - { - tcp_conn->tc_flags |= TCF_RCV_PUSH; - } - - hi_seq= lo_seq+data_len; - if (tcp_Gmod4G(hi_seq, tcp_conn->tc_RCV_HI)) - { - data_len= tcp_conn->tc_RCV_HI-lo_seq; - tmp_data= bf_cut(tcp_data, 0, data_len); - bf_afree(tcp_data); - tcp_data= tmp_data; - hi_seq= lo_seq+data_len; - tcp_hdr_flags &= ~THF_FIN; - } - assert (tcp_LEmod4G (hi_seq, tcp_conn->tc_RCV_HI)); - - rcvd_data= tcp_conn->tc_rcvd_data; - tcp_conn->tc_rcvd_data= 0; - tmp_data= bf_append(rcvd_data, tcp_data); - tcp_conn->tc_rcvd_data= tmp_data; - tcp_conn->tc_RCV_NXT= hi_seq; - - if ((tcp_hdr_flags & THF_FIN) && - tcp_Lmod4G(tcp_conn->tc_RCV_NXT, tcp_conn->tc_RCV_HI) && - !(tcp_conn->tc_flags & TCF_FIN_RECV)) - { - tcp_conn->tc_RCV_NXT++; - tcp_conn->tc_flags |= TCF_FIN_RECV; - } - - if (tcp_conn->tc_fd && (tcp_conn->tc_fd->tf_flags & TFF_READ_IP)) - tcp_fd_read(tcp_conn, 1); - if (tcp_conn->tc_fd && (tcp_conn->tc_fd->tf_flags & TFF_SEL_READ)) - tcp_rsel_read(tcp_conn); - - DIFBLOCK(2, (tcp_conn->tc_RCV_NXT == tcp_conn->tc_RCV_HI), - printf("conn[[%d] full receive buffer\n", - tcp_conn-tcp_conn_table)); - - if (tcp_conn->tc_adv_data == NULL) - return; - if (tcp_hdr_flags & THF_FIN) - { - printf("conn[%d]: advanced data after FIN\n", - tcp_conn-tcp_conn_table); - tcp_data= tcp_conn->tc_adv_data; - tcp_conn->tc_adv_data= NULL; - bf_afree(tcp_data); - return; - } - - lo_seq= tcp_conn->tc_adv_seq; - if (tcp_Gmod4G(lo_seq, tcp_conn->tc_RCV_NXT)) - return; /* Not yet */ - - tcp_data= tcp_conn->tc_adv_data; - tcp_conn->tc_adv_data= NULL; - - data_len= bf_bufsize(tcp_data); - if (tcp_Lmod4G(lo_seq, tcp_conn->tc_RCV_NXT)) - { - offset= tcp_conn->tc_RCV_NXT-lo_seq; - if (offset >= data_len) - { - bf_afree(tcp_data); - return; - } - tcp_data= bf_delhead(tcp_data, offset); - lo_seq += offset; - data_len -= offset; - } - assert (lo_seq == tcp_conn->tc_RCV_NXT); - - hi_seq= lo_seq+data_len; - assert (tcp_LEmod4G (hi_seq, tcp_conn->tc_RCV_HI)); - - rcvd_data= tcp_conn->tc_rcvd_data; - tcp_conn->tc_rcvd_data= 0; - tmp_data= bf_append(rcvd_data, tcp_data); - tcp_conn->tc_rcvd_data= tmp_data; - tcp_conn->tc_RCV_NXT= hi_seq; - - assert (tcp_conn->tc_RCV_LO + bf_bufsize(tcp_conn->tc_rcvd_data) == - tcp_conn->tc_RCV_NXT || - (tcp_print_conn(tcp_conn), printf("\n"), 0)); - - if (tcp_conn->tc_fd && (tcp_conn->tc_fd->tf_flags & TFF_READ_IP)) - tcp_fd_read(tcp_conn, 1); - if (tcp_conn->tc_fd && (tcp_conn->tc_fd->tf_flags & TFF_SEL_READ)) - tcp_rsel_read(tcp_conn); - - adv_data= tcp_conn->tc_adv_data; - if (adv_data != NULL) - { - /* Try to use advanced data. */ - adv_seq= tcp_conn->tc_adv_seq; - nxt= tcp_conn->tc_RCV_NXT; - - if (tcp_Gmod4G(adv_seq, nxt)) - return; /* not yet */ - - tcp_conn->tc_adv_data= NULL; - data_len= bf_bufsize(adv_data); - - if (tcp_Lmod4G(adv_seq, nxt)) - { - if (tcp_LEmod4G(adv_seq+data_len, nxt)) - { - /* Data is not needed anymore. */ - bf_afree(adv_data); - return; - } - - len_diff= nxt-adv_seq; - adv_data= bf_delhead(adv_data, len_diff); - data_len -= len_diff; - } - - DBLOCK(1, printf("using advanced data\n")); - - /* Append data to the input buffer */ - if (tcp_conn->tc_rcvd_data == NULL) - { - tcp_conn->tc_rcvd_data= adv_data; - } - else - { - tcp_conn->tc_rcvd_data= - bf_append(tcp_conn->tc_rcvd_data, adv_data); - } - tcp_conn->tc_SND_NXT += data_len; - assert(tcp_check_conn(tcp_conn)); - - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & TFF_READ_IP)) - { - tcp_fd_read(tcp_conn, 1); - } - if (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & TFF_SEL_READ)) - { - tcp_rsel_read(tcp_conn); - } - } -} - -static void process_advanced_data(tcp_conn, tcp_hdr, tcp_data, data_len) -tcp_conn_t *tcp_conn; -tcp_hdr_t *tcp_hdr; -acc_t *tcp_data; -int data_len; -{ - u32_t seq, adv_seq; - acc_t *adv_data; - - assert(tcp_conn->tc_busy); - - /* Note, tcp_data will be freed by the caller. */ - - /* Always send an ACK, this allows the sender to do a fast - * retransmit. - */ - tcp_conn->tc_flags |= TCF_SEND_ACK; - tcp_conn_write(tcp_conn, 1); - - if (tcp_hdr->th_flags & THF_URG) - return; /* Urgent data is to complicated */ - - if (tcp_hdr->th_flags & THF_PSH) - tcp_conn->tc_flags |= TCF_RCV_PUSH; - seq= ntohl(tcp_hdr->th_seq_nr); - - /* Make sure that the packet doesn't fall outside of the window - * we offered. - */ - if (tcp_Gmod4G(seq+data_len, tcp_conn->tc_RCV_HI)) - return; - - adv_data= tcp_conn->tc_adv_data; - adv_seq= tcp_conn->tc_adv_seq; - tcp_conn->tc_adv_data= NULL; - - tcp_data->acc_linkC++; - if (adv_data == NULL) - { - adv_seq= seq; - adv_data= tcp_data; - } - else if (seq + data_len == adv_seq) - { - /* New data fits right before exiting data. */ - adv_data= bf_append(tcp_data, adv_data); - adv_seq= seq; - } - else if (adv_seq + bf_bufsize(adv_data) == seq) - { - /* New data fits right after exiting data. */ - adv_data= bf_append(adv_data, tcp_data); - } - else - { - /* New data doesn't fit. */ - bf_afree(tcp_data); - } - tcp_conn->tc_adv_data= adv_data; - tcp_conn->tc_adv_seq= adv_seq; -} - -static void create_RST(tcp_conn, ip_hdr, tcp_hdr, data_len) -tcp_conn_t *tcp_conn; -ip_hdr_t *ip_hdr; -tcp_hdr_t *tcp_hdr; -int data_len; -{ - acc_t *tmp_ipopt, *tmp_tcpopt, *tcp_pack; - acc_t *RST_acc; - ip_hdr_t *RST_ip_hdr; - tcp_hdr_t *RST_tcp_hdr; - size_t pack_size, ip_hdr_len, mss; - - DBLOCK(0x10, printf("in create_RST, bad pack is:\n"); - tcp_print_pack(ip_hdr, tcp_hdr); tcp_print_state(tcp_conn); - printf("\n")); - - assert(tcp_conn->tc_busy); - - /* Only send RST packets in reponse to actual data (or SYN, FIN) - * this solves a problem during connection shutdown. The problem - * is the follow senario: a senders closes the connection instead - * of doing a shutdown and waiting for the receiver to shutdown. - * The receiver is slow in processing the last data. After the - * sender has completely closed the connection, the receiver - * sends a window update which triggers the sender to send a - * RST. The receiver closes the connection in reponse to the RST. - */ - if ((tcp_hdr->th_flags & (THF_FIN|THF_SYN)) == 0 && - data_len == 0) - { -#if DEBUG - { printf("tcp_recv`create_RST: no data, no RST\n"); } -#endif - return; - } - - tmp_ipopt= tcp_conn->tc_remipopt; - if (tmp_ipopt) - tmp_ipopt->acc_linkC++; - tmp_tcpopt= tcp_conn->tc_tcpopt; - if (tmp_tcpopt) - tmp_tcpopt->acc_linkC++; - - tcp_extract_ipopt (tcp_conn, ip_hdr); - tcp_extract_tcpopt (tcp_conn, tcp_hdr, &mss); - - RST_acc= tcp_make_header (tcp_conn, &RST_ip_hdr, &RST_tcp_hdr, - (acc_t *)0); - - if (tcp_conn->tc_remipopt) - bf_afree(tcp_conn->tc_remipopt); - tcp_conn->tc_remipopt= tmp_ipopt; - if (tcp_conn->tc_tcpopt) - bf_afree(tcp_conn->tc_tcpopt); - tcp_conn->tc_tcpopt= tmp_tcpopt; - - RST_ip_hdr->ih_src= ip_hdr->ih_dst; - RST_ip_hdr->ih_dst= ip_hdr->ih_src; - - RST_tcp_hdr->th_srcport= tcp_hdr->th_dstport; - RST_tcp_hdr->th_dstport= tcp_hdr->th_srcport; - if (tcp_hdr->th_flags & THF_ACK) - { - RST_tcp_hdr->th_seq_nr= tcp_hdr->th_ack_nr; - RST_tcp_hdr->th_flags= THF_RST; - } - else - { - RST_tcp_hdr->th_seq_nr= 0; - RST_tcp_hdr->th_ack_nr= - htonl( - ntohl(tcp_hdr->th_seq_nr)+ - data_len + - (tcp_hdr->th_flags & THF_SYN ? 1 : 0) + - (tcp_hdr->th_flags & THF_FIN ? 1 : 0)); - RST_tcp_hdr->th_flags= THF_RST|THF_ACK; - } - - pack_size= bf_bufsize(RST_acc); - RST_ip_hdr->ih_length= htons(pack_size); - RST_tcp_hdr->th_window= htons(tcp_conn->tc_rcv_wnd); - RST_tcp_hdr->th_chksum= 0; - - RST_acc->acc_linkC++; - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - tcp_pack= bf_delhead(RST_acc, ip_hdr_len); - RST_tcp_hdr->th_chksum= ~tcp_pack_oneCsum (RST_ip_hdr, tcp_pack); - bf_afree(tcp_pack); - - DBLOCK(2, tcp_print_pack(ip_hdr, tcp_hdr); printf("\n"); - tcp_print_pack(RST_ip_hdr, RST_tcp_hdr); printf("\n")); - - if (tcp_conn->tc_frag2send) - bf_afree(tcp_conn->tc_frag2send); - tcp_conn->tc_frag2send= RST_acc; - tcp_conn_write(tcp_conn, 1); -} - -void -tcp_fd_read(tcp_conn, enq) -tcp_conn_t *tcp_conn; -int enq; /* Enqueue writes. */ -{ - tcp_fd_t *tcp_fd; - size_t data_size, read_size; - acc_t *data; - int fin_recv, urg, push, result; - i32_t old_window, new_window; - u16_t mss; - - assert(tcp_conn->tc_busy); - - tcp_fd= tcp_conn->tc_fd; - - assert (tcp_fd->tf_flags & TFF_READ_IP); - if (tcp_conn->tc_state == TCS_CLOSED) - { - if (tcp_fd->tf_read_offset) - tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset); - else - tcp_reply_read (tcp_fd, tcp_conn->tc_error); - return; - } - - urg= tcp_Gmod4G(tcp_conn->tc_RCV_UP, tcp_conn->tc_RCV_LO); - push= (tcp_conn->tc_flags & TCF_RCV_PUSH); - fin_recv= (tcp_conn->tc_flags & TCF_FIN_RECV); - - data_size= tcp_conn->tc_RCV_NXT-tcp_conn->tc_RCV_LO; - if (fin_recv) - data_size--; - if (urg) - { -#if DEBUG - printf("tcp_fd_read: RCV_UP = 0x%x, RCV_LO = 0x%x\n", - tcp_conn->tc_RCV_UP, tcp_conn->tc_RCV_LO); -#endif - read_size= tcp_conn->tc_RCV_UP-tcp_conn->tc_RCV_LO; - } - else - read_size= data_size; - - if (read_size >= tcp_fd->tf_read_count) - read_size= tcp_fd->tf_read_count; - else if (!push && !fin_recv && !urg && - data_size < TCP_MIN_RCV_WND_SIZE) - { - /* Defer the copy out until later. */ - return; - } - else if (data_size == 0 && !fin_recv) - { - /* No data, and no end of file. */ - return; - } - - if (read_size) - { - if (urg && !(tcp_fd->tf_flags & TFF_RECV_URG)) - { - if (tcp_fd->tf_read_offset) - { - tcp_reply_read (tcp_fd, - tcp_fd->tf_read_offset); - } - else - { - tcp_reply_read (tcp_fd, EURG); - } - return; - } - else if (!urg && (tcp_fd->tf_flags & TFF_RECV_URG)) - { - if (tcp_fd->tf_read_offset) - { - tcp_reply_read (tcp_fd, - tcp_fd->tf_read_offset); - } - else - { - tcp_reply_read(tcp_fd, ENOURG); - } - return; - } - - if (read_size == data_size) - { - data= tcp_conn->tc_rcvd_data; - data->acc_linkC++; - } - else - { - data= bf_cut(tcp_conn->tc_rcvd_data, 0, read_size); - } - result= (*tcp_fd->tf_put_userdata) (tcp_fd->tf_srfd, - tcp_fd->tf_read_offset, data, FALSE); - if (result<0) - { - if (tcp_fd->tf_read_offset) - tcp_reply_read(tcp_fd, tcp_fd-> - tf_read_offset); - else - tcp_reply_read(tcp_fd, result); - return; - } - tcp_fd->tf_read_offset += read_size; - tcp_fd->tf_read_count -= read_size; - - if (data_size == read_size) - { - bf_afree(tcp_conn->tc_rcvd_data); - tcp_conn->tc_rcvd_data= 0; - } - else - { - tcp_conn->tc_rcvd_data= - bf_delhead(tcp_conn->tc_rcvd_data, - read_size); - } - tcp_conn->tc_RCV_LO += read_size; - data_size -= read_size; - } - - /* Update IRS and often RCV_UP every 0.5GB */ - if (tcp_conn->tc_RCV_LO - tcp_conn->tc_IRS > 0x40000000) - { - tcp_conn->tc_IRS += 0x20000000; - DBLOCK(1, printf("tcp_fd_read: updating IRS to 0x%lx\n", - (unsigned long)tcp_conn->tc_IRS);); - if (tcp_Lmod4G(tcp_conn->tc_RCV_UP, tcp_conn->tc_IRS)) - { - tcp_conn->tc_RCV_UP= tcp_conn->tc_IRS; - DBLOCK(1, printf( - "tcp_fd_read: updating RCV_UP to 0x%lx\n", - (unsigned long)tcp_conn->tc_RCV_UP);); - } - DBLOCK(1, printf("tcp_fd_read: RCP_LO = 0x%lx\n", - (unsigned long)tcp_conn->tc_RCV_LO);); - } - - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - if (tcp_conn->tc_RCV_HI-tcp_conn->tc_RCV_LO <= - tcp_conn->tc_rcv_wnd-mss) - { - old_window= tcp_conn->tc_RCV_HI-tcp_conn->tc_RCV_NXT; - tcp_conn->tc_RCV_HI= tcp_conn->tc_RCV_LO + - tcp_conn->tc_rcv_wnd; - new_window= tcp_conn->tc_RCV_HI-tcp_conn->tc_RCV_NXT; - assert(old_window >=0 && new_window >= old_window); - if (old_window < mss && new_window >= mss) - { - tcp_conn->tc_flags |= TCF_SEND_ACK; - DBLOCK(2, printf("opening window\n")); - tcp_conn_write(tcp_conn, 1); - } - } - if (tcp_conn->tc_rcvd_data == NULL && - tcp_conn->tc_adv_data == NULL) - { - /* Out of data, clear PUSH flag and reply to a read. */ - tcp_conn->tc_flags &= ~TCF_RCV_PUSH; - } - if (fin_recv || urg || tcp_fd->tf_read_offset || - !tcp_fd->tf_read_count) - { - tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset); - return; - } -} - -unsigned -tcp_sel_read(tcp_conn) -tcp_conn_t *tcp_conn; -{ - size_t data_size; - int fin_recv, urg, push; - - if (tcp_conn->tc_state == TCS_CLOSED) - return 1; - - fin_recv= (tcp_conn->tc_flags & TCF_FIN_RECV); - if (fin_recv) - return 1; - - data_size= tcp_conn->tc_RCV_NXT-tcp_conn->tc_RCV_LO; - if (data_size == 0) - { - /* No data, and no end of file. */ - return 0; - } - - urg= tcp_Gmod4G(tcp_conn->tc_RCV_UP, tcp_conn->tc_RCV_LO); - push= (tcp_conn->tc_flags & TCF_RCV_PUSH); - - if (!push && !urg && data_size < TCP_MIN_RCV_WND_SIZE) - { - /* Defer until later. */ - return 0; - } - - return 1; -} - -void -tcp_rsel_read(tcp_conn) -tcp_conn_t *tcp_conn; -{ - tcp_fd_t *tcp_fd; - - if (tcp_sel_read(tcp_conn) == 0) - return; - - tcp_fd= tcp_conn->tc_fd; - tcp_fd->tf_flags &= ~TFF_SEL_READ; - if (tcp_fd->tf_select_res) - tcp_fd->tf_select_res(tcp_fd->tf_srfd, SR_SELECT_READ); - else - printf("tcp_rsel_read: no select_res\n"); -} - -void tcp_bytesavailable(tcp_fd, bytesp) -tcp_fd_t *tcp_fd; -int *bytesp; -{ - tcp_conn_t *tcp_conn; - size_t data_size; - int fin_recv, urg; - - *bytesp= 0; /* The default is that nothing is available */ - - if (!(tcp_fd->tf_flags & TFF_CONNECTED)) - return; - tcp_conn= tcp_fd->tf_conn; - - if (tcp_conn->tc_state == TCS_CLOSED) - return; - - urg= tcp_Gmod4G(tcp_conn->tc_RCV_UP, tcp_conn->tc_RCV_LO); - fin_recv= (tcp_conn->tc_flags & TCF_FIN_RECV); - - data_size= tcp_conn->tc_RCV_NXT-tcp_conn->tc_RCV_LO; - if (fin_recv) - data_size--; - if (urg) - data_size= tcp_conn->tc_RCV_UP-tcp_conn->tc_RCV_LO; - - if (urg && !(tcp_fd->tf_flags & TFF_RECV_URG)) - return; - else if (!urg && (tcp_fd->tf_flags & TFF_RECV_URG)) - return; - - *bytesp= data_size; -} - -/* - * $PchId: tcp_recv.c,v 1.30 2005/06/28 14:21:35 philip Exp $ - */ diff --git a/minix/net/inet/generic/tcp_send.c b/minix/net/inet/generic/tcp_send.c deleted file mode 100644 index 97a90146a..000000000 --- a/minix/net/inet/generic/tcp_send.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* -tcp_send.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "buf.h" -#include "clock.h" -#include "event.h" -#include "type.h" -#include "sr.h" - -#include "assert.h" -#include "io.h" -#include "ip.h" -#include "tcp.h" -#include "tcp_int.h" - -THIS_FILE - -static acc_t *make_pack ARGS(( tcp_conn_t *tcp_conn )); -static void tcp_send_timeout ARGS(( int conn, minix_timer_t *timer )); -static void do_snd_event ARGS(( event_t *ev, ev_arg_t arg )); - -void tcp_conn_write (tcp_conn, enq) -tcp_conn_t *tcp_conn; -int enq; /* Writes need to be enqueued. */ -{ - tcp_port_t *tcp_port; - ev_arg_t snd_arg; - - assert (tcp_conn->tc_flags & TCF_INUSE); - - tcp_port= tcp_conn->tc_port; - if (tcp_conn->tc_flags & TCF_MORE2WRITE) - return; - - /* Do we really have something to send here? */ - if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT && - !(tcp_conn->tc_flags & TCF_SEND_ACK) && - !tcp_conn->tc_frag2send) - { - return; - } - - tcp_conn->tc_flags |= TCF_MORE2WRITE; - tcp_conn->tc_send_link= NULL; - if (!tcp_port->tp_snd_head) - { - tcp_port->tp_snd_head= tcp_conn; - tcp_port->tp_snd_tail= tcp_conn; - if (enq) - { - snd_arg.ev_ptr= tcp_port; - if (!ev_in_queue(&tcp_port->tp_snd_event)) - { - ev_enqueue(&tcp_port->tp_snd_event, - do_snd_event, snd_arg); - } - } - else - tcp_port_write(tcp_port); - } - else - { - tcp_port->tp_snd_tail->tc_send_link= tcp_conn; - tcp_port->tp_snd_tail= tcp_conn; - } -} - -static void do_snd_event(ev, arg) -event_t *ev; -ev_arg_t arg; -{ - tcp_port_t *tcp_port; - - tcp_port= arg.ev_ptr; - - assert(ev == &tcp_port->tp_snd_event); - tcp_port_write(tcp_port); -} - -void tcp_port_write(tcp_port) -tcp_port_t *tcp_port; -{ - tcp_conn_t *tcp_conn; - acc_t *pack2write; - int r; - - assert (!(tcp_port->tp_flags & TPF_WRITE_IP)); - - while(tcp_port->tp_snd_head) - { - tcp_conn= tcp_port->tp_snd_head; - assert(tcp_conn->tc_flags & TCF_MORE2WRITE); - - for(;;) - { - if (tcp_conn->tc_frag2send) - { - pack2write= tcp_conn->tc_frag2send; - tcp_conn->tc_frag2send= 0; - } - else - { - tcp_conn->tc_busy++; - pack2write= make_pack(tcp_conn); - tcp_conn->tc_busy--; - if (!pack2write) - break; - } - r= ip_send(tcp_port->tp_ipfd, pack2write, - bf_bufsize(pack2write)); - if (r != NW_OK) - { - if (r == NW_WOULDBLOCK) - break; - if (r == EPACKSIZE) - { - tcp_mtu_exceeded(tcp_conn); - continue; - } - if (r == EHOSTUNREACH || r == ENETUNREACH || - r == ENETDOWN) - { - tcp_notreach(tcp_conn, r); - continue; - } - if (r == EAFNOSUPPORT) - continue; - } - assert(r == NW_OK || - (printf("ip_send failed, error %d\n", r),0)); - } - - if (pack2write) - { - tcp_port->tp_flags |= TPF_WRITE_IP; - tcp_port->tp_pack= pack2write; - - r= ip_write (tcp_port->tp_ipfd, - bf_bufsize(pack2write)); - if (r == NW_SUSPEND) - { - tcp_port->tp_flags |= TPF_WRITE_SP; - return; - } - assert(r == NW_OK); - tcp_port->tp_flags &= ~TPF_WRITE_IP; - assert(!(tcp_port->tp_flags & - (TPF_WRITE_IP|TPF_WRITE_SP))); - continue; - } - tcp_conn->tc_flags &= ~TCF_MORE2WRITE; - tcp_port->tp_snd_head= tcp_conn->tc_send_link; - - } -} - -static acc_t *make_pack(tcp_conn) -tcp_conn_t *tcp_conn; -{ - acc_t *pack2write, *tmp_pack, *tcp_pack; - tcp_hdr_t *tcp_hdr = NULL; - ip_hdr_t *ip_hdr = NULL; - int tot_hdr_size, ip_hdr_len, no_push, head, more2write; - u32_t seg_seq, seg_lo_data, queue_lo_data, seg_hi, seg_hi_data; - u16_t seg_up, mss; - u8_t seg_flags; - size_t pack_size; - clock_t curr_time, new_dis; - u8_t *optptr; - - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - - assert(tcp_conn->tc_busy); - curr_time= get_time(); - switch (tcp_conn->tc_state) - { - case TCS_CLOSED: - case TCS_LISTEN: - return NULL; - case TCS_SYN_RECEIVED: - case TCS_SYN_SENT: - - if (tcp_conn->tc_SND_TRM == tcp_conn->tc_SND_NXT && - !(tcp_conn->tc_flags & TCF_SEND_ACK)) - { - return 0; - } - - tcp_conn->tc_flags &= ~TCF_SEND_ACK; - - /* Advertise a mss based on the port mtu. The current mtu may - * be lower if the other side sends a smaller mss. - */ - mss= tcp_conn->tc_port->tp_mtu-IP_TCP_MIN_HDR_SIZE; - - /* Include a max segment size option. */ - assert(tcp_conn->tc_tcpopt == NULL); - tcp_conn->tc_tcpopt= bf_memreq(4); - optptr= (u8_t *)ptr2acc_data(tcp_conn->tc_tcpopt); - optptr[0]= TCP_OPT_MSS; - optptr[1]= 4; - optptr[2]= mss >> 8; - optptr[3]= mss & 0xFF; - - pack2write= tcp_make_header(tcp_conn, &ip_hdr, &tcp_hdr, - (acc_t *)0); - - bf_afree(tcp_conn->tc_tcpopt); - tcp_conn->tc_tcpopt= NULL; - - if (!pack2write) - { - DBLOCK(1, printf("connection closed while inuse\n")); - return 0; - } - tot_hdr_size= bf_bufsize(pack2write); - seg_seq= tcp_conn->tc_SND_TRM; - if (tcp_conn->tc_state == TCS_SYN_SENT) - seg_flags= 0; - else - seg_flags= THF_ACK; /* except for TCS_SYN_SENT - * ack is always present */ - - if (seg_seq == tcp_conn->tc_ISS) - { - assert(tcp_conn->tc_transmit_timer.tim_active || - (tcp_print_conn(tcp_conn), printf("\n"), 0)); - seg_flags |= THF_SYN; - tcp_conn->tc_SND_TRM++; - } - - tcp_hdr->th_seq_nr= htonl(seg_seq); - tcp_hdr->th_ack_nr= htonl(tcp_conn->tc_RCV_NXT); - tcp_hdr->th_flags= seg_flags; - tcp_hdr->th_window= htons(mss); - /* Initially we allow one segment */ - - ip_hdr->ih_length= htons(tot_hdr_size); - - pack2write->acc_linkC++; - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - tcp_pack= bf_delhead(pack2write, ip_hdr_len); - tcp_hdr->th_chksum= ~tcp_pack_oneCsum(ip_hdr, tcp_pack); - bf_afree(tcp_pack); - - new_dis= curr_time + 2*HZ*tcp_conn->tc_ttl; - if (new_dis > tcp_conn->tc_senddis) - tcp_conn->tc_senddis= new_dis; - return pack2write; - - case TCS_ESTABLISHED: - case TCS_CLOSING: - seg_seq= tcp_conn->tc_SND_TRM; - - seg_flags= 0; - pack2write= 0; - seg_up= 0; - if (tcp_conn->tc_flags & TCF_SEND_ACK) - { - seg_flags= THF_ACK; - tcp_conn->tc_flags &= ~TCF_SEND_ACK; - - pack2write= tcp_make_header (tcp_conn, &ip_hdr, - &tcp_hdr, (acc_t *)0); - if (!pack2write) - { - return NULL; - } - } - - if (tcp_conn->tc_SND_UNA != tcp_conn->tc_SND_NXT) - { - assert(tcp_LEmod4G(seg_seq, tcp_conn->tc_SND_NXT)); - - if (seg_seq == tcp_conn->tc_snd_cwnd) - { - DBLOCK(2, - printf("no data: window is closed\n")); - goto after_data; - } - - /* Assert that our SYN has been ACKed. */ - assert(tcp_conn->tc_SND_UNA != tcp_conn->tc_ISS); - - seg_lo_data= seg_seq; - queue_lo_data= tcp_conn->tc_SND_UNA; - - seg_hi= tcp_conn->tc_SND_NXT; - seg_hi_data= seg_hi; - if (tcp_conn->tc_flags & TCF_FIN_SENT) - { - if (seg_seq != seg_hi) - seg_flags |= THF_FIN; - if (queue_lo_data == seg_hi_data) - queue_lo_data--; - if (seg_lo_data == seg_hi_data) - seg_lo_data--; - seg_hi_data--; - } - - if (!pack2write) - { - pack2write= tcp_make_header (tcp_conn, - &ip_hdr, &tcp_hdr, (acc_t *)0); - if (!pack2write) - { - return NULL; - } - } - - tot_hdr_size= bf_bufsize(pack2write); - - no_push= (tcp_LEmod4G(tcp_conn->tc_SND_PSH, seg_seq)); - head= (seg_seq == tcp_conn->tc_SND_UNA); - if (no_push) - { - /* Shutdown sets SND_PSH */ - seg_flags &= ~THF_FIN; - if (seg_hi_data-seg_lo_data <= 1) - { - /* Allways keep at least one byte - * for a future push. - */ - DBLOCK(0x20, - printf("no data: no push\n")); - if (head) - { - DBLOCK(0x1, printf( - "no data: setting TCF_NO_PUSH\n")); - tcp_conn->tc_flags |= - TCF_NO_PUSH; - } - goto after_data; - } - seg_hi_data--; - } - - if (tot_hdr_size != IP_TCP_MIN_HDR_SIZE) - { - printf( - "tcp_write`make_pack: tot_hdr_size = %d\n", - tot_hdr_size); - mss= tcp_conn->tc_mtu-tot_hdr_size; - } - if (seg_hi_data - seg_lo_data > mss) - { - /* Truncate to at most one segment */ - seg_hi_data= seg_lo_data + mss; - seg_hi= seg_hi_data; - seg_flags &= ~THF_FIN; - } - - if (no_push && - seg_hi_data-seg_lo_data != mss) - { - DBLOCK(0x20, printf( - "no data: no push for partial segment\n")); - more2write= (tcp_conn->tc_fd && - (tcp_conn->tc_fd->tf_flags & - TFF_WRITE_IP)); - DIFBLOCK(2, more2write, - printf( - "tcp_send`make_pack: more2write -> !TCF_NO_PUSH\n"); - ); - if (head && !more2write) - { - DBLOCK(0x1, printf( - "partial segment: setting TCF_NO_PUSH\n")); - tcp_conn->tc_flags |= TCF_NO_PUSH; - } - goto after_data; - } - - - if (tcp_Gmod4G(seg_hi, tcp_conn->tc_snd_cwnd)) - { - seg_hi_data= tcp_conn->tc_snd_cwnd; - seg_hi= seg_hi_data; - seg_flags &= ~THF_FIN; - } - - if (!head && - seg_hi_data-seg_lo_data < mss) - { - if (tcp_conn->tc_flags & TCF_PUSH_NOW) - { - DBLOCK(0x20, - printf("push: no Nagle\n")); - } - else - { - DBLOCK(0x20, - printf("no data: partial packet\n")); - seg_flags &= ~THF_FIN; - goto after_data; - } - } - - if (seg_hi-seg_seq == 0) - { - DBLOCK(0x20, - printf("no data: no data available\n")); - goto after_data; - } - - if (tcp_GEmod4G(tcp_conn->tc_SND_UP, seg_lo_data)) - { - extern int killer_inet; - - if (tcp_GEmod4G(tcp_conn->tc_SND_UP, - seg_hi_data)) - { - seg_up= seg_hi_data-seg_seq; - } - else - { - seg_up= tcp_conn->tc_SND_UP-seg_seq; - } - seg_flags |= THF_URG; - if (!killer_inet && - (tcp_conn->tc_flags & TCF_BSD_URG) && - seg_up == 0) - { - /* A zero urgent pointer doesn't mean - * anything when BSD semantics are - * used (urgent pointer points to the - * first no urgent byte). The use of - * a zero urgent pointer also crashes - * a Solaris 2.3 kernel. If urgent - * pointer doesn't have BSD semantics - * then an urgent pointer of zero - * simply indicates that there is one - * urgent byte. - */ - seg_flags &= ~THF_URG; - } - } - else - seg_up= 0; - - if (tcp_Gmod4G(tcp_conn->tc_SND_PSH, seg_lo_data) && - tcp_LEmod4G(tcp_conn->tc_SND_PSH, seg_hi_data)) - { - seg_flags |= THF_PSH; - } - - tcp_conn->tc_SND_TRM= seg_hi; - - assert(tcp_conn->tc_transmit_timer.tim_active || - (tcp_print_conn(tcp_conn), printf("\n"), 0)); - if (tcp_conn->tc_rt_seq == 0 && - tcp_Gmod4G(seg_seq, tcp_conn->tc_rt_threshold)) - { - tcp_conn->tc_rt_time= curr_time; - tcp_conn->tc_rt_seq= - tcp_conn->tc_rt_threshold= seg_seq; - } - - if (seg_hi_data-seg_lo_data) - { -#if DEBUG & 0 - assert(tcp_check_conn(tcp_conn)); - assert((seg_hi_data-queue_lo_data <= - bf_bufsize(tcp_conn->tc_send_data) && - seg_lo_data-queue_lo_data <= - bf_bufsize(tcp_conn->tc_send_data) && - seg_hi_data>seg_lo_data)|| - (tcp_print_conn(tcp_conn), - printf( - " seg_hi_data= 0x%x, seg_lo_data= 0x%x, queue_lo_data= 0x%x\n", - seg_hi_data, seg_lo_data, - queue_lo_data), 0)); -#endif - - tmp_pack= pack2write; - while (tmp_pack->acc_next) - tmp_pack= tmp_pack->acc_next; - tmp_pack->acc_next= - bf_cut(tcp_conn->tc_send_data, - (unsigned)(seg_lo_data-queue_lo_data), - (unsigned) (seg_hi_data-seg_lo_data)); - } - seg_flags |= THF_ACK; - } - -after_data: - if (!(seg_flags & THF_ACK)) - { - if (pack2write) - bf_afree(pack2write); - return NULL; - } - - assert( tcp_hdr != NULL ); - assert( ip_hdr != NULL ); - tcp_hdr->th_seq_nr= htonl(seg_seq); - tcp_hdr->th_ack_nr= htonl(tcp_conn->tc_RCV_NXT); - tcp_hdr->th_flags= seg_flags; - tcp_hdr->th_window= htons(tcp_conn->tc_RCV_HI - - tcp_conn->tc_RCV_NXT); - tcp_hdr->th_urgptr= htons(seg_up); - - pack_size= bf_bufsize(pack2write); - ip_hdr->ih_length= htons(pack_size); - - pack2write->acc_linkC++; - ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - tcp_pack= bf_delhead(pack2write, ip_hdr_len); - tcp_hdr->th_chksum= ~tcp_pack_oneCsum(ip_hdr, tcp_pack); - bf_afree(tcp_pack); - - new_dis= curr_time + 2*HZ*tcp_conn->tc_ttl; - if (new_dis > tcp_conn->tc_senddis) - tcp_conn->tc_senddis= new_dis; - - return pack2write; - default: - DBLOCK(1, tcp_print_conn(tcp_conn); printf("\n")); - ip_panic(( "Illegal state" )); - } - assert(0); - return NULL; -} - -/* -tcp_release_retrans -*/ - -void tcp_release_retrans( - tcp_conn_t *tcp_conn, - u32_t seg_ack, - u16_t new_win -) -{ - tcp_fd_t *tcp_fd; - size_t size, offset; - acc_t *pack; - clock_t retrans_time, curr_time, rtt, artt, drtt, srtt; - u32_t queue_lo, queue_hi; - u16_t mss, cthresh, new_cthresh; - unsigned window; - - DBLOCK(0x10, printf("tcp_release_retrans, conn[%d]: ack %lu, win %u\n", - tcp_conn-tcp_conn_table, (unsigned long)seg_ack, new_win);); - - assert(tcp_conn->tc_busy); - assert (tcp_GEmod4G(seg_ack, tcp_conn->tc_SND_UNA)); - assert (tcp_LEmod4G(seg_ack, tcp_conn->tc_SND_NXT)); - - tcp_conn->tc_snd_dack= 0; - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - - curr_time= get_time(); - if (tcp_conn->tc_rt_seq != 0 && - tcp_Gmod4G(seg_ack, tcp_conn->tc_rt_seq)) - { - assert(curr_time >= tcp_conn->tc_rt_time); - retrans_time= curr_time-tcp_conn->tc_rt_time; - rtt= tcp_conn->tc_rtt; - - tcp_conn->tc_rt_seq= 0; - - if (rtt == TCP_RTT_GRAN*CLOCK_GRAN && - retrans_time <= TCP_RTT_GRAN*CLOCK_GRAN) - { - /* Common in fast networks. Nothing to do. */ - } - else - { - srtt= retrans_time * TCP_RTT_SCALE; - - artt= tcp_conn->tc_artt; - artt= ((TCP_RTT_SMOOTH-1)*artt+srtt)/TCP_RTT_SMOOTH; - - if (srtt < artt) - srtt = artt - srtt; - else - srtt -= artt; - drtt= tcp_conn->tc_drtt; - drtt= ((TCP_RTT_SMOOTH-1)*drtt+srtt)/TCP_RTT_SMOOTH; - - rtt= (artt+TCP_DRTT_MULT*drtt-1)/TCP_RTT_SCALE+1; - if (rtt < TCP_RTT_GRAN*CLOCK_GRAN) - { - rtt= TCP_RTT_GRAN*CLOCK_GRAN; - } - else if (rtt > TCP_RTT_MAX) - { -#if DEBUG - static int warned /* = 0 */; - - if (!warned) - { - printf( -"tcp_release_retrans: warning retransmission time is limited to %d ms\n", - TCP_RTT_MAX*1000/HZ); - warned= 1; - } -#endif - rtt= TCP_RTT_MAX; - } - DBLOCK(0x10, printf( - "tcp_release_retrans, conn[%i]: retrans_time= %u ms, rtt = %u ms\n", - tcp_conn-tcp_conn_table, - retrans_time*1000/HZ, - rtt*1000/HZ)); - - DBLOCK(0x10, printf( - "tcp_release_retrans: artt= %u -> %u, drtt= %u -> %u\n", - tcp_conn->tc_artt, artt, - tcp_conn->tc_drtt, drtt)); - - tcp_conn->tc_artt= artt; - tcp_conn->tc_drtt= drtt; - tcp_conn->tc_rtt= rtt; - } - - if (tcp_conn->tc_mtu != tcp_conn->tc_max_mtu && - curr_time > tcp_conn->tc_mtutim+TCP_PMTU_INCR_IV) - { - tcp_mtu_incr(tcp_conn); - } - } - - /* Update the current window. */ - window= tcp_conn->tc_snd_cwnd-tcp_conn->tc_SND_UNA; - assert(seg_ack != tcp_conn->tc_SND_UNA); - - /* For every real ACK we try to increase the current window - * with 1 mss. - */ - window += mss; - - /* If the window becomes larger than the current threshold, - * increment the threshold by a small amount and set the - * window to the threshold. - */ - cthresh= tcp_conn->tc_snd_cthresh; - if (window > cthresh) - { - new_cthresh= cthresh + tcp_conn->tc_snd_cinc; - if (new_cthresh < cthresh) - new_cthresh= cthresh; /* overflow */ - tcp_conn->tc_snd_cthresh= new_cthresh; - window= new_cthresh; - } - - /* If the window is larger than the window advertised by the - * receiver, set the window size to the advertisement. - */ - if (window > new_win) - window= new_win; - - tcp_conn->tc_snd_cwnd= seg_ack+window; - - /* Release data queued for retransmissions. */ - queue_lo= tcp_conn->tc_SND_UNA; - queue_hi= tcp_conn->tc_SND_NXT; - - tcp_conn->tc_SND_UNA= seg_ack; - if (tcp_Lmod4G(tcp_conn->tc_SND_TRM, seg_ack)) - { - tcp_conn->tc_SND_TRM= seg_ack; - } - assert(tcp_GEmod4G(tcp_conn->tc_snd_cwnd, seg_ack)); - - /* Advance ISS every 0.5GB to avoid problem with wrap around */ - if (tcp_conn->tc_SND_UNA - tcp_conn->tc_ISS > 0x40000000) - { - tcp_conn->tc_ISS += 0x20000000; - DBLOCK(1, printf( - "tcp_release_retrans: updating ISS to 0x%lx\n", - (unsigned long)tcp_conn->tc_ISS);); - if (tcp_Lmod4G(tcp_conn->tc_SND_UP, tcp_conn->tc_ISS)) - { - tcp_conn->tc_SND_UP= tcp_conn->tc_ISS; - DBLOCK(1, printf( - "tcp_release_retrans: updating SND_UP to 0x%lx\n", - (unsigned long)tcp_conn->tc_SND_UP);); - } - } - - if (queue_lo == tcp_conn->tc_ISS) - queue_lo++; - - if (tcp_conn->tc_flags & TCF_FIN_SENT) - { - if (seg_ack == queue_hi) - seg_ack--; - if (queue_lo == queue_hi) - queue_lo--; - queue_hi--; - } - - offset= seg_ack - queue_lo; - size= queue_hi - seg_ack; - pack= tcp_conn->tc_send_data; - tcp_conn->tc_send_data= 0; - - if (!size) - { - bf_afree(pack); - } - else - { - pack= bf_delhead(pack, offset); - tcp_conn->tc_send_data= pack; - } - - if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd)) - tcp_conn->tc_SND_TRM= tcp_conn->tc_snd_cwnd; - - /* Copy in new data if an ioctl is pending or if a write request is - * pending and either the write can be completed or at least one - * mss buffer space is available. - */ - tcp_fd= tcp_conn->tc_fd; - if (tcp_fd) - { - if (tcp_fd->tf_flags & TFF_IOCTL_IP) - { - tcp_fd_write(tcp_conn); - } - if ((tcp_fd->tf_flags & TFF_WRITE_IP) && - (size+tcp_fd->tf_write_count <= TCP_MAX_SND_WND_SIZE || - size <= TCP_MAX_SND_WND_SIZE-mss)) - { - tcp_fd_write(tcp_conn); - } - if (tcp_fd->tf_flags & TFF_SEL_WRITE) - tcp_rsel_write(tcp_conn); - } - else - { - if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT) - { - assert(tcp_conn->tc_state == TCS_CLOSING); - DBLOCK(0x10, - printf("all data sent in abondoned connection\n")); - tcp_close_connection(tcp_conn, ENOTCONN); - return; - } - } - - if (!size && !tcp_conn->tc_send_data) - { - /* Reset window if a write is completed */ - tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + mss; - } - - DIFBLOCK(2, (tcp_conn->tc_snd_cwnd == tcp_conn->tc_SND_TRM), - printf("not sending: zero window\n")); - - if (tcp_conn->tc_snd_cwnd != tcp_conn->tc_SND_TRM && - tcp_conn->tc_SND_NXT != tcp_conn->tc_SND_TRM) - { - tcp_conn_write(tcp_conn, 1); - } - -} - -/* -tcp_fast_retrans -*/ - -void tcp_fast_retrans(tcp_conn) -tcp_conn_t *tcp_conn; -{ - u16_t mss, mss2; - - /* Update threshold sequence number for retransmission calculation. */ - if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_rt_threshold)) - tcp_conn->tc_rt_threshold= tcp_conn->tc_SND_TRM; - - tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA; - - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - mss2= 2*mss; - - if (tcp_conn->tc_snd_cwnd == tcp_conn->tc_SND_UNA) - tcp_conn->tc_snd_cwnd++; - if (tcp_Gmod4G(tcp_conn->tc_snd_cwnd, tcp_conn->tc_SND_UNA + mss2)) - { - tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + mss2; - if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd)) - tcp_conn->tc_SND_TRM= tcp_conn->tc_snd_cwnd; - - tcp_conn->tc_snd_cthresh /= 2; - if (tcp_conn->tc_snd_cthresh < mss2) - tcp_conn->tc_snd_cthresh= mss2; - } - - tcp_conn_write(tcp_conn, 1); -} - -#if 0 -void do_tcp_timeout(tcp_conn) -tcp_conn_t *tcp_conn; -{ - tcp_send_timeout(tcp_conn-tcp_conn_table, - &tcp_conn->tc_transmit_timer); -} -#endif - -/* -tcp_send_timeout -*/ - -static void tcp_send_timeout(conn, timer) -int conn; -minix_timer_t *timer; -{ - tcp_conn_t *tcp_conn; - u16_t mss, mss2; - u32_t snd_una, snd_nxt; - clock_t curr_time, rtt, stt, timeout; - acc_t *pkt; - int new_ttl, no_push; - - DBLOCK(0x20, printf("tcp_send_timeout: conn[%d]\n", conn)); - - curr_time= get_time(); - - tcp_conn= &tcp_conn_table[conn]; - assert(tcp_conn->tc_flags & TCF_INUSE); - assert(tcp_conn->tc_state != TCS_CLOSED); - assert(tcp_conn->tc_state != TCS_LISTEN); - - snd_una= tcp_conn->tc_SND_UNA; - snd_nxt= tcp_conn->tc_SND_NXT; - no_push= (tcp_conn->tc_flags & TCF_NO_PUSH); - if (snd_nxt == snd_una || no_push) - { - /* Nothing more to send */ - assert(tcp_conn->tc_SND_TRM == snd_una || no_push); - - /* A new write sets the timer if tc_transmit_seq == SND_UNA */ - tcp_conn->tc_transmit_seq= tcp_conn->tc_SND_UNA; - tcp_conn->tc_stt= 0; - tcp_conn->tc_0wnd_to= 0; - assert(!tcp_conn->tc_fd || - !(tcp_conn->tc_fd->tf_flags & TFF_WRITE_IP) || - (tcp_print_conn(tcp_conn), printf("\n"), 0)); - - if (snd_nxt != snd_una) - { - assert(no_push); - DBLOCK(1, printf("not setting keepalive timer\n");); - - /* No point in setting the keepalive timer if we - * still have to send more data. - */ - return; - } - - assert(tcp_conn->tc_send_data == NULL); - DBLOCK(0x20, printf("keep alive timer\n")); - if (tcp_conn->tc_ka_snd != tcp_conn->tc_SND_NXT || - tcp_conn->tc_ka_rcv != tcp_conn->tc_RCV_NXT) - { - tcp_conn->tc_ka_snd= tcp_conn->tc_SND_NXT; - tcp_conn->tc_ka_rcv= tcp_conn->tc_RCV_NXT; - DBLOCK(0x20, printf( -"tcp_send_timeout: conn[%i] setting keepalive timer (+%u ms)\n", - tcp_conn-tcp_conn_table, - tcp_conn->tc_ka_time*1000/HZ)); - clck_timer(&tcp_conn->tc_transmit_timer, - curr_time+tcp_conn->tc_ka_time, - tcp_send_timeout, - tcp_conn-tcp_conn_table); - return; - } - DBLOCK(0x10, printf( - "tcp_send_timeout, conn[%d]: triggering keep alive probe\n", - tcp_conn-tcp_conn_table)); - tcp_conn->tc_ka_snd--; - if (!(tcp_conn->tc_flags & TCF_FIN_SENT)) - { - pkt= bf_memreq(1); - *ptr2acc_data(pkt)= '\xff'; /* a random char */ - tcp_conn->tc_send_data= pkt; pkt= NULL; - } - tcp_conn->tc_SND_UNA--; - if (tcp_conn->tc_SND_UNA == tcp_conn->tc_ISS) - { - /* We didn't send anything so far. Retrying the - * SYN is too hard. Decrement ISS and hope - * that the other side doesn't care. - */ - tcp_conn->tc_ISS--; - } - - /* Set tc_transmit_seq and tc_stt to trigger packet */ - tcp_conn->tc_transmit_seq= tcp_conn->tc_SND_UNA; - tcp_conn->tc_stt= curr_time; - - /* Set tc_rt_seq for round trip measurements */ - tcp_conn->tc_rt_time= curr_time; - tcp_conn->tc_rt_seq= tcp_conn->tc_SND_UNA; - - /* Set PSH to make sure that data gets sent */ - tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT; - assert(tcp_check_conn(tcp_conn)); - - /* Fall through */ - } - - rtt= tcp_conn->tc_rtt; - - if (tcp_conn->tc_transmit_seq != tcp_conn->tc_SND_UNA) - { - /* Some data has been acknowledged since the last time the - * timer was set, set the timer again. */ - tcp_conn->tc_transmit_seq= tcp_conn->tc_SND_UNA; - tcp_conn->tc_stt= 0; - tcp_conn->tc_0wnd_to= 0; - - DBLOCK(0x20, printf( - "tcp_send_timeout: conn[%i] setting timer to %u ms (+%u ms)\n", - tcp_conn-tcp_conn_table, - (curr_time+rtt)*1000/HZ, rtt*1000/HZ)); - - clck_timer(&tcp_conn->tc_transmit_timer, - curr_time+rtt, tcp_send_timeout, - tcp_conn-tcp_conn_table); - return; - } - - stt= tcp_conn->tc_stt; - if (stt == 0) - { - /* Some packet arrived but did not acknowledge any data. - * Apparently, the other side is still alive and has a - * reason to transmit. We can asume a zero window. - */ - - DBLOCK(0x10, printf("conn[%d] setting zero window timer\n", - tcp_conn-tcp_conn_table)); - - if (tcp_conn->tc_0wnd_to < TCP_0WND_MIN) - tcp_conn->tc_0wnd_to= TCP_0WND_MIN; - else if (tcp_conn->tc_0wnd_to < rtt) - tcp_conn->tc_0wnd_to= rtt; - else - { - tcp_conn->tc_0wnd_to *= 2; - if (tcp_conn->tc_0wnd_to > TCP_0WND_MAX) - tcp_conn->tc_0wnd_to= TCP_0WND_MAX; - } - tcp_conn->tc_stt= curr_time; - tcp_conn->tc_rt_seq= 0; - - DBLOCK(0x10, printf( - "tcp_send_timeout: conn[%i] setting timer to %u ms (+%u ms)\n", - tcp_conn-tcp_conn_table, - (curr_time+tcp_conn->tc_0wnd_to)*1000/HZ, - tcp_conn->tc_0wnd_to*1000/HZ)); - - clck_timer(&tcp_conn->tc_transmit_timer, - curr_time+tcp_conn->tc_0wnd_to, - tcp_send_timeout, tcp_conn-tcp_conn_table); - return; - } - assert(stt <= curr_time); - - DIFBLOCK(0x10, (tcp_conn->tc_fd == 0), - printf("conn[%d] timeout in abondoned connection\n", - tcp_conn-tcp_conn_table)); - - /* At this point, we have do a retransmission, or send a zero window - * probe, which is almost the same. - */ - - DBLOCK(0x20, printf("tcp_send_timeout: conn[%i] una= %lu, rtt= %u ms\n", - tcp_conn-tcp_conn_table, - (unsigned long)tcp_conn->tc_SND_UNA, rtt*1000/HZ)); - - /* Update threshold sequence number for retransmission calculation. */ - if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_rt_threshold)) - tcp_conn->tc_rt_threshold= tcp_conn->tc_SND_TRM; - - tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA; - - if (tcp_conn->tc_flags & TCF_PMTU && - curr_time > stt+TCP_PMTU_BLACKHOLE) - { - /* We can't tell the difference between a PMTU blackhole - * and a broken link. Assume a PMTU blackhole, and switch - * off PMTU discovery. - */ - DBLOCK(1, printf( - "tcp[%d]: PMTU blackhole (or broken link) on route to ", - tcp_conn-tcp_conn_table); - writeIpAddr(tcp_conn->tc_remaddr); - printf(", max mtu = %u\n", tcp_conn->tc_max_mtu);); - tcp_conn->tc_flags &= ~TCF_PMTU; - tcp_conn->tc_mtutim= curr_time; - if (tcp_conn->tc_max_mtu > IP_DEF_MTU) - tcp_conn->tc_mtu= IP_DEF_MTU; - } - - mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; - mss2= 2*mss; - - if (tcp_conn->tc_snd_cwnd == tcp_conn->tc_SND_UNA) - tcp_conn->tc_snd_cwnd++; - if (tcp_Gmod4G(tcp_conn->tc_snd_cwnd, tcp_conn->tc_SND_UNA + mss2)) - { - tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + mss2; - if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd)) - tcp_conn->tc_SND_TRM= tcp_conn->tc_snd_cwnd; - - tcp_conn->tc_snd_cthresh /= 2; - if (tcp_conn->tc_snd_cthresh < mss2) - tcp_conn->tc_snd_cthresh= mss2; - } - - if (curr_time-stt > tcp_conn->tc_rt_dead) - { - tcp_close_connection(tcp_conn, ETIMEDOUT); - return; - } - - timeout= (curr_time-stt) >> 3; - if (timeout < rtt) - timeout= rtt; - timeout += curr_time; - - DBLOCK(0x20, printf( - "tcp_send_timeout: conn[%i] setting timer to %u ms (+%u ms)\n", - tcp_conn-tcp_conn_table, timeout*1000/HZ, - (timeout-curr_time)*1000/HZ)); - - clck_timer(&tcp_conn->tc_transmit_timer, timeout, - tcp_send_timeout, tcp_conn-tcp_conn_table); - -#if 0 - if (tcp_conn->tc_rt_seq == 0) - { - printf("tcp_send_timeout: conn[%d]: setting tc_rt_time\n", - tcp_conn-tcp_conn_table); - tcp_conn->tc_rt_time= curr_time-rtt; - tcp_conn->tc_rt_seq= tcp_conn->tc_SND_UNA; - } -#endif - - if (tcp_conn->tc_state == TCS_SYN_SENT || - (curr_time-stt >= tcp_conn->tc_ttl*HZ)) - { - new_ttl= tcp_conn->tc_ttl+1; - if (new_ttl> IP_MAX_TTL) - new_ttl= IP_MAX_TTL; - tcp_conn->tc_ttl= new_ttl; - } - - tcp_conn_write(tcp_conn, 0); -} - - -void tcp_fd_write(tcp_conn) -tcp_conn_t *tcp_conn; -{ - tcp_fd_t *tcp_fd; - int urg, nourg, push; - u32_t max_seq; - size_t max_trans, write_count; - acc_t *data, *send_data; - - assert(tcp_conn->tc_busy); - tcp_fd= tcp_conn->tc_fd; - - if ((tcp_fd->tf_flags & TFF_IOCTL_IP) && - !(tcp_fd->tf_flags & TFF_WRITE_IP)) - { - if (tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN) - return; - DBLOCK(0x10, printf("NWIOTCPSHUTDOWN\n")); - if (tcp_conn->tc_state == TCS_CLOSED) - { - tcp_reply_ioctl (tcp_fd, tcp_conn->tc_error); - return; - } - if (!(tcp_conn->tc_flags & TCF_FIN_SENT)) - { - DBLOCK(0x10, printf("calling tcp_shutdown\n")); - tcp_shutdown (tcp_conn); - } - else - { - if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT) - { - tcp_reply_ioctl (tcp_fd, NW_OK); - DBLOCK(0x10, printf("shutdown completed\n")); - } - else - { - DBLOCK(0x10, - printf("shutdown still inprogress\n")); - } - } - return; - } - - assert (tcp_fd->tf_flags & TFF_WRITE_IP); - if (tcp_conn->tc_state == TCS_CLOSED) - { - if (tcp_fd->tf_write_offset) - { - tcp_reply_write(tcp_fd, - tcp_fd->tf_write_offset); - } - else - tcp_reply_write(tcp_fd, tcp_conn->tc_error); - return; - } - - urg= (tcp_fd->tf_flags & TFF_WR_URG); - push= (tcp_fd->tf_flags & TFF_PUSH_DATA); - - max_seq= tcp_conn->tc_SND_UNA + TCP_MAX_SND_WND_SIZE; - max_trans= max_seq - tcp_conn->tc_SND_NXT; - if (tcp_fd->tf_write_count <= max_trans) - write_count= tcp_fd->tf_write_count; - else - write_count= max_trans; - if (write_count) - { - if (tcp_conn->tc_flags & TCF_BSD_URG) - { - if (tcp_Gmod4G(tcp_conn->tc_SND_NXT, - tcp_conn->tc_SND_UNA)) - { - nourg= tcp_LEmod4G(tcp_conn->tc_SND_UP, - tcp_conn->tc_SND_UNA); - if ((urg && nourg) || (!urg && !nourg)) - { - DBLOCK(0x20, - printf("not sending\n")); - return; - } - } - } - data= (*tcp_fd->tf_get_userdata) - (tcp_fd->tf_srfd, tcp_fd->tf_write_offset, - write_count, FALSE); - - if (!data) - { - if (tcp_fd->tf_write_offset) - { - tcp_reply_write(tcp_fd, - tcp_fd->tf_write_offset); - } - else - tcp_reply_write(tcp_fd, EFAULT); - return; - } - tcp_fd->tf_write_offset += write_count; - tcp_fd->tf_write_count -= write_count; - - send_data= tcp_conn->tc_send_data; - tcp_conn->tc_send_data= 0; - send_data= bf_append(send_data, data); - tcp_conn->tc_send_data= send_data; - tcp_conn->tc_SND_NXT += write_count; - if (urg) - { - if (tcp_conn->tc_flags & TCF_BSD_URG) - tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT; - else - tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT-1; - } - if (push && !tcp_fd->tf_write_count) - tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT; - } - if (!tcp_fd->tf_write_count) - { - tcp_reply_write(tcp_fd, tcp_fd->tf_write_offset); - } -} - -unsigned tcp_sel_write(tcp_conn) -tcp_conn_t *tcp_conn; -{ - tcp_fd_t *tcp_fd; - int urg, nourg; - u32_t max_seq; - size_t max_trans; - - tcp_fd= tcp_conn->tc_fd; - - if (tcp_conn->tc_state == TCS_CLOSED) - return 1; - - urg= (tcp_fd->tf_flags & TFF_WR_URG); - - max_seq= tcp_conn->tc_SND_UNA + TCP_MAX_SND_WND_SIZE; - max_trans= max_seq - tcp_conn->tc_SND_NXT; - if (max_trans) - { - if (tcp_conn->tc_flags & TCF_BSD_URG) - { - if (tcp_Gmod4G(tcp_conn->tc_SND_NXT, - tcp_conn->tc_SND_UNA)) - { - nourg= tcp_LEmod4G(tcp_conn->tc_SND_UP, - tcp_conn->tc_SND_UNA); - if ((urg && nourg) || (!urg && !nourg)) - { - DBLOCK(0x20, - printf("not sending\n")); - return 0; - } - } - } - return 1; - } - - return 0; -} - -void -tcp_rsel_write(tcp_conn) -tcp_conn_t *tcp_conn; -{ - tcp_fd_t *tcp_fd; - - if (tcp_sel_write(tcp_conn) == 0) - return; - - tcp_fd= tcp_conn->tc_fd; - tcp_fd->tf_flags &= ~TFF_SEL_WRITE; - if (tcp_fd->tf_select_res) - tcp_fd->tf_select_res(tcp_fd->tf_srfd, SR_SELECT_WRITE); - else - printf("tcp_rsel_write: no select_res\n"); -} - -/* -tcp_shutdown -*/ - -void tcp_shutdown(tcp_conn) -tcp_conn_t *tcp_conn; -{ - switch (tcp_conn->tc_state) - { - case TCS_CLOSED: - case TCS_LISTEN: - case TCS_SYN_SENT: - case TCS_SYN_RECEIVED: - tcp_close_connection(tcp_conn, ENOTCONN); - return; - } - - if (tcp_conn->tc_flags & TCF_FIN_SENT) - return; - tcp_conn->tc_flags |= TCF_FIN_SENT; - tcp_conn->tc_flags &= ~TCF_NO_PUSH; - tcp_conn->tc_SND_NXT++; - tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT; - - assert (tcp_check_conn(tcp_conn) || - (tcp_print_conn(tcp_conn), printf("\n"), 0)); - - tcp_conn_write(tcp_conn, 1); - - /* Start the timer */ - tcp_set_send_timer(tcp_conn); -} - -void tcp_set_send_timer(tcp_conn) -tcp_conn_t *tcp_conn; -{ - clock_t curr_time; - clock_t rtt; - - assert(tcp_conn->tc_state != TCS_CLOSED); - assert(tcp_conn->tc_state != TCS_LISTEN); - - curr_time= get_time(); - rtt= tcp_conn->tc_rtt; - - DBLOCK(0x20, printf( - "tcp_set_send_timer: conn[%i] setting timer to %u ms (+%u ms)\n", - tcp_conn-tcp_conn_table, - (curr_time+rtt)*1000/HZ, rtt*1000/HZ)); - - /* Start the timer */ - clck_timer(&tcp_conn->tc_transmit_timer, - curr_time+rtt, tcp_send_timeout, tcp_conn-tcp_conn_table); - tcp_conn->tc_stt= curr_time; -} - -/* -tcp_close_connection - -*/ - -void tcp_close_connection(tcp_conn, error) -tcp_conn_t *tcp_conn; -int error; -{ - int i; - tcp_port_t *tcp_port; - tcp_fd_t *tcp_fd; - tcp_conn_t *tc; - - assert (tcp_check_conn(tcp_conn) || - (tcp_print_conn(tcp_conn), printf("\n"), 0)); - assert (tcp_conn->tc_flags & TCF_INUSE); - - tcp_conn->tc_error= error; - tcp_port= tcp_conn->tc_port; - tcp_fd= tcp_conn->tc_fd; - if (tcp_conn->tc_state == TCS_CLOSED) - return; - - tcp_conn->tc_state= TCS_CLOSED; - DBLOCK(0x10, tcp_print_state(tcp_conn); printf("\n")); - - if (tcp_fd && (tcp_fd->tf_flags & TFF_LISTENQ)) - { - for (i= 0; itf_listenq[i] == tcp_conn) - break; - } - assert(i < TFL_LISTEN_MAX); - tcp_fd->tf_listenq[i]= NULL; - - tcp_conn->tc_connInprogress= 0; - - tcp_conn->tc_fd= NULL; - tcp_fd= NULL; - } - else if (tcp_fd) - { - - tcp_conn->tc_busy++; - assert(tcp_fd->tf_conn == tcp_conn); - - if (tcp_fd->tf_flags & TFF_READ_IP) - tcp_fd_read (tcp_conn, 1); - assert (!(tcp_fd->tf_flags & TFF_READ_IP)); - if (tcp_fd->tf_flags & TFF_SEL_READ) - tcp_rsel_read (tcp_conn); - - if (tcp_fd->tf_flags & TFF_WRITE_IP) - { - tcp_fd_write(tcp_conn); - tcp_conn_write(tcp_conn, 1); - } - assert (!(tcp_fd->tf_flags & TFF_WRITE_IP)); - if (tcp_fd->tf_flags & TFF_IOCTL_IP) - { - tcp_fd_write(tcp_conn); - tcp_conn_write(tcp_conn, 1); - } - if (tcp_fd->tf_flags & TFF_IOCTL_IP) - assert(tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN); - if (tcp_fd->tf_flags & TFF_SEL_WRITE) - tcp_rsel_write(tcp_conn); - - if (tcp_conn->tc_connInprogress) - tcp_restart_connect(tcp_conn); - assert(!tcp_conn->tc_connInprogress); - assert (!(tcp_fd->tf_flags & TFF_IOCTL_IP) || - (printf("req= 0x%lx\n", - (unsigned long)tcp_fd->tf_ioreq), 0)); - tcp_conn->tc_busy--; - } - - if (tcp_conn->tc_rcvd_data) - { - bf_afree(tcp_conn->tc_rcvd_data); - tcp_conn->tc_rcvd_data= NULL; - } - tcp_conn->tc_flags &= ~TCF_FIN_RECV; - tcp_conn->tc_RCV_LO= tcp_conn->tc_RCV_NXT; - - if (tcp_conn->tc_adv_data) - { - bf_afree(tcp_conn->tc_adv_data); - tcp_conn->tc_adv_data= NULL; - } - - if (tcp_conn->tc_send_data) - { - bf_afree(tcp_conn->tc_send_data); - tcp_conn->tc_send_data= NULL; - tcp_conn->tc_SND_TRM= - tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA; - } - tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA; - - if (tcp_conn->tc_remipopt) - { - bf_afree(tcp_conn->tc_remipopt); - tcp_conn->tc_remipopt= NULL; - } - - if (tcp_conn->tc_tcpopt) - { - bf_afree(tcp_conn->tc_tcpopt); - tcp_conn->tc_tcpopt= NULL; - } - - if (tcp_conn->tc_frag2send) - { - bf_afree(tcp_conn->tc_frag2send); - tcp_conn->tc_frag2send= NULL; - } - if (tcp_conn->tc_flags & TCF_MORE2WRITE) - { - for (tc= tcp_port->tp_snd_head; tc; tc= tc->tc_send_link) - { - if (tc->tc_send_link == tcp_conn) - break; - } - if (tc == NULL) - { - assert(tcp_port->tp_snd_head == tcp_conn); - tcp_port->tp_snd_head= tcp_conn->tc_send_link; - } - else - { - tc->tc_send_link= tcp_conn->tc_send_link; - if (tc->tc_send_link == NULL) - tcp_port->tp_snd_tail= tc; - } - tcp_conn->tc_flags &= ~TCF_MORE2WRITE; - } - - clck_untimer (&tcp_conn->tc_transmit_timer); - tcp_conn->tc_transmit_seq= 0; - - /* clear all flags but TCF_INUSE */ - tcp_conn->tc_flags &= TCF_INUSE; - assert (tcp_check_conn(tcp_conn)); -} - -/* - * $PchId: tcp_send.c,v 1.32 2005/06/28 14:21:52 philip Exp $ - */ diff --git a/minix/net/inet/generic/type.h b/minix/net/inet/generic/type.h deleted file mode 100644 index 7a588b051..000000000 --- a/minix/net/inet/generic/type.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -type.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET_TYPE_H -#define INET_TYPE_H - -typedef struct acc *(*get_userdata_t) ARGS(( int fd, size_t offset, - size_t count, int for_ioctl )); -typedef int (*put_userdata_t) ARGS(( int fd, size_t offset, - struct acc *data, int for_ioctl )); -typedef void (*put_pkt_t) ARGS(( int fd, struct acc *data, size_t datalen )); -typedef void (*select_res_t) ARGS(( int fd, unsigned ops )); - -#endif /* INET_TYPE_H */ - -/* - * $PchId: type.h,v 1.6 2005/06/28 14:22:04 philip Exp $ - */ diff --git a/minix/net/inet/generic/udp.c b/minix/net/inet/generic/udp.c deleted file mode 100644 index fe41fb8e8..000000000 --- a/minix/net/inet/generic/udp.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* -udp.c - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "type.h" - -#include "assert.h" -#include "buf.h" -#include "clock.h" -#include "icmp_lib.h" -#include "io.h" -#include "ip.h" -#include "sr.h" -#include "udp.h" -#include "udp_int.h" - -THIS_FILE - -static void read_ip_packets ARGS(( udp_port_t *udp_port )); -static void udp_buffree ARGS(( int priority )); -#ifdef BUF_CONSISTENCY_CHECK -static void udp_bufcheck ARGS(( void )); -#endif -static void udp_main ARGS(( udp_port_t *udp_port )); -static int udp_select ARGS(( int fd, unsigned operations )); -static acc_t *udp_get_data ARGS(( int fd, size_t offset, size_t count, - int for_ioctl )); -static int udp_put_data ARGS(( int fd, size_t offset, acc_t *data, - int for_ioctl )); -static int udp_peek ARGS(( udp_fd_t * )); -static int udp_sel_read ARGS(( udp_fd_t * )); -static void udp_restart_write_port ARGS(( udp_port_t *udp_port )); -static void udp_ip_arrived ARGS(( int port, acc_t *pack, size_t pack_size )); -static void reply_thr_put ARGS(( udp_fd_t *udp_fd, int reply, - int for_ioctl )); -static void reply_thr_get ARGS(( udp_fd_t *udp_fd, int reply, - int for_ioctl )); -static int udp_setopt ARGS(( udp_fd_t *udp_fd )); -static udpport_t find_unused_port ARGS(( int fd )); -static int is_unused_port ARGS(( udpport_t port )); -static int udp_packet2user ARGS(( udp_fd_t *udp_fd )); -static void restart_write_fd ARGS(( udp_fd_t *udp_fd )); -static u16_t pack_oneCsum ARGS(( acc_t *pack )); -static void udp_rd_enqueue ARGS(( udp_fd_t *udp_fd, acc_t *pack, - clock_t exp_tim )); -static void hash_fd ARGS(( udp_fd_t *udp_fd )); -static void unhash_fd ARGS(( udp_fd_t *udp_fd )); - -udp_port_t *udp_port_table; -udp_fd_t udp_fd_table[UDP_FD_NR]; - -void udp_prep() -{ - udp_port_table= alloc(udp_conf_nr * sizeof(udp_port_table[0])); -} - -void udp_init() -{ - udp_fd_t *udp_fd; - udp_port_t *udp_port; - int i, j, ifno; - - assert (BUF_S >= sizeof(struct nwio_ipopt)); - assert (BUF_S >= sizeof(struct nwio_ipconf)); - assert (BUF_S >= sizeof(struct nwio_udpopt)); - assert (BUF_S >= sizeof(struct udp_io_hdr)); - assert (UDP_HDR_SIZE == sizeof(udp_hdr_t)); - assert (UDP_IO_HDR_SIZE == sizeof(udp_io_hdr_t)); - - for (i= 0, udp_fd= udp_fd_table; iuf_flags= UFF_EMPTY; - udp_fd->uf_rdbuf_head= NULL; - } - -#ifndef BUF_CONSISTENCY_CHECK - bf_logon(udp_buffree); -#else - bf_logon(udp_buffree, udp_bufcheck); -#endif - - for (i= 0, udp_port= udp_port_table; iup_ipdev= udp_conf[i].uc_port; - - udp_port->up_flags= UPF_EMPTY; - udp_port->up_state= UPS_EMPTY; - udp_port->up_next_fd= udp_fd_table; - udp_port->up_write_fd= NULL; - udp_port->up_wr_pack= NULL; - udp_port->up_port_any= NULL; - for (j= 0; jup_port_hash[j]= NULL; - - ifno= ip_conf[udp_port->up_ipdev].ic_ifno; - sr_add_minor(if2minor(ifno, UDP_DEV_OFF), - i, udp_open, udp_close, udp_read, - udp_write, udp_ioctl, udp_cancel, udp_select); - - udp_main(udp_port); - } -} - -int udp_open (port, srfd, get_userdata, put_userdata, put_pkt, - select_res) -int port; -int srfd; -get_userdata_t get_userdata; -put_userdata_t put_userdata; -put_pkt_t put_pkt; -select_res_t select_res; -{ - int i; - udp_fd_t *udp_fd; - - for (i= 0; i= UDP_FD_NR) - { - DBLOCK(1, printf("out of fds\n")); - return EAGAIN; - } - - udp_fd= &udp_fd_table[i]; - - udp_fd->uf_flags= UFF_INUSE; - udp_fd->uf_port= &udp_port_table[port]; - udp_fd->uf_srfd= srfd; - udp_fd->uf_udpopt.nwuo_flags= UDP_DEF_OPT; - udp_fd->uf_get_userdata= get_userdata; - udp_fd->uf_put_userdata= put_userdata; - udp_fd->uf_select_res= select_res; - assert(udp_fd->uf_rdbuf_head == NULL); - udp_fd->uf_port_next= NULL; - - return i; - -} - -int udp_ioctl (fd, req) -int fd; -ioreq_t req; -{ - udp_fd_t *udp_fd; - udp_port_t *udp_port; - nwio_udpopt_t *udp_opt; - acc_t *opt_acc; - int result; - - udp_fd= &udp_fd_table[fd]; - -assert (udp_fd->uf_flags & UFF_INUSE); - - udp_port= udp_fd->uf_port; - udp_fd->uf_flags |= UFF_IOCTL_IP; - udp_fd->uf_ioreq= req; - - if (udp_port->up_state != UPS_MAIN) - return NW_SUSPEND; - - switch(req) - { - case NWIOSUDPOPT: - result= udp_setopt(udp_fd); - break; - case NWIOGUDPOPT: - opt_acc= bf_memreq(sizeof(*udp_opt)); -assert (opt_acc->acc_length == sizeof(*udp_opt)); - udp_opt= (nwio_udpopt_t *)ptr2acc_data(opt_acc); - - *udp_opt= udp_fd->uf_udpopt; - udp_opt->nwuo_locaddr= udp_fd->uf_port->up_ipaddr; - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, 0, opt_acc, - TRUE); - if (result == NW_OK) - reply_thr_put(udp_fd, NW_OK, TRUE); - break; - case NWIOUDPPEEK: - result= udp_peek(udp_fd); - break; - default: - reply_thr_get(udp_fd, ENOTTY, TRUE); - result= NW_OK; - break; - } - if (result != NW_SUSPEND) - udp_fd->uf_flags &= ~UFF_IOCTL_IP; - return result; -} - -int udp_read (fd, count) -int fd; -size_t count; -{ - udp_fd_t *udp_fd; - acc_t *tmp_acc, *next_acc; - - udp_fd= &udp_fd_table[fd]; - if (!(udp_fd->uf_flags & UFF_OPTSET)) - { - reply_thr_put(udp_fd, EBADMODE, FALSE); - return NW_OK; - } - - udp_fd->uf_rd_count= count; - - if (udp_fd->uf_rdbuf_head) - { - if (get_time() <= udp_fd->uf_exp_tim) - return udp_packet2user (udp_fd); - tmp_acc= udp_fd->uf_rdbuf_head; - while (tmp_acc) - { - next_acc= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - tmp_acc= next_acc; - } - udp_fd->uf_rdbuf_head= NULL; - } - udp_fd->uf_flags |= UFF_READ_IP; - return NW_SUSPEND; -} - -static void udp_main(udp_port) -udp_port_t *udp_port; -{ - udp_fd_t *udp_fd; - int result, i; - - switch (udp_port->up_state) - { - case UPS_EMPTY: - udp_port->up_state= UPS_SETPROTO; - - udp_port->up_ipfd= ip_open(udp_port->up_ipdev, - udp_port->up_ipdev, udp_get_data, udp_put_data, - udp_ip_arrived, 0 /* no select_res */); - if (udp_port->up_ipfd < 0) - { - udp_port->up_state= UPS_ERROR; - DBLOCK(1, printf("%s, %d: unable to open ip port\n", - __FILE__, __LINE__)); - return; - } - - result= ip_ioctl(udp_port->up_ipfd, NWIOSIPOPT); - if (result == NW_SUSPEND) - udp_port->up_flags |= UPF_SUSPEND; - if (result<0) - { - return; - } - if (udp_port->up_state != UPS_GETCONF) - return; - /* drops through */ - case UPS_GETCONF: - udp_port->up_flags &= ~UPF_SUSPEND; - - result= ip_ioctl(udp_port->up_ipfd, NWIOGIPCONF); - if (result == NW_SUSPEND) - udp_port->up_flags |= UPF_SUSPEND; - if (result<0) - { - return; - } - if (udp_port->up_state != UPS_MAIN) - return; - /* drops through */ - case UPS_MAIN: - udp_port->up_flags &= ~UPF_SUSPEND; - - for (i= 0, udp_fd= udp_fd_table; iuf_flags & UFF_INUSE)) - continue; - if (udp_fd->uf_port != udp_port) - continue; - if (udp_fd->uf_flags & UFF_IOCTL_IP) - udp_ioctl(i, udp_fd->uf_ioreq); - } - read_ip_packets(udp_port); - return; - default: - DBLOCK(1, printf("udp_port_table[%d].up_state= %d\n", - udp_port->up_ipdev, udp_port->up_state)); - ip_panic(( "unknown state" )); - break; - } -} - -static int udp_select(fd, operations) -int fd; -unsigned operations; -{ - unsigned resops; - udp_fd_t *udp_fd; - - udp_fd= &udp_fd_table[fd]; - assert (udp_fd->uf_flags & UFF_INUSE); - - resops= 0; - - if (operations & SR_SELECT_READ) - { - if (udp_sel_read(udp_fd)) - resops |= SR_SELECT_READ; - else if (!(operations & SR_SELECT_POLL)) - udp_fd->uf_flags |= UFF_SEL_READ; - } - if (operations & SR_SELECT_WRITE) - { - /* Should handle special case when the interface is down */ - resops |= SR_SELECT_WRITE; - } - if (operations & SR_SELECT_EXCEPTION) - { - /* Nothing */ - } - return resops; -} - -static acc_t *udp_get_data (port, offset, count, for_ioctl) -int port; -size_t offset; -size_t count; -int for_ioctl; -{ - udp_port_t *udp_port; - udp_fd_t *udp_fd; - int result; - - udp_port= &udp_port_table[port]; - - switch(udp_port->up_state) - { - case UPS_SETPROTO: -assert (for_ioctl); - if (!count) - { - result= (int)offset; - if (result<0) - { - udp_port->up_state= UPS_ERROR; - break; - } - udp_port->up_state= UPS_GETCONF; - if (udp_port->up_flags & UPF_SUSPEND) - udp_main(udp_port); - return NULL; - } - else - { - struct nwio_ipopt *ipopt; - acc_t *acc; - -assert (!offset); -assert (count == sizeof(*ipopt)); - - acc= bf_memreq(sizeof(*ipopt)); - ipopt= (struct nwio_ipopt *)ptr2acc_data(acc); - ipopt->nwio_flags= NWIO_COPY | NWIO_EN_LOC | - NWIO_EN_BROAD | NWIO_REMANY | NWIO_PROTOSPEC | - NWIO_HDR_O_ANY | NWIO_RWDATALL; - ipopt->nwio_proto= IPPROTO_UDP; - return acc; - } - case UPS_MAIN: -assert (!for_ioctl); -assert (udp_port->up_flags & UPF_WRITE_IP); - if (!count) - { - result= (int)offset; -assert (udp_port->up_wr_pack); - bf_afree(udp_port->up_wr_pack); - udp_port->up_wr_pack= 0; - if (udp_port->up_flags & UPF_WRITE_SP) - { - if (udp_port->up_write_fd) - { - udp_fd= udp_port->up_write_fd; - udp_port->up_write_fd= NULL; - udp_fd->uf_flags &= ~UFF_WRITE_IP; - reply_thr_get(udp_fd, result, FALSE); - } - udp_port->up_flags &= ~(UPF_WRITE_SP | - UPF_WRITE_IP); - if (udp_port->up_flags & UPF_MORE2WRITE) - { - udp_restart_write_port(udp_port); - } - } - else - udp_port->up_flags &= ~UPF_WRITE_IP; - } - else - { - return bf_cut (udp_port->up_wr_pack, offset, count); - } - break; - default: - printf("udp_get_data(%d, 0x%x, 0x%x) called but up_state= 0x%x\n", - port, offset, count, udp_port->up_state); - break; - } - return NULL; -} - -static int udp_put_data (fd, offset, data, for_ioctl) -int fd; -size_t offset; -acc_t *data; -int for_ioctl; -{ - udp_port_t *udp_port; - int result; - - udp_port= &udp_port_table[fd]; - - switch (udp_port->up_state) - { - case UPS_GETCONF: - if (!data) - { - result= (int)offset; - if (result<0) - { - udp_port->up_state= UPS_ERROR; - return NW_OK; - } - udp_port->up_state= UPS_MAIN; - if (udp_port->up_flags & UPF_SUSPEND) - udp_main(udp_port); - } - else - { - struct nwio_ipconf *ipconf; - - data= bf_packIffLess(data, sizeof(*ipconf)); - ipconf= (struct nwio_ipconf *)ptr2acc_data(data); -assert (ipconf->nwic_flags & NWIC_IPADDR_SET); - udp_port->up_ipaddr= ipconf->nwic_ipaddr; - bf_afree(data); - } - break; - case UPS_MAIN: - assert(0); - - assert (udp_port->up_flags & UPF_READ_IP); - if (!data) - { - result= (int)offset; - compare (result, >=, 0); - if (udp_port->up_flags & UPF_READ_SP) - { - udp_port->up_flags &= ~(UPF_READ_SP| - UPF_READ_IP); - read_ip_packets(udp_port); - } - else - udp_port->up_flags &= ~UPF_READ_IP; - } - else - { -assert (!offset); /* This isn't a valid assertion but ip sends only - * whole datagrams up */ - udp_ip_arrived(fd, data, bf_bufsize(data)); - } - break; - default: - ip_panic(( - "udp_put_data(%d, 0x%x, %p) called but up_state= 0x%x\n", - fd, offset, data, udp_port->up_state )); - } - return NW_OK; -} - -static int udp_setopt(udp_fd) -udp_fd_t *udp_fd; -{ - udp_fd_t *fd_ptr; - nwio_udpopt_t oldopt, newopt; - acc_t *data; - unsigned int new_en_flags, new_di_flags, old_en_flags, old_di_flags, - all_flags, flags; - unsigned long new_flags; - int i; - - data= (*udp_fd->uf_get_userdata)(udp_fd->uf_srfd, 0, - sizeof(nwio_udpopt_t), TRUE); - - if (!data) - return EFAULT; - - data= bf_packIffLess(data, sizeof(nwio_udpopt_t)); -assert (data->acc_length == sizeof(nwio_udpopt_t)); - - newopt= *(nwio_udpopt_t *)ptr2acc_data(data); - bf_afree(data); - oldopt= udp_fd->uf_udpopt; - - old_en_flags= oldopt.nwuo_flags & 0xffff; - old_di_flags= (oldopt.nwuo_flags >> 16) & 0xffff; - - new_en_flags= newopt.nwuo_flags & 0xffff; - new_di_flags= (newopt.nwuo_flags >> 16) & 0xffff; - - if (new_en_flags & new_di_flags) - { - DBLOCK(1, printf("returning EBADMODE\n")); - - reply_thr_get(udp_fd, EBADMODE, TRUE); - return NW_OK; - } - - /* NWUO_ACC_MASK */ - if (new_di_flags & NWUO_ACC_MASK) - { - DBLOCK(1, printf("returning EBADMODE\n")); - - reply_thr_get(udp_fd, EBADMODE, TRUE); - return NW_OK; - /* access modes can't be disabled */ - } - - if (!(new_en_flags & NWUO_ACC_MASK)) - new_en_flags |= (old_en_flags & NWUO_ACC_MASK); - - /* NWUO_LOCPORT_MASK */ - if (new_di_flags & NWUO_LOCPORT_MASK) - { - DBLOCK(1, printf("returning EBADMODE\n")); - - reply_thr_get(udp_fd, EBADMODE, TRUE); - return NW_OK; - /* the loc ports can't be disabled */ - } - if (!(new_en_flags & NWUO_LOCPORT_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_LOCPORT_MASK); - newopt.nwuo_locport= oldopt.nwuo_locport; - } - else if ((new_en_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SEL) - { - newopt.nwuo_locport= find_unused_port(udp_fd-udp_fd_table); - } - else if ((new_en_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SET) - { - if (!newopt.nwuo_locport) - { - DBLOCK(1, printf("returning EBADMODE\n")); - - reply_thr_get(udp_fd, EBADMODE, TRUE); - return NW_OK; - } - } - - /* NWUO_LOCADDR_MASK */ - if (!((new_en_flags | new_di_flags) & NWUO_LOCADDR_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_LOCADDR_MASK); - new_di_flags |= (old_di_flags & NWUO_LOCADDR_MASK); - } - - /* NWUO_BROAD_MASK */ - if (!((new_en_flags | new_di_flags) & NWUO_BROAD_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_BROAD_MASK); - new_di_flags |= (old_di_flags & NWUO_BROAD_MASK); - } - - /* NWUO_REMPORT_MASK */ - if (!((new_en_flags | new_di_flags) & NWUO_REMPORT_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_REMPORT_MASK); - new_di_flags |= (old_di_flags & NWUO_REMPORT_MASK); - newopt.nwuo_remport= oldopt.nwuo_remport; - } - - /* NWUO_REMADDR_MASK */ - if (!((new_en_flags | new_di_flags) & NWUO_REMADDR_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_REMADDR_MASK); - new_di_flags |= (old_di_flags & NWUO_REMADDR_MASK); - newopt.nwuo_remaddr= oldopt.nwuo_remaddr; - } - - /* NWUO_RW_MASK */ - if (!((new_en_flags | new_di_flags) & NWUO_RW_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_RW_MASK); - new_di_flags |= (old_di_flags & NWUO_RW_MASK); - } - - /* NWUO_IPOPT_MASK */ - if (!((new_en_flags | new_di_flags) & NWUO_IPOPT_MASK)) - { - new_en_flags |= (old_en_flags & NWUO_IPOPT_MASK); - new_di_flags |= (old_di_flags & NWUO_IPOPT_MASK); - } - - new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags; - if ((new_flags & NWUO_RWDATONLY) && - ((new_flags & NWUO_LOCPORT_MASK) == NWUO_LP_ANY || - (new_flags & (NWUO_RP_ANY|NWUO_RA_ANY|NWUO_EN_IPOPT)))) - { - DBLOCK(1, printf("returning EBADMODE\n")); - - reply_thr_get(udp_fd, EBADMODE, TRUE); - return NW_OK; - } - - /* Check the access modes */ - if ((new_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SEL || - (new_flags & NWUO_LOCPORT_MASK) == NWUO_LP_SET) - { - for (i= 0, fd_ptr= udp_fd_table; iuf_flags & UFF_INUSE)) - continue; - if (fd_ptr->uf_port != udp_fd->uf_port) - continue; - flags= fd_ptr->uf_udpopt.nwuo_flags; - if ((flags & NWUO_LOCPORT_MASK) != NWUO_LP_SEL && - (flags & NWUO_LOCPORT_MASK) != NWUO_LP_SET) - continue; - if (fd_ptr->uf_udpopt.nwuo_locport != - newopt.nwuo_locport) - { - continue; - } - if ((flags & NWUO_ACC_MASK) != - (new_flags & NWUO_ACC_MASK)) - { - DBLOCK(1, printf( - "address inuse: new fd= %d, old_fd= %d, port= %u\n", - udp_fd-udp_fd_table, - fd_ptr-udp_fd_table, - newopt.nwuo_locport)); - - reply_thr_get(udp_fd, EADDRINUSE, TRUE); - return NW_OK; - } - } - } - - if (udp_fd->uf_flags & UFF_OPTSET) - unhash_fd(udp_fd); - - newopt.nwuo_flags= new_flags; - udp_fd->uf_udpopt= newopt; - - all_flags= new_en_flags | new_di_flags; - if ((all_flags & NWUO_ACC_MASK) && (all_flags & NWUO_LOCPORT_MASK) && - (all_flags & NWUO_LOCADDR_MASK) && - (all_flags & NWUO_BROAD_MASK) && - (all_flags & NWUO_REMPORT_MASK) && - (all_flags & NWUO_REMADDR_MASK) && - (all_flags & NWUO_RW_MASK) && - (all_flags & NWUO_IPOPT_MASK)) - udp_fd->uf_flags |= UFF_OPTSET; - else - { - udp_fd->uf_flags &= ~UFF_OPTSET; - } - - if (udp_fd->uf_flags & UFF_OPTSET) - hash_fd(udp_fd); - - reply_thr_get(udp_fd, NW_OK, TRUE); - return NW_OK; -} - -static udpport_t find_unused_port(int fd) -{ - udpport_t port, nw_port; - - for (port= 0x8000+fd; port < 0xffff-UDP_FD_NR; port+= UDP_FD_NR) - { - nw_port= htons(port); - if (is_unused_port(nw_port)) - return nw_port; - } - for (port= 0x8000; port < 0xffff; port++) - { - nw_port= htons(port); - if (is_unused_port(nw_port)) - return nw_port; - } - ip_panic(( "unable to find unused port (shouldn't occur)" )); - return 0; -} - -/* -reply_thr_put -*/ - -static void reply_thr_put(udp_fd, reply, for_ioctl) -udp_fd_t *udp_fd; -int reply; -int for_ioctl; -{ - int result; - - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, reply, - (acc_t *)0, for_ioctl); - assert(result == NW_OK); -} - -/* -reply_thr_get -*/ - -static void reply_thr_get(udp_fd, reply, for_ioctl) -udp_fd_t *udp_fd; -int reply; -int for_ioctl; -{ - acc_t *result; - result= (*udp_fd->uf_get_userdata)(udp_fd->uf_srfd, reply, - (size_t)0, for_ioctl); - assert (!result); -} - -static int is_unused_port(udpport_t port) -{ - int i; - udp_fd_t *udp_fd; - - for (i= 0, udp_fd= udp_fd_table; iuf_flags & UFF_OPTSET)) - continue; - if (udp_fd->uf_udpopt.nwuo_locport == port) - return FALSE; - } - return TRUE; -} - -static void read_ip_packets(udp_port) -udp_port_t *udp_port; -{ - int result; - - do - { - udp_port->up_flags |= UPF_READ_IP; - result= ip_read(udp_port->up_ipfd, UDP_MAX_DATAGRAM); - if (result == NW_SUSPEND) - { - udp_port->up_flags |= UPF_READ_SP; - return; - } -assert(result == NW_OK); - udp_port->up_flags &= ~UPF_READ_IP; - } while(!(udp_port->up_flags & UPF_READ_IP)); -} - - -static int udp_peek (udp_fd) -udp_fd_t *udp_fd; -{ - acc_t *pack, *tmp_acc, *next_acc; - int result; - - if (!(udp_fd->uf_flags & UFF_OPTSET)) - { - udp_fd->uf_flags &= ~UFF_IOCTL_IP; - reply_thr_put(udp_fd, EBADMODE, TRUE); - return NW_OK; - } - - if (udp_fd->uf_rdbuf_head) - { - if (get_time() <= udp_fd->uf_exp_tim) - { - pack= bf_cut(udp_fd->uf_rdbuf_head, 0, - sizeof(udp_io_hdr_t)); - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, - (size_t)0, pack, TRUE); - - udp_fd->uf_flags &= ~UFF_IOCTL_IP; - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, - result, (acc_t *)0, TRUE); - assert (result == 0); - return result; - } - tmp_acc= udp_fd->uf_rdbuf_head; - while (tmp_acc) - { - next_acc= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - tmp_acc= next_acc; - } - udp_fd->uf_rdbuf_head= NULL; - } - udp_fd->uf_flags |= UFF_PEEK_IP; - return NW_SUSPEND; -} - -static int udp_sel_read (udp_fd_t *udp_fd) -{ - acc_t *tmp_acc, *next_acc; - - if (!(udp_fd->uf_flags & UFF_OPTSET)) - return 1; /* Read will not block */ - - if (udp_fd->uf_rdbuf_head) - { - if (get_time() <= udp_fd->uf_exp_tim) - return 1; - - tmp_acc= udp_fd->uf_rdbuf_head; - while (tmp_acc) - { - next_acc= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - tmp_acc= next_acc; - } - udp_fd->uf_rdbuf_head= NULL; - } - return 0; -} - -static int udp_packet2user (udp_fd) -udp_fd_t *udp_fd; -{ - acc_t *pack, *tmp_pack; - udp_io_hdr_t *hdr; - int result, hdr_len; - size_t size, transf_size; - - pack= udp_fd->uf_rdbuf_head; - udp_fd->uf_rdbuf_head= pack->acc_ext_link; - - size= bf_bufsize (pack); - - if (udp_fd->uf_udpopt.nwuo_flags & NWUO_RWDATONLY) - { - - pack= bf_packIffLess (pack, UDP_IO_HDR_SIZE); - assert (pack->acc_length >= UDP_IO_HDR_SIZE); - - hdr= (udp_io_hdr_t *)ptr2acc_data(pack); -#if CONF_UDP_IO_NW_BYTE_ORDER - hdr_len= UDP_IO_HDR_SIZE+NTOHS(hdr->uih_ip_opt_len); -#else - hdr_len= UDP_IO_HDR_SIZE+hdr->uih_ip_opt_len; -#endif - - assert (size>= hdr_len); - size -= hdr_len; - tmp_pack= bf_cut(pack, hdr_len, size); - bf_afree(pack); - pack= tmp_pack; - } - - if (size>udp_fd->uf_rd_count) - { - tmp_pack= bf_cut (pack, 0, udp_fd->uf_rd_count); - bf_afree(pack); - pack= tmp_pack; - transf_size= udp_fd->uf_rd_count; - } - else - transf_size= size; - - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, - (size_t)0, pack, FALSE); - - if (result >= 0) { - if (size > transf_size) - result= EPACKSIZE; - else - result= transf_size; - } - - udp_fd->uf_flags &= ~UFF_READ_IP; - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, result, - (acc_t *)0, FALSE); - assert (result == 0); - - return result; -} - -static void udp_ip_arrived(port, pack, pack_size) -int port; -acc_t *pack; -size_t pack_size; -{ - udp_port_t *udp_port; - udp_fd_t *udp_fd, *share_fd; - acc_t *ip_hdr_acc, *udp_acc, *ipopt_pack, *no_ipopt_pack, *tmp_acc; - ip_hdr_t *ip_hdr; - udp_hdr_t *udp_hdr; - udp_io_hdr_t *udp_io_hdr; - size_t ip_hdr_size, udp_size, data_size, opt_size; - ipaddr_t src_addr, dst_addr, ipaddr; - udpport_t src_port, dst_port; - u8_t u16[2]; - u16_t chksum; - unsigned long dst_type, flags; - clock_t exp_tim; - int i, delivered, hash; - - udp_port= &udp_port_table[port]; - - ip_hdr_acc= bf_cut(pack, 0, IP_MIN_HDR_SIZE); - ip_hdr_acc= bf_packIffLess(ip_hdr_acc, IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_hdr_acc); - ip_hdr_size= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; - if (ip_hdr_size != IP_MIN_HDR_SIZE) - { - bf_afree(ip_hdr_acc); - ip_hdr_acc= bf_cut(pack, 0, ip_hdr_size); - ip_hdr_acc= bf_packIffLess(ip_hdr_acc, ip_hdr_size); - ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_hdr_acc); - } - - pack_size -= ip_hdr_size; - if (pack_size < UDP_HDR_SIZE) - { - if (pack_size == 0 && ip_hdr->ih_proto == 0) - { - /* IP layer reports new IP address */ - ipaddr= ip_hdr->ih_src; - udp_port->up_ipaddr= ipaddr; - DBLOCK(1, printf("udp_ip_arrived: using address "); - writeIpAddr(ipaddr); printf("\n")); - } - else - DBLOCK(1, printf("packet too small\n")); - - bf_afree(ip_hdr_acc); - bf_afree(pack); - return; - } - - udp_acc= bf_delhead(pack, ip_hdr_size); - pack= NULL; - - - udp_acc= bf_packIffLess(udp_acc, UDP_HDR_SIZE); - udp_hdr= (udp_hdr_t *)ptr2acc_data(udp_acc); - udp_size= ntohs(udp_hdr->uh_length); - if (udp_size > pack_size) - { - DBLOCK(1, printf("packet too large\n")); - - bf_afree(ip_hdr_acc); - bf_afree(udp_acc); - return; - } - - src_addr= ip_hdr->ih_src; - dst_addr= ip_hdr->ih_dst; - - if (udp_hdr->uh_chksum) - { - u16[0]= 0; - u16[1]= ip_hdr->ih_proto; - chksum= pack_oneCsum(udp_acc); - chksum= oneC_sum(chksum, (u16_t *)&src_addr, sizeof(ipaddr_t)); - chksum= oneC_sum(chksum, (u16_t *)&dst_addr, sizeof(ipaddr_t)); - chksum= oneC_sum(chksum, (u16_t *)u16, sizeof(u16)); - chksum= oneC_sum(chksum, (u16_t *)&udp_hdr->uh_length, - sizeof(udp_hdr->uh_length)); - if (~chksum & 0xffff) - { - DBLOCK(1, printf("checksum error in udp packet\n"); - printf("src ip_addr= "); - writeIpAddr(src_addr); - printf(" dst ip_addr= "); - writeIpAddr(dst_addr); - printf("\n"); - printf("packet chksum= 0x%x, sum= 0x%x\n", - udp_hdr->uh_chksum, chksum)); - - bf_afree(ip_hdr_acc); - bf_afree(udp_acc); - return; - } - } - - exp_tim= get_time() + UDP_READ_EXP_TIME; - src_port= udp_hdr->uh_src_port; - dst_port= udp_hdr->uh_dst_port; - - /* Send an ICMP port unreachable if the packet could not be - * delivered. - */ - delivered= 0; - - if (dst_addr == udp_port->up_ipaddr) - dst_type= NWUO_EN_LOC; - else - { - dst_type= NWUO_EN_BROAD; - - /* Don't send ICMP error packets for broadcast packets */ - delivered= 1; - } - - DBLOCK(0x20, printf("udp: got packet from "); - writeIpAddr(src_addr); - printf(".%u to ", ntohs(src_port)); - writeIpAddr(dst_addr); - printf(".%u\n", ntohs(dst_port))); - - no_ipopt_pack= bf_memreq(UDP_IO_HDR_SIZE); - udp_io_hdr= (udp_io_hdr_t *)ptr2acc_data(no_ipopt_pack); - udp_io_hdr->uih_src_addr= src_addr; - udp_io_hdr->uih_dst_addr= dst_addr; - udp_io_hdr->uih_src_port= src_port; - udp_io_hdr->uih_dst_port= dst_port; - data_size = udp_size-UDP_HDR_SIZE; -#if CONF_UDP_IO_NW_BYTE_ORDER - udp_io_hdr->uih_ip_opt_len= HTONS(0); - udp_io_hdr->uih_data_len= htons(data_size); -#else - udp_io_hdr->uih_ip_opt_len= 0; - udp_io_hdr->uih_data_len= data_size; -#endif - no_ipopt_pack->acc_next= bf_cut(udp_acc, UDP_HDR_SIZE, data_size); - - if (ip_hdr_size == IP_MIN_HDR_SIZE) - { - ipopt_pack= no_ipopt_pack; - ipopt_pack->acc_linkC++; - } - else - { - ipopt_pack= bf_memreq(UDP_IO_HDR_SIZE); - *(udp_io_hdr_t *)ptr2acc_data(ipopt_pack)= *udp_io_hdr; - udp_io_hdr= (udp_io_hdr_t *)ptr2acc_data(ipopt_pack); - opt_size = ip_hdr_size-IP_MIN_HDR_SIZE; -#if CONF_UDP_IO_NW_BYTE_ORDER - udp_io_hdr->uih_ip_opt_len= htons(opt_size); -#else - udp_io_hdr->uih_ip_opt_len= opt_size; -#endif - tmp_acc= bf_cut(ip_hdr_acc, (size_t)IP_MIN_HDR_SIZE, opt_size); - assert(tmp_acc->acc_linkC == 1); - assert(tmp_acc->acc_next == NULL); - ipopt_pack->acc_next= tmp_acc; - - tmp_acc->acc_next= no_ipopt_pack->acc_next; - if (tmp_acc->acc_next) - tmp_acc->acc_next->acc_linkC++; - } - - hash= dst_port; - hash ^= (hash >> 8); - hash &= (UDP_PORT_HASH_NR-1); - - for (i= 0; i<2; i++) - { - share_fd= NULL; - - udp_fd= (i == 0) ? udp_port->up_port_any : - udp_port->up_port_hash[hash]; - for (; udp_fd; udp_fd= udp_fd->uf_port_next) - { - if (i && udp_fd->uf_udpopt.nwuo_locport != dst_port) - continue; - - assert(udp_fd->uf_flags & UFF_INUSE); - assert(udp_fd->uf_flags & UFF_OPTSET); - - if (udp_fd->uf_port != udp_port) - continue; - - flags= udp_fd->uf_udpopt.nwuo_flags; - if (!(flags & dst_type)) - continue; - - if ((flags & NWUO_RP_SET) && - udp_fd->uf_udpopt.nwuo_remport != src_port) - { - continue; - } - - if ((flags & NWUO_RA_SET) && - udp_fd->uf_udpopt.nwuo_remaddr != src_addr) - { - continue; - } - - if (i) - { - /* Packet is considdered to be delivered */ - delivered= 1; - } - - if ((flags & NWUO_ACC_MASK) == NWUO_SHARED && - (!share_fd || !udp_fd->uf_rdbuf_head)) - { - share_fd= udp_fd; - continue; - } - - if (flags & NWUO_EN_IPOPT) - pack= ipopt_pack; - else - pack= no_ipopt_pack; - - pack->acc_linkC++; - udp_rd_enqueue(udp_fd, pack, exp_tim); - if (udp_fd->uf_flags & UFF_READ_IP) - udp_packet2user(udp_fd); - } - - if (share_fd) - { - flags= share_fd->uf_udpopt.nwuo_flags; - if (flags & NWUO_EN_IPOPT) - pack= ipopt_pack; - else - pack= no_ipopt_pack; - - pack->acc_linkC++; - udp_rd_enqueue(share_fd, pack, exp_tim); - if (share_fd->uf_flags & UFF_READ_IP) - udp_packet2user(share_fd); - } - } - - if (ipopt_pack) - bf_afree(ipopt_pack); - if (no_ipopt_pack) - bf_afree(no_ipopt_pack); - - if (!delivered) - { - DBLOCK(0x2, printf("udp: could not deliver packet from "); - writeIpAddr(src_addr); - printf(".%u to ", ntohs(src_port)); - writeIpAddr(dst_addr); - printf(".%u\n", ntohs(dst_port))); - - pack= bf_append(ip_hdr_acc, udp_acc); - ip_hdr_acc= NULL; - udp_acc= NULL; - icmp_snd_unreachable(udp_port->up_ipdev, pack, - ICMP_PORT_UNRCH); - return; - } - - assert (ip_hdr_acc); - bf_afree(ip_hdr_acc); - assert (udp_acc); - bf_afree(udp_acc); -} - -void udp_close(fd) -int fd; -{ - udp_fd_t *udp_fd; - acc_t *tmp_acc, *next_acc; - - udp_fd= &udp_fd_table[fd]; - - assert (udp_fd->uf_flags & UFF_INUSE); - - if (udp_fd->uf_flags & UFF_OPTSET) - unhash_fd(udp_fd); - - udp_fd->uf_flags= UFF_EMPTY; - tmp_acc= udp_fd->uf_rdbuf_head; - while (tmp_acc) - { - next_acc= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - tmp_acc= next_acc; - } - udp_fd->uf_rdbuf_head= NULL; -} - -int udp_write(int fd, size_t count) -{ - udp_fd_t *udp_fd; - - udp_fd= &udp_fd_table[fd]; - - if (!(udp_fd->uf_flags & UFF_OPTSET)) - { - reply_thr_get (udp_fd, EBADMODE, FALSE); - return NW_OK; - } - -assert (!(udp_fd->uf_flags & UFF_WRITE_IP)); - - udp_fd->uf_wr_count= count; - - udp_fd->uf_flags |= UFF_WRITE_IP; - - restart_write_fd(udp_fd); - - if (udp_fd->uf_flags & UFF_WRITE_IP) - { - DBLOCK(1, printf("replying NW_SUSPEND\n")); - - return NW_SUSPEND; - } - else - { - return NW_OK; - } -} - -static void restart_write_fd(udp_fd) -udp_fd_t *udp_fd; -{ - udp_port_t *udp_port; - acc_t *pack, *ip_hdr_pack, *udp_hdr_pack, *ip_opt_pack, *user_data; - udp_hdr_t *udp_hdr; - udp_io_hdr_t *udp_io_hdr; - ip_hdr_t *ip_hdr; - size_t ip_opt_size, user_data_size; - unsigned long flags; - u16_t chksum; - u8_t u16[2]; - int result; - - udp_port= udp_fd->uf_port; - - if (udp_port->up_flags & UPF_WRITE_IP) - { - udp_port->up_flags |= UPF_MORE2WRITE; - return; - } - -assert (udp_fd->uf_flags & UFF_WRITE_IP); - udp_fd->uf_flags &= ~UFF_WRITE_IP; - -assert (!udp_port->up_wr_pack); - - pack= (*udp_fd->uf_get_userdata)(udp_fd->uf_srfd, 0, - udp_fd->uf_wr_count, FALSE); - if (!pack) - { - udp_fd->uf_flags &= ~UFF_WRITE_IP; - reply_thr_get (udp_fd, EFAULT, FALSE); - return; - } - - flags= udp_fd->uf_udpopt.nwuo_flags; - - ip_hdr_pack= bf_memreq(IP_MIN_HDR_SIZE); - ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_hdr_pack); - - udp_hdr_pack= bf_memreq(UDP_HDR_SIZE); - udp_hdr= (udp_hdr_t *)ptr2acc_data(udp_hdr_pack); - - if (flags & NWUO_RWDATALL) - { - pack= bf_packIffLess(pack, UDP_IO_HDR_SIZE); - udp_io_hdr= (udp_io_hdr_t *)ptr2acc_data(pack); -#if CONF_UDP_IO_NW_BYTE_ORDER - ip_opt_size= ntohs(udp_io_hdr->uih_ip_opt_len); -#else - ip_opt_size= udp_io_hdr->uih_ip_opt_len; -#endif - if (UDP_IO_HDR_SIZE+ip_opt_size>udp_fd->uf_wr_count) - { - bf_afree(ip_hdr_pack); - bf_afree(udp_hdr_pack); - bf_afree(pack); - reply_thr_get (udp_fd, EINVAL, FALSE); - return; - } - if (ip_opt_size & 3) - { - bf_afree(ip_hdr_pack); - bf_afree(udp_hdr_pack); - bf_afree(pack); - reply_thr_get (udp_fd, EFAULT, FALSE); - return; - } - if (ip_opt_size) - ip_opt_pack= bf_cut(pack, UDP_IO_HDR_SIZE, ip_opt_size); - else - ip_opt_pack= 0; - user_data_size= udp_fd->uf_wr_count-UDP_IO_HDR_SIZE- - ip_opt_size; - user_data= bf_cut(pack, UDP_IO_HDR_SIZE+ip_opt_size, - user_data_size); - bf_afree(pack); - } - else - { - udp_io_hdr= 0; - ip_opt_size= 0; - user_data_size= udp_fd->uf_wr_count; - ip_opt_pack= 0; - user_data= pack; - } - - ip_hdr->ih_vers_ihl= (IP_MIN_HDR_SIZE+ip_opt_size) >> 2; - ip_hdr->ih_tos= UDP_TOS; - ip_hdr->ih_flags_fragoff= HTONS(UDP_IP_FLAGS); - ip_hdr->ih_ttl= IP_DEF_TTL; - ip_hdr->ih_proto= IPPROTO_UDP; - if (flags & NWUO_RA_SET) - { - ip_hdr->ih_dst= udp_fd->uf_udpopt.nwuo_remaddr; - } - else - { -assert (udp_io_hdr); - ip_hdr->ih_dst= udp_io_hdr->uih_dst_addr; - } - - if ((flags & NWUO_LOCPORT_MASK) != NWUO_LP_ANY) - udp_hdr->uh_src_port= udp_fd->uf_udpopt.nwuo_locport; - else - { -assert (udp_io_hdr); - udp_hdr->uh_src_port= udp_io_hdr->uih_src_port; - } - - if (flags & NWUO_RP_SET) - udp_hdr->uh_dst_port= udp_fd->uf_udpopt.nwuo_remport; - else - { -assert (udp_io_hdr); - udp_hdr->uh_dst_port= udp_io_hdr->uih_dst_port; - } - - udp_hdr->uh_length= htons(UDP_HDR_SIZE+user_data_size); - udp_hdr->uh_chksum= 0; - - udp_hdr_pack->acc_next= user_data; - chksum= pack_oneCsum(udp_hdr_pack); - chksum= oneC_sum(chksum, (u16_t *)&udp_fd->uf_port->up_ipaddr, - sizeof(ipaddr_t)); - chksum= oneC_sum(chksum, (u16_t *)&ip_hdr->ih_dst, sizeof(ipaddr_t)); - u16[0]= 0; - u16[1]= IPPROTO_UDP; - chksum= oneC_sum(chksum, (u16_t *)u16, sizeof(u16)); - chksum= oneC_sum(chksum, (u16_t *)&udp_hdr->uh_length, sizeof(u16_t)); - if (~chksum) - chksum= ~chksum; - udp_hdr->uh_chksum= chksum; - - if (ip_opt_pack) - { - ip_opt_pack= bf_packIffLess(ip_opt_pack, ip_opt_size); - ip_opt_pack->acc_next= udp_hdr_pack; - udp_hdr_pack= ip_opt_pack; - } - ip_hdr_pack->acc_next= udp_hdr_pack; - -assert (!udp_port->up_wr_pack); -assert (!(udp_port->up_flags & UPF_WRITE_IP)); - - udp_port->up_wr_pack= ip_hdr_pack; - udp_port->up_flags |= UPF_WRITE_IP; - result= ip_write(udp_port->up_ipfd, bf_bufsize(ip_hdr_pack)); - if (result == NW_SUSPEND) - { - udp_port->up_flags |= UPF_WRITE_SP; - udp_fd->uf_flags |= UFF_WRITE_IP; - udp_port->up_write_fd= udp_fd; - } - else if (result<0) - reply_thr_get(udp_fd, result, FALSE); - else - reply_thr_get (udp_fd, udp_fd->uf_wr_count, FALSE); -} - -static u16_t pack_oneCsum(pack) -acc_t *pack; -{ - u16_t prev; - int odd_byte; - char *data_ptr; - int length; - char byte_buf[2]; - - assert (pack); - - prev= 0; - - odd_byte= FALSE; - for (; pack; pack= pack->acc_next) - { - - data_ptr= ptr2acc_data(pack); - length= pack->acc_length; - - if (!length) - continue; - if (odd_byte) - { - byte_buf[1]= *data_ptr; - prev= oneC_sum(prev, (u16_t *)byte_buf, 2); - data_ptr++; - length--; - odd_byte= FALSE; - } - if (length & 1) - { - odd_byte= TRUE; - length--; - byte_buf[0]= data_ptr[length]; - } - if (!length) - continue; - prev= oneC_sum (prev, (u16_t *)data_ptr, length); - } - if (odd_byte) - { - byte_buf[1]= 0; - prev= oneC_sum (prev, (u16_t *)byte_buf, 1); - } - return prev; -} - -static void udp_restart_write_port(udp_port ) -udp_port_t *udp_port; -{ - udp_fd_t *udp_fd; - int i; - -assert (!udp_port->up_wr_pack); -assert (!(udp_port->up_flags & (UPF_WRITE_IP|UPF_WRITE_SP))); - - while (udp_port->up_flags & UPF_MORE2WRITE) - { - udp_port->up_flags &= ~UPF_MORE2WRITE; - - for (i= 0, udp_fd= udp_port->up_next_fd; iuf_flags & UFF_INUSE)) - continue; - if (!(udp_fd->uf_flags & UFF_WRITE_IP)) - continue; - if (udp_fd->uf_port != udp_port) - continue; - restart_write_fd(udp_fd); - if (udp_port->up_flags & UPF_WRITE_IP) - { - udp_port->up_next_fd= udp_fd+1; - udp_port->up_flags |= UPF_MORE2WRITE; - return; - } - } - } -} - -int udp_cancel(fd, which_operation) -int fd; -int which_operation; -{ - udp_fd_t *udp_fd; - - DBLOCK(0x10, printf("udp_cancel(%d, %d)\n", fd, which_operation)); - - udp_fd= &udp_fd_table[fd]; - - switch (which_operation) - { - case SR_CANCEL_READ: -assert (udp_fd->uf_flags & UFF_READ_IP); - udp_fd->uf_flags &= ~UFF_READ_IP; - reply_thr_put(udp_fd, EINTR, FALSE); - break; - case SR_CANCEL_WRITE: -assert (udp_fd->uf_flags & UFF_WRITE_IP); - udp_fd->uf_flags &= ~UFF_WRITE_IP; - if (udp_fd->uf_port->up_write_fd == udp_fd) - udp_fd->uf_port->up_write_fd= NULL; - reply_thr_get(udp_fd, EINTR, FALSE); - break; - case SR_CANCEL_IOCTL: -assert (udp_fd->uf_flags & UFF_IOCTL_IP); - udp_fd->uf_flags &= ~UFF_IOCTL_IP; - udp_fd->uf_flags &= ~UFF_PEEK_IP; - reply_thr_get(udp_fd, EINTR, TRUE); - break; - default: - ip_panic(( "got unknown cancel request" )); - } - return NW_OK; -} - -static void udp_buffree (priority) -int priority; -{ - int i; - udp_fd_t *udp_fd; - acc_t *tmp_acc; - - if (priority == UDP_PRI_FDBUFS_EXTRA) - { - for (i=0, udp_fd= udp_fd_table; iuf_rdbuf_head && - udp_fd->uf_rdbuf_head->acc_ext_link) - { - tmp_acc= udp_fd->uf_rdbuf_head; - udp_fd->uf_rdbuf_head= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - } - } - } - - if (priority == UDP_PRI_FDBUFS) - { - for (i=0, udp_fd= udp_fd_table; iuf_rdbuf_head) - { - tmp_acc= udp_fd->uf_rdbuf_head; - udp_fd->uf_rdbuf_head= tmp_acc->acc_ext_link; - bf_afree(tmp_acc); - } - } - } -} - -static void udp_rd_enqueue(udp_fd, pack, exp_tim) -udp_fd_t *udp_fd; -acc_t *pack; -clock_t exp_tim; -{ - acc_t *tmp_acc; - int result; - - if (pack->acc_linkC != 1) - { - tmp_acc= bf_dupacc(pack); - bf_afree(pack); - pack= tmp_acc; - } - pack->acc_ext_link= NULL; - if (udp_fd->uf_rdbuf_head == NULL) - { - udp_fd->uf_exp_tim= exp_tim; - udp_fd->uf_rdbuf_head= pack; - } - else - udp_fd->uf_rdbuf_tail->acc_ext_link= pack; - udp_fd->uf_rdbuf_tail= pack; - - if (udp_fd->uf_flags & UFF_PEEK_IP) - { - pack= bf_cut(udp_fd->uf_rdbuf_head, 0, - sizeof(udp_io_hdr_t)); - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, - (size_t)0, pack, TRUE); - - udp_fd->uf_flags &= ~UFF_IOCTL_IP; - udp_fd->uf_flags &= ~UFF_PEEK_IP; - result= (*udp_fd->uf_put_userdata)(udp_fd->uf_srfd, - result, (acc_t *)0, TRUE); - assert (result == 0); - } - - if (udp_fd->uf_flags & UFF_SEL_READ) - { - udp_fd->uf_flags &= ~UFF_SEL_READ; - if (udp_fd->uf_select_res) - udp_fd->uf_select_res(udp_fd->uf_srfd, SR_SELECT_READ); - else - printf("udp_rd_enqueue: no select_res\n"); - } -} - -static void hash_fd(udp_fd) -udp_fd_t *udp_fd; -{ - udp_port_t *udp_port; - int hash; - - udp_port= udp_fd->uf_port; - if ((udp_fd->uf_udpopt.nwuo_flags & NWUO_LOCPORT_MASK) == - NWUO_LP_ANY) - { - udp_fd->uf_port_next= udp_port->up_port_any; - udp_port->up_port_any= udp_fd; - } - else - { - hash= udp_fd->uf_udpopt.nwuo_locport; - hash ^= (hash >> 8); - hash &= (UDP_PORT_HASH_NR-1); - - udp_fd->uf_port_next= udp_port->up_port_hash[hash]; - udp_port->up_port_hash[hash]= udp_fd; - } -} - -static void unhash_fd(udp_fd) -udp_fd_t *udp_fd; -{ - udp_port_t *udp_port; - udp_fd_t *prev, *curr, **udp_fd_p; - int hash; - - udp_port= udp_fd->uf_port; - if ((udp_fd->uf_udpopt.nwuo_flags & NWUO_LOCPORT_MASK) == - NWUO_LP_ANY) - { - udp_fd_p= &udp_port->up_port_any; - } - else - { - hash= udp_fd->uf_udpopt.nwuo_locport; - hash ^= (hash >> 8); - hash &= (UDP_PORT_HASH_NR-1); - - udp_fd_p= &udp_port->up_port_hash[hash]; - } - for (prev= NULL, curr= *udp_fd_p; curr; - prev= curr, curr= curr->uf_port_next) - { - if (curr == udp_fd) - break; - } - assert(curr); - if (prev) - prev->uf_port_next= curr->uf_port_next; - else - *udp_fd_p= curr->uf_port_next; -} - -#ifdef BUF_CONSISTENCY_CHECK -static void udp_bufcheck() -{ - int i; - udp_port_t *udp_port; - udp_fd_t *udp_fd; - acc_t *tmp_acc; - - for (i= 0, udp_port= udp_port_table; iup_wr_pack) - bf_check_acc(udp_port->up_wr_pack); - } - - for (i= 0, udp_fd= udp_fd_table; iuf_rdbuf_head; tmp_acc; - tmp_acc= tmp_acc->acc_ext_link) - { - bf_check_acc(tmp_acc); - } - } -} -#endif - -/* - * $PchId: udp.c,v 1.25 2005/06/28 14:14:44 philip Exp $ - */ diff --git a/minix/net/inet/generic/udp.h b/minix/net/inet/generic/udp.h deleted file mode 100644 index 4a0b58290..000000000 --- a/minix/net/inet/generic/udp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -udp.h - -Copyright 1995 Philip Homburg -*/ - -#ifndef UDP_H -#define UDP_H - -#define UDP_DEF_OPT NWUO_NOFLAGS -#define UDP_MAX_DATAGRAM 40000 /* 8192 */ -#define UDP_READ_EXP_TIME (10L * HZ) -#define UDP_TOS 0 -#define UDP_IP_FLAGS 0 - -#define UDP0 0 - -struct acc; - -void udp_prep ARGS(( void )); -void udp_init ARGS(( void )); -int udp_open ARGS(( int port, int srfd, - get_userdata_t get_userdata, put_userdata_t put_userdata, - put_pkt_t put_pkt, select_res_t select_res )); -int udp_ioctl ARGS(( int fd, ioreq_t req )); -int udp_read ARGS(( int fd, size_t count )); -int udp_write ARGS(( int fd, size_t count )); -void udp_close ARGS(( int fd )); -int udp_cancel ARGS(( int fd, int which_operation )); - -#endif /* UDP_H */ - - -/* - * $PchId: udp.h,v 1.9 2005/06/28 14:12:05 philip Exp $ - */ diff --git a/minix/net/inet/generic/udp_int.h b/minix/net/inet/generic/udp_int.h deleted file mode 100644 index f2783cb7d..000000000 --- a/minix/net/inet/generic/udp_int.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -generic/udp_int.h - -Created: March 2001 by Philip Homburg - -Some internals of the UDP module -*/ - -#define UDP_FD_NR (4*IP_PORT_MAX) -#define UDP_PORT_HASH_NR 16 /* Must be a power of 2 */ - -typedef struct udp_port -{ - int up_flags; - int up_state; - int up_ipfd; - int up_ipdev; - acc_t *up_wr_pack; - ipaddr_t up_ipaddr; - struct udp_fd *up_next_fd; - struct udp_fd *up_write_fd; - struct udp_fd *up_port_any; - struct udp_fd *up_port_hash[UDP_PORT_HASH_NR]; -} udp_port_t; - -#define UPF_EMPTY 0x0 -#define UPF_WRITE_IP 0x1 -#define UPF_WRITE_SP 0x2 -#define UPF_READ_IP 0x4 -#define UPF_READ_SP 0x8 -#define UPF_SUSPEND 0x10 -#define UPF_MORE2WRITE 0x20 - -#define UPS_EMPTY 0 -#define UPS_SETPROTO 1 -#define UPS_GETCONF 2 -#define UPS_MAIN 3 -#define UPS_ERROR 4 - -typedef struct udp_fd -{ - int uf_flags; - udp_port_t *uf_port; - ioreq_t uf_ioreq; - int uf_srfd; - nwio_udpopt_t uf_udpopt; - get_userdata_t uf_get_userdata; - put_userdata_t uf_put_userdata; - select_res_t uf_select_res; - acc_t *uf_rdbuf_head; - acc_t *uf_rdbuf_tail; - size_t uf_rd_count; - size_t uf_wr_count; - clock_t uf_exp_tim; - struct udp_fd *uf_port_next; -} udp_fd_t; - -#define UFF_EMPTY 0x0 -#define UFF_INUSE 0x1 -#define UFF_IOCTL_IP 0x2 -#define UFF_READ_IP 0x4 -#define UFF_WRITE_IP 0x8 -#define UFF_OPTSET 0x10 -#define UFF_PEEK_IP 0x20 -#define UFF_SEL_READ 0x40 -#define UFF_SEL_WRITE 0x80 - -EXTERN udp_port_t *udp_port_table; -EXTERN udp_fd_t udp_fd_table[UDP_FD_NR]; - -/* - * $PchId: udp_int.h,v 1.4 2004/08/03 11:12:01 philip Exp $ - */ diff --git a/minix/net/inet/inet.8 b/minix/net/inet/inet.8 deleted file mode 100644 index a61ac3f82..000000000 --- a/minix/net/inet/inet.8 +++ /dev/null @@ -1,145 +0,0 @@ -.TH INET 8 -.SH NAME -inet, inet.conf \- TCP/IP server -.SH SYNOPSIS -.B inet -.SH DESCRIPTION -.de SP -.if t .sp 0.4 -.if n .sp -.. -.B Inet -is the TCP/IP server. It is a device driver that interfaces between the -file server and the low level ethernet device driver. The interface to this -server is described in -.BR ip (4). -.PP -.B Inet -starts as a normal process, reads a the configuration file -.B /etc/inet.conf -to see what it should do, and uses a few special low level system calls -to turn itself into a server. The format of the configuration file is as -follows: -.SS Configuration -The inet configuration file is fairly simple, here is an example: -.PP -.RS -.ft C -.nf -eth0 DP8390 0 { default; }; -psip1; -.fi -.ft P -.RS -.PP -It tells that network 0 (the one containing devices -.BR eth0 , -.BR ip0 , -.BR tcp0 -and -.BR udp0 ) -uses the ethernet device driver handled -by driver "DP8390" instance 0. This network is marked as the default -network, so most programs use it through the unnumbered devices like -.B /dev/tcp -or -.BR /dev/udp . -Network 1 is a Pseudo IP network that can be used for -a serial IP over a modem for instance. -.PP -The configuration file uses a simple line-based format. -Each network definition has to be fully on its own line. -Empty lines and lines that start with a `#' symbol are ignored. -The following network definitions are possible: -.PP -.BI eth N -.I driver instance -.RI { options }; -.RS -This sets up an ethernet with device name -.BI /dev/eth N\fR, -built on the given ethernet device driver with the given instance number. -(If there are two network cards of the same type -then they will be managed by instance 0 and 1 of the corresponding driver.) -.br -.RE -.PP -.BI eth N -.B vlan -.I id -.BI eth M -.RI { options }; -\0\0\0\0 -.RS -The ethernet -.BI eth N -uses VLAN number -.I id -and is built on ethernet -.BI eth M\fR. -A packet given to this network has a VLAN tag prefixed to it and is then -handed over to another ethernet for transmission. Likewise a packet on -that ethernet carrying the appropriate VLAN tag has this tag removed and is -sent on to this network. The VLAN ethernet behaves like an ordinary ethernet -as far as applications are concerned. -.RE -.PP -.BI psip N -.RI { options }; -.RS -Creates pseudo IP network -.BI /dev/psip N\fR, -usable for IP over serial lines, tunnels and whatnot. -.RE -.SH OPTIONS -Some options can be given between braces. -.PP -.BR default ; -.RS -Mark this network as the default network. Exactly one of the networks must -be so marked. -When -.B inet -is started it will check and create all the necessary network devices before -becoming a server. To know what major device number to use it checks -.BR /dev/ip , -so that device must already exist. It can be created by -.B MAKEDEV -if need be. -.RE -.PP -.BR "no ip" ; -.br -.BR "no tcp" ; -.br -.BR "no udp" ; -.RS -These options turn the IP, TCP, or UDP layer off. Inet will not enable the -devices for these layers, and will deactivate code for these layers. -Disabling IP will also disable TCP or UDP, because they need IP to function. -An ethernet without an IP layer can be used as for stealth listening. An IP -network without TCP or UDP can be used to pester students into creating the -missing functionality. Keeps them off the streets, and maybe they'll learn -something. -.RE -.SH "SEE ALSO" -.BR ip (4), -.BR boot (8). -.SH NOTES -The number of networks that can be defined are 2 (Minix-86), 4 (Minix-386) -or 16 (Minix-vmd). This limits both the total number and the highest -device number you can use. -.PP -Getting a network administrator to give you a trunk or multi-VLAN port to -run multiple networks on can be a challenge. It questions their idea that -VLANs are separate networks, while in reality it is just one big ethernet. -.SH ACKNOWLEDGMENTS -Cindy Crawford, for providing invaluable help debugging this server. -.SH AUTHOR -.ta \w'Manual:'u+2n -Code: Philip Homburg -.br -Manual: Kees J. Bot - -.\" -.\" $PchId: inet.8,v 1.6 2001/10/08 19:01:35 philip Exp $ diff --git a/minix/net/inet/inet.c b/minix/net/inet/inet.c deleted file mode 100644 index fb316673c..000000000 --- a/minix/net/inet/inet.c +++ /dev/null @@ -1,370 +0,0 @@ -/* this file contains the interface of the network software with rest of - minix. Furthermore it contains the main loop of the network task. - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mq.h" -#include "qp.h" -#include "proto.h" -#include "generic/type.h" - -#include "generic/arp.h" -#include "generic/assert.h" -#include "generic/buf.h" -#include "generic/clock.h" -#include "generic/eth.h" -#include "generic/event.h" -#include "generic/ip.h" -#include "generic/psip.h" -#include "generic/rand256.h" -#include "generic/sr.h" -#include "generic/tcp.h" -#include "generic/udp.h" - -THIS_FILE - -#define RANDOM_DEV_NAME "/dev/random" - -endpoint_t this_proc; /* Process number of this server. */ - -/* Killing Solaris */ -int killer_inet= 0; - -#ifdef BUF_CONSISTENCY_CHECK -extern int inet_buf_debug; -#endif - -#if HZ_DYNAMIC -u32_t system_hz; -#endif - -static void nw_conf(void); -static void nw_init(void); -static void ds_event(void); - -/* SEF functions and variables. */ -static void sef_local_startup(void); -static int sef_cb_init_fresh(int type, sef_init_info_t *info); - -int main(int argc, char *argv[]) -{ - message mess; - int ipc_status; - int r; - - /* SEF local startup. */ - sef_local_startup(); - - while (TRUE) - { -#ifdef BUF_CONSISTENCY_CHECK - if (inet_buf_debug) - { - static int buf_debug_count= 0; - - if (++buf_debug_count >= inet_buf_debug) - { - buf_debug_count= 0; - if (!bf_consistency_check()) - break; - } - } -#endif - if (ev_head) - { - ev_process(); - continue; - } - if (clck_call_expire) - { - clck_expire_timers(); - continue; - } - - r= sef_receive_status(ANY, &mess, &ipc_status); - if (r<0) - { - ip_panic(("unable to receive: %d", r)); - } - reset_time(); - if (mess.m_source == VFS_PROC_NR) - { - sr_rec(&mess, ipc_status); - } - else if (is_ipc_notify(ipc_status)) - { - if (mess.m_source == CLOCK) - { - clck_tick(&mess); - } - else if (mess.m_source == DS_PROC_NR) - { - /* DS notifies us of an event. */ - ds_event(); - } - else - { - printf("inet: got unexpected notify from %d\n", - mess.m_source); - } - } - else if (mess.m_source == MIB_PROC_NR) - { - rmib_process(&mess, ipc_status); - } - else if (mess.m_type == DL_CONF_REPLY || - mess.m_type == DL_TASK_REPLY || - mess.m_type == DL_STAT_REPLY) - { - eth_rec(&mess); - } - else - { - printf("inet: got bad message type 0x%x from %d\n", - mess.m_type, mess.m_source); - } - } - ip_panic(("task is not allowed to terminate")); - return 1; -} - -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -static void sef_local_startup() -{ - /* Register init callbacks. */ - sef_setcb_init_fresh(sef_cb_init_fresh); - sef_setcb_init_restart(sef_cb_init_fresh); - - /* Let SEF perform startup. */ - sef_startup(); -} - -/*===========================================================================* - * sef_cb_init_fresh * - *===========================================================================*/ -static int sef_cb_init_fresh(int type, sef_init_info_t *info) -{ -/* Initialize the inet server. */ - int r; - int timerand, fd; - u8_t randbits[32]; - struct timeval tv; - -#if DEBUG - printf("Starting inet...\n"); - printf("%s\n", version); -#endif - -#if HZ_DYNAMIC - system_hz = sys_hz(); -#endif - - /* Read configuration. */ - nw_conf(); - - /* Get a random number */ - timerand= 1; - fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK); - if (fd != -1) - { - r= read(fd, randbits, sizeof(randbits)); - if (r == sizeof(randbits)) - timerand= 0; - else - { - printf("inet: unable to read random data from %s: %s\n", - RANDOM_DEV_NAME, r == -1 ? strerror(errno) : - r == 0 ? "EOF" : "not enough data"); - } - close(fd); - } - else - { - printf("inet: unable to open random device %s: %s\n", - RANDOM_DEV_NAME, strerror(errno)); - } - if (timerand) - { - printf("inet: using current time for random-number seed\n"); - r= gettimeofday(&tv, NULL); - if (r == -1) - { - printf("sysutime failed: %s\n", strerror(errno)); - exit(1); - } - memcpy(randbits, &tv, sizeof(tv)); - } - init_rand256(randbits); - - /* Our new identity as a server. */ - this_proc= info->endpoint; - -#ifdef BUF_CONSISTENCY_CHECK - inet_buf_debug= (getenv("inetbufdebug") && - (strcmp(getenv("inetbufdebug"), "on") == 0)); - inet_buf_debug= 100; - if (inet_buf_debug) - { - ip_warning(( "buffer consistency check enabled" )); - } -#endif - - if (getenv("killerinet")) - { - ip_warning(( "killer inet active" )); - killer_inet= 1; - } - - nw_init(); - - /* Subscribe to driver events for network drivers. */ - r = ds_subscribe("drv\\.net\\..*", DSF_INITIAL | DSF_OVERWRITE); - if(r != OK) { - ip_panic(("inet: can't subscribe to driver events")); - } - - /* Drop privileges. */ - if (setuid(SERVICE_UID) != 0) - printf("inet: warning, unable to drop privileges\n"); - - /* Announce we are up. INET announces its presence to VFS just like - * any other character driver. - */ - chardriver_announce(); - - /* Register net.route RMIB subtree with the MIB service. */ - rtinfo_init(); - - return(OK); -} - -static void nw_conf() -{ - read_conf(); - eth_prep(); - arp_prep(); - psip_prep(); - ip_prep(); - tcp_prep(); - udp_prep(); -} - -static void nw_init() -{ - mq_init(); - bf_init(); - clck_init(); - sr_init(); - qp_init(); - eth_init(); - arp_init(); - psip_init(); - ip_init(); - tcp_init(); - udp_init(); -} - -/*===========================================================================* - * ds_event * - *===========================================================================*/ -static void ds_event() -{ - char key[DS_MAX_KEYLEN]; - char *driver_prefix = (char *) "drv.net."; - char *label; - u32_t value; - int type; - endpoint_t owner_endpoint; - int r; - int prefix_len; - - prefix_len = strlen(driver_prefix); - - /* We may get one notification for multiple updates from DS. Get events - * and owners from DS, until DS tells us that there are no more. - */ - while ((r = ds_check(key, &type, &owner_endpoint)) == OK) { - r = ds_retrieve_u32(key, &value); - if(r != OK) { - printf("inet: ds_event: ds_retrieve_u32 failed\n"); - return; - } - - /* Only check for network driver up events. */ - if(strncmp(key, driver_prefix, prefix_len) - || value != DS_DRIVER_UP) { - return; - } - - /* The driver label comes after the prefix. */ - label = key + prefix_len; - - /* A driver is (re)started. */ - eth_check_driver(label, owner_endpoint); - } - - if(r != ENOENT) - printf("inet: ds_event: ds_check failed: %d\n", r); -} - -void panic0(file, line) -char *file; -int line; -{ - printf("panic at %s, %d: ", file, line); -} - -__dead -void inet_panic(void) -{ - printf("\ninet stacktrace: "); - util_stacktrace(); - (panic)("aborted due to a panic"); - for(;;); -} - -#if !NDEBUG -__dead -void bad_assertion(file, line, what) -char *file; -int line; -char *what; -{ - panic0(file, line); - printf("assertion \"%s\" failed", what); - panic("help"); -} - - -__dead -void bad_compare(file, line, lhs, what, rhs) -char *file; -int line; -int lhs; -char *what; -int rhs; -{ - panic0(file, line); - printf("compare (%d) %s (%d) failed", lhs, what, rhs); - panic("help"); -} -#endif /* !NDEBUG */ - -/* - * $PchId: inet.c,v 1.23 2005/06/28 14:27:22 philip Exp $ - */ diff --git a/minix/net/inet/inet.conf b/minix/net/inet/inet.conf deleted file mode 100644 index 657b23b46..000000000 --- a/minix/net/inet/inet.conf +++ /dev/null @@ -1,5 +0,0 @@ -service inet -{ - uid 0; -}; - diff --git a/minix/net/inet/inet.h b/minix/net/inet/inet.h deleted file mode 100644 index a078f4230..000000000 --- a/minix/net/inet/inet.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -inet/inet.h - -Created: Dec 30, 1991 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__INET_H -#define INET__INET_H - -#define _SYSTEM 1 /* get OK and negative error codes */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define _NORETURN /* Should be non empty for GCC */ - -typedef unsigned long ioreq_t; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "const.h" -#include "inet_config.h" - -#define PUBLIC -#define EXTERN extern -#define PRIVATE static -#define FORWARD static - -#define THIS_FILE -#define this_file __FILE__ - -void panic0(char *file, int line); -void inet_panic(void) _NORETURN; - -#if 0 -#define ip_panic(print_list) \ - (panic0(this_file, __LINE__), printf print_list, panic()) -#define panic() inet_panic() -#else -#define ip_panic(print_list) do { panic print_list; } while(0) -#endif - -#if DEBUG -#define ip_warning(print_list) \ - ( \ - printf("warning at %s, %d: ", this_file, __LINE__), \ - printf print_list, \ - printf("\ninet stacktrace: "), \ - util_stacktrace() \ - ) -#else -#define ip_warning(print_list) ((void) 0) -#endif - -#define DBLOCK(level, code) \ - do { if ((level) & DEBUG) { where(); code; } } while(0) -#define DIFBLOCK(level, condition, code) \ - do { if (((level) & DEBUG) && (condition)) \ - { where(); code; } } while(0) - -extern endpoint_t this_proc; -extern char version[]; - -#ifndef HZ -EXTERN u32_t system_hz; -#define HZ system_hz -#define HZ_DYNAMIC 1 -#endif - -#endif /* INET__INET_H */ - -/* - * $PchId: inet.h,v 1.16 2005/06/28 14:27:54 philip Exp $ - */ diff --git a/minix/net/inet/inet_config.c b/minix/net/inet/inet_config.c deleted file mode 100644 index b7b6595cf..000000000 --- a/minix/net/inet/inet_config.c +++ /dev/null @@ -1,434 +0,0 @@ -/* -inet/inet_config.c - -Created: Nov 11, 1992 by Philip Homburg - -Modified: Apr 07, 2001 by Kees J. Bot - Read the configuration file and fill in the xx_conf[] arrays. - -Copyright 1995 Philip Homburg -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "inet_config.h" -#include "inet.h" - -THIS_FILE - -struct eth_conf eth_conf[IP_PORT_MAX]; -struct psip_conf psip_conf[IP_PORT_MAX]; -struct ip_conf ip_conf[IP_PORT_MAX]; -struct tcp_conf tcp_conf[IP_PORT_MAX]; -struct udp_conf udp_conf[IP_PORT_MAX]; -dev_t ip_dev; - -int eth_conf_nr; -int psip_conf_nr; -int ip_conf_nr; -int tcp_conf_nr; -int udp_conf_nr; - -int ip_forward_directed_bcast= 0; /* Default is off */ - -static u8_t iftype[IP_PORT_MAX]; /* Interface in use as? */ -static int ifdefault= -1; /* Default network interface. */ - -__dead -static void fatal(char *label) -{ - printf("init: %s: %s\n", label, strerror(errno)); - exit(1); -} - -static void check_rm(char *device) -/* Check if a device is not among the living. */ -{ - if (unlink(device) < 0) { - if (errno == ENOENT) return; - fatal(device); - } - printf("rm %s\n", device); -} - -static void check_mknod(char *device, mode_t mode, int minor) -/* Check if a device exists with the proper device number. */ -{ - struct stat st; - dev_t dev; - - dev= makedev(major(ip_dev), minor); - - if (stat(device, &st) < 0) { - if (errno != ENOENT) fatal(device); - } else { - if (S_ISCHR(st.st_mode) && st.st_rdev == dev) return; - if (unlink(device) < 0) fatal(device); - } - - if (mknod(device, S_IFCHR | mode, dev) < 0) fatal(device); - printf("mknod %s c %d %d\n", device, major(ip_dev), minor); -} - -static void check_ln(char *old, char *new) -/* Check if 'old' and 'new' are still properly linked. */ -{ - struct stat st_old, st_new; - - if (stat(old, &st_old) < 0) fatal(old); - if (stat(new, &st_new) < 0) { - if (errno != ENOENT) fatal(new); - } else { - if (st_new.st_dev == st_old.st_dev - && st_new.st_ino == st_old.st_ino) { - return; - } - if (unlink(new) < 0) fatal(new); - } - - if (link(old, new) < 0) fatal(new); - printf("ln %s %s\n", old, new); -} - -static void check_dev(int type, int ifno) -/* Check if the device group with interface number 'ifno' exists and has the - * proper device numbers. If 'type' is -1 then the device group must be - * removed. - */ -{ - static struct devlist { - char *defname; - mode_t mode; - u8_t minor_off; - } devlist[5] = { - { (char *) "/dev/eth", 0600, ETH_DEV_OFF }, - { (char *) "/dev/psip", 0600, PSIP_DEV_OFF }, - { (char *) "/dev/ip", 0600, IP_DEV_OFF }, - { (char *) "/dev/tcp", 0666, TCP_DEV_OFF }, - { (char *) "/dev/udp", 0666, UDP_DEV_OFF }, - }; - struct devlist *dvp; - int i; - char device[sizeof("/dev/psip99")]; - char *dp; - - for (i= 0; i < sizeof(devlist) / sizeof(devlist[0]); i++) { - dvp= &devlist[i]; - strcpy(device, dvp->defname); - dp= device + strlen(device); - if (ifno >= 10) *dp++ = '0' + (ifno / 10); - *dp++ = '0' + (ifno % 10); - *dp = 0; - - if (type == 0 - || (i == 0 && type != NETTYPE_ETH) - || (i == 1 && type != NETTYPE_PSIP) - ) { - check_rm(device); - if (ifno == ifdefault) check_rm(dvp->defname); - } else { - check_mknod(device, dvp->mode, - if2minor(ifno, dvp->minor_off)); - if (ifno == ifdefault) check_ln(device, dvp->defname); - } - } - check_mknod(IPSTAT_DEV, IPSTAT_MODE, IPSTAT_MINOR); -} - -static int cfg_fd; -static char word[16]; -static unsigned char line[256], *lineptr; -static unsigned linenr; - -__dead -static void error(void) -{ - printf("inet: error on line %u\n", linenr); - exit(1); -} - -static int nextline(void) -{ - /* Read a line from the configuration file, to be used by subsequent - * token() calls. Skip empty lines, and lines where the first character - * after leading "whitespace" is '#'. The last line of the file need - * not be terminated by a newline. Return 1 if a line was read in - * successfully, and 0 on EOF or error. - */ - unsigned char *lp, c; - int r, skip; - - lineptr = lp = line; - linenr++; - skip = -1; - - while ((r = read(cfg_fd, &c, 1)) == 1) { - if (c == '\n') { - if (skip == 0) - break; - - linenr++; - skip = -1; - continue; - } - - if (skip == -1 && c > ' ') - skip = (c == '#'); - - if (skip == 0 && lp < (unsigned char *) line + sizeof(line)-1) - *lp++ = c; - } - - *lp = 0; - return (r == 1 || lp != line); -} - -static void token(int need) -{ - /* Read a word from the configuration line. Return a null string on - * EOL. Return a punctuation as a one character word. If 'need' is - * true then an actual word is expected at this point, so err out if - * not. - */ - unsigned char *wp; - static unsigned char c= '\n'; - - wp= (unsigned char *) word; - *wp = 0; - - while (c <= ' ') { - if (*lineptr == 0) { - if (need) error(); - return; - } - c = *lineptr++; - } - - do { - if (wp < (unsigned char *) word + sizeof(word)-1) *wp++ = c; - c = (*lineptr != 0) ? *lineptr++ : ' '; - if (word[0] == ';' || word[0] == '{' || word[0] == '}') { - if (need) error(); - break; - } - } while (c > ' ' && c != ';' && c != '{' && c != '}'); - *wp = 0; -} - -static unsigned number(char *str, unsigned max) -{ - /* Interpret a string as an unsigned decimal number, no bigger than - * 'max'. Return this number. - */ - char *s; - unsigned n, d; - - s= str; - n= 0; - while ((d= (*s - '0')) < 10 && n <= max) { - n= n * 10 + d; - s++; - } - if (*s != 0 || n > max) { - printf("inet: '%s' is not a number <= %u\n", str, max); - error(); - } - return n; -} - -void read_conf(void) -{ - int i, j, ifno = -1, type = -1, port = -1, enable; - struct eth_conf *ecp; - struct psip_conf *pcp; - struct ip_conf *icp; - struct stat st; - char buf[sizeof(word)]; - - { static int first= 1; - if (!first) ip_panic(( "read_conf: called a second time" )); - first= 0; -#if 0 - *(u8_t *)0 = 0xcc; /* INT 3 */ -#endif - } - - - /* Open the configuration file. */ - if ((cfg_fd= open(PATH_INET_CONF, O_RDONLY)) == -1) - fatal(PATH_INET_CONF); - - ecp= eth_conf; - pcp= psip_conf; - icp= ip_conf; - - while (nextline()) { - token(1); - if (strncmp(word, "eth", 3) == 0) { - ecp->ec_ifno= ifno= number(word+3, IP_PORT_MAX-1); - type= NETTYPE_ETH; - port= eth_conf_nr; - token(1); - if (strcmp(word, "vlan") == 0) { - token(1); - ecp->ec_vlan= number(word, (1<<12)-1); - token(1); - if (strncmp(word, "eth", 3) != 0) { - printf( - "inet: VLAN eth%d can't be built on %s\n", - ifno, word); - exit(1); - } - ecp->ec_port= number(word+3, IP_PORT_MAX-1); - } else { - /* The process label consists of the driver - * name, an underscore, and the instance - * number. - */ - size_t len; - strncpy(buf, word, sizeof(buf)-1); - buf[sizeof(buf)-1]= 0; - token(1); - len = strlen(buf)+1+strlen(word)+1; - ecp->ec_label= alloc(len); - snprintf(ecp->ec_label, len, "%s_%s", buf, word); - ecp->ec_port= 0; - } - ecp++; - eth_conf_nr++; - } else if (strncmp(word, "psip", 4) == 0) { - pcp->pc_ifno= ifno= number(word+4, IP_PORT_MAX-1); - type= NETTYPE_PSIP; - port= psip_conf_nr; - pcp++; - psip_conf_nr++; - } else { - printf("inet: Unknown device '%s'\n", word); - error(); - } - - if (type == -1 || ifno == -1 || port == -1) { - printf("inet: faulty configuration\n"); - exit(1); - } - - iftype[ifno]= type; - icp->ic_ifno= ifno; - icp->ic_devtype= type; - icp->ic_port= port; - tcp_conf[tcp_conf_nr].tc_port= ip_conf_nr; - udp_conf[udp_conf_nr].uc_port= ip_conf_nr; - - enable= 7; /* 1 = IP, 2 = TCP, 4 = UDP */ - - token(0); - if (word[0] == '{') { - token(0); - while (word[0] != '}') { - if (strcmp(word, "default") == 0) { - if (ifdefault != -1) { - printf( - "inet: ip%d and ip%d can't both be default\n", - ifdefault, ifno); - error(); - } - ifdefault= ifno; - token(0); - } else - if (strcmp(word, "no") == 0) { - token(1); - if (strcmp(word, "ip") == 0) { - enable= 0; - } else - if (strcmp(word, "tcp") == 0) { - enable &= ~2; - } else - if (strcmp(word, "udp") == 0) { - enable &= ~4; - } else { - printf( - "inet: Can't do 'no %s'\n", - word); - exit(1); - } - token(0); - } else { - printf("inet: Unknown option '%s'\n", - word); - exit(1); - } - if (word[0] == ';') token(0); - else - if (word[0] != '}') error(); - } - token(0); - } - if (word[0] != ';' && word[0] != 0) error(); - - if (enable & 1) icp++, ip_conf_nr++; - if (enable & 2) tcp_conf_nr++; - if (enable & 4) udp_conf_nr++; - } - - if (ifdefault == -1) { - printf("inet: No networks or no default network defined\n"); - exit(1); - } - - /* Translate VLAN network references to port numbers. */ - for (i= 0; i < eth_conf_nr; i++) { - ecp= ð_conf[i]; - if (eth_is_vlan(ecp)) { - for (j= 0; j < eth_conf_nr; j++) { - if (eth_conf[j].ec_ifno == ecp->ec_port - && !eth_is_vlan(ð_conf[j]) - ) { - ecp->ec_port= j; - break; - } - } - if (j == eth_conf_nr) { - printf( - "inet: VLAN eth%d can't be built on eth%d\n", - ecp->ec_ifno, ecp->ec_port); - exit(1); - } - } - } - - /* Set umask 0 so we can creat mode 666 devices. */ - (void) umask(0); - - /* See what the device number of /dev/ip is. That's what we - * used last time for the network devices, so we keep doing so. - */ - if (stat("/dev/ip", &st) < 0) fatal((char *) "/dev/ip"); - ip_dev= st.st_rdev; - - for (i= 0; i < IP_PORT_MAX; i++) { - /* Create network devices. */ - check_dev(iftype[i], i); - } -} - -void *alloc(size_t size) -{ - /* Allocate memory on the heap with sbrk(). */ - - void *addr = malloc(size); - memset(addr, 0, size); - return addr; -} - -/* - * $PchId: inet_config.c,v 1.10 2003/08/21 09:26:02 philip Exp $ - */ diff --git a/minix/net/inet/inet_config.h b/minix/net/inet/inet_config.h deleted file mode 100644 index 164174465..000000000 --- a/minix/net/inet/inet_config.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -inet/inet_config.h - -Created: Nov 11, 1992 by Philip Homburg - -Defines values for configurable parameters. The structure definitions for -configuration information are also here. - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__INET_CONFIG_H -#define INET__INET_CONFIG_H - -/* Inet configuration file. */ -#define PATH_INET_CONF (char *) "/etc/inet.conf" - -#define IP_PORT_MAX 32 /* Up to this many network devices */ -extern int eth_conf_nr; /* Number of ethernets */ -extern int psip_conf_nr; /* Number of Pseudo IP networks */ -extern int ip_conf_nr; /* Number of configured IP layers */ -extern int tcp_conf_nr; /* Number of configured TCP layers */ -extern int udp_conf_nr; /* Number of configured UDP layers */ - -extern dev_t ip_dev; /* Device number of /dev/ip */ - -struct eth_conf -{ - char *ec_label; /* Process label name if nonnull */ - u8_t ec_port; /* Ethernet port for VLAN if label == NULL */ - u8_t ec_ifno; /* Interface number of /dev/eth* */ - u16_t ec_vlan; /* VLAN number of this net if label == NULL */ -}; -#define eth_is_vlan(ecp) ((ecp)->ec_label == NULL) - -struct psip_conf -{ - u8_t pc_ifno; /* Interface number of /dev/psip* */ -}; - -struct ip_conf -{ - u8_t ic_devtype; /* Underlying device type: Ethernet / PSIP */ - u8_t ic_port; /* Port of underlying device */ - u8_t ic_ifno; /* Interface number of /dev/ip*, tcp*, udp* */ -}; - -struct tcp_conf -{ - u8_t tc_port; /* IP port number */ -}; - -struct udp_conf -{ - u8_t uc_port; /* IP port number */ -}; - -/* Types of networks. */ -#define NETTYPE_ETH 1 -#define NETTYPE_PSIP 2 - -/* To compute the minor device number for a device on an interface. */ -#define if2minor(ifno, dev) (1 + (ifno) * 8 + (dev)) - -#define IPSTAT_DEV (char *) "/dev/ipstat" -#define IPSTAT_MODE 0666 /* Is this right? What about just setuid apps */ -#define IPSTAT_MINOR 0 /* Minor number of /dev/ipstat */ - -/* Offsets of the minor device numbers within a group per interface. */ -#define ETH_DEV_OFF 0 -#define PSIP_DEV_OFF 0 -#define IP_DEV_OFF 1 -#define TCP_DEV_OFF 2 -#define UDP_DEV_OFF 3 - -extern struct eth_conf eth_conf[IP_PORT_MAX]; -extern struct psip_conf psip_conf[IP_PORT_MAX]; -extern struct ip_conf ip_conf[IP_PORT_MAX]; -extern struct tcp_conf tcp_conf[IP_PORT_MAX]; -extern struct udp_conf udp_conf[IP_PORT_MAX]; -void read_conf(void); -extern void *sbrk(int); -void *alloc(size_t size); - -/* Options */ -extern int ip_forward_directed_bcast; - -#undef HTONL -#undef HTONS -#define HTONL htonl -#define HTONS htons - -#endif /* INET__INET_CONFIG_H */ - -/* - * $PchId: inet_config.h,v 1.10 2003/08/21 09:24:33 philip Exp $ - */ diff --git a/minix/net/inet/mnx_eth.c b/minix/net/inet/mnx_eth.c deleted file mode 100644 index 0fe584099..000000000 --- a/minix/net/inet/mnx_eth.c +++ /dev/null @@ -1,786 +0,0 @@ -/* -inet/mnx_eth.c - -Created: Jan 2, 1992 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include -#include "proto.h" -#include "osdep_eth.h" -#include "generic/type.h" - -#include "generic/assert.h" -#include "generic/buf.h" -#include "generic/clock.h" -#include "generic/eth.h" -#include "generic/eth_int.h" -#include "generic/sr.h" - -THIS_FILE - -static void setup_read(eth_port_t *eth_port); -static void read_int(eth_port_t *eth_port, int count); -static void eth_issue_send(eth_port_t *eth_port); -static void write_int(eth_port_t *eth_port); -static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint); -static void send_getstat(eth_port_t *eth_port); - -void osdep_eth_init() -{ - int i, j, rport; - struct eth_conf *ecp; - eth_port_t *eth_port, *rep; - cp_grant_id_t gid; - - /* First initialize normal ethernet interfaces */ - for (i= 0, ecp= eth_conf, eth_port= eth_port_table; - ietp_osdep.etp_wr_iovec[j].iov_grant= -1; - eth_port->etp_osdep.etp_wr_vec_grant= -1; - for (j= 0; jetp_osdep.etp_rd_iovec[j].iov_grant= -1; - eth_port->etp_osdep.etp_rd_vec_grant= -1; - - eth_port->etp_osdep.etp_state= OEPS_INIT; - eth_port->etp_osdep.etp_flags= OEPF_EMPTY; - eth_port->etp_osdep.etp_stat_gid= -1; - eth_port->etp_osdep.etp_stat_buf= NULL; - - if (eth_is_vlan(ecp)) - continue; - - /* Allocate grants */ - for (j= 0; jetp_osdep.etp_wr_iovec[j].iov_grant= gid; - } - if (cpf_getgrants(&gid, 1) != 1) - { - ip_panic(( - "osdep_eth_init: cpf_getgrants failed: %d\n", - errno)); - } - eth_port->etp_osdep.etp_wr_vec_grant= gid; - for (j= 0; jetp_osdep.etp_rd_iovec[j].iov_grant= gid; - } - if (cpf_getgrants(&gid, 1) != 1) - { - ip_panic(( - "osdep_eth_init: cpf_getgrants failed: %d\n", - errno)); - } - eth_port->etp_osdep.etp_rd_vec_grant= gid; - - eth_port->etp_osdep.etp_task= NONE; - eth_port->etp_osdep.etp_recvconf= 0; - ev_init(ð_port->etp_osdep.etp_recvev); - - sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF), - i, eth_open, eth_close, eth_read, - eth_write, eth_ioctl, eth_cancel, eth_select); - - eth_port->etp_flags |= EPF_ENABLED; - eth_port->etp_vlan= 0; - eth_port->etp_vlan_port= NULL; - eth_port->etp_wr_pack= 0; - eth_port->etp_rd_pack= 0; - } - - /* And now come the VLANs */ - for (i= 0, ecp= eth_conf, eth_port= eth_port_table; - ietp_osdep.etp_task= NONE; - ev_init(ð_port->etp_osdep.etp_recvev); - - rport= ecp->ec_port; - assert(rport >= 0 && rport < eth_conf_nr); - rep= ð_port_table[rport]; - if (!(rep->etp_flags & EPF_ENABLED)) - { - printf( - "eth%d: underlying ethernet device %d not enabled", - i, rport); - continue; - } - if (rep->etp_vlan != 0) - { - printf( - "eth%d: underlying ethernet device %d is a VLAN", - i, rport); - continue; - } - - if (rep->etp_flags & EPF_GOT_ADDR) - { - eth_port->etp_ethaddr= rep->etp_ethaddr; - printf("osdep_eth_init: setting EPF_GOT_ADDR\n"); - eth_port->etp_flags |= EPF_GOT_ADDR; - } - - sr_add_minor(if2minor(ecp->ec_ifno, ETH_DEV_OFF), - i, eth_open, eth_close, eth_read, - eth_write, eth_ioctl, eth_cancel, eth_select); - - eth_port->etp_flags |= EPF_ENABLED; - eth_port->etp_vlan= ecp->ec_vlan; - eth_port->etp_vlan_port= rep; - assert(eth_port->etp_vlan != 0); - eth_port->etp_wr_pack= 0; - eth_port->etp_rd_pack= 0; - eth_reg_vlan(rep, eth_port); - } -} - -void eth_write_port(eth_port, pack) -eth_port_t *eth_port; -acc_t *pack; -{ - assert(!no_ethWritePort); - assert(!eth_port->etp_vlan); - - assert(eth_port->etp_wr_pack == NULL); - eth_port->etp_wr_pack= pack; - - if (eth_port->etp_osdep.etp_state != OEPS_IDLE) - { - eth_port->etp_osdep.etp_flags |= OEPF_NEED_SEND; - return; - } - - - eth_issue_send(eth_port); -} - -void eth_rec(message *m) -{ - int i, r, flags; - eth_port_t *loc_port, *vlan_port; - - for (i=0, loc_port= eth_port_table; ietp_osdep.etp_task == m->m_source) - break; - } - if (i >= eth_conf_nr) - { - printf("eth_rec: message 0x%x from unknown driver %d\n", - m->m_type, m->m_source); - return; - } - - switch (m->m_type) { - case DL_CONF_REPLY: - if (loc_port->etp_osdep.etp_state != OEPS_CONF_SENT) { - printf("eth_rec: got DL_CONF_REPLY from %d while in " - "state %d (ignoring)\n", m->m_source, - loc_port->etp_osdep.etp_state); - return; - } - - r= m->m_netdrv_net_dl_conf.stat; - if (r < 0) - { - ip_warning(("eth_rec: DL_CONF returned error %d\n", - r)); - - /* Just leave it in limbo. Nothing more we can do. */ - return; - } - - loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_CONF; - loc_port->etp_osdep.etp_state= OEPS_IDLE; - loc_port->etp_flags |= EPF_ENABLED; - - memcpy(loc_port->etp_ethaddr.ea_addr, - m->m_netdrv_net_dl_conf.hw_addr, - sizeof(loc_port->etp_ethaddr.ea_addr)); - if (!(loc_port->etp_flags & EPF_GOT_ADDR)) - { - loc_port->etp_flags |= EPF_GOT_ADDR; -#if 0 - printf("eth_rec: calling eth_restart_ioctl\n"); -#endif - eth_restart_ioctl(loc_port); - - /* Also update any VLANs on this device */ - for (i=0, vlan_port= eth_port_table; ietp_flags & EPF_ENABLED)) - continue; - if (vlan_port->etp_vlan_port != loc_port) - continue; - - vlan_port->etp_ethaddr= loc_port->etp_ethaddr; - vlan_port->etp_flags |= EPF_GOT_ADDR; - eth_restart_ioctl(vlan_port); - } - } - - if (!(loc_port->etp_flags & EPF_READ_IP)) - loc_port->etp_osdep.etp_flags |= OEPF_NEED_RECV; - - break; - - case DL_STAT_REPLY: - if (loc_port->etp_osdep.etp_state != OEPS_GETSTAT_SENT) { - printf("eth_rec: got DL_STAT_REPLY from %d while in " - "state %d (ignoring)\n", m->m_source, - loc_port->etp_osdep.etp_state); - return; - } - - loc_port->etp_osdep.etp_state= OEPS_IDLE; - loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_STAT; - - assert(loc_port->etp_osdep.etp_stat_gid != -1); - cpf_revoke(loc_port->etp_osdep.etp_stat_gid); - loc_port->etp_osdep.etp_stat_gid= -1; - loc_port->etp_osdep.etp_stat_buf= NULL; - - /* Finish ioctl */ - assert(loc_port->etp_flags & EPF_GOT_ADDR); - eth_restart_ioctl(loc_port); - - break; - - case DL_TASK_REPLY: - if (loc_port->etp_osdep.etp_state == OEPS_RECV_SENT || - loc_port->etp_osdep.etp_state == OEPS_SEND_SENT) - loc_port->etp_osdep.etp_state= OEPS_IDLE; - - flags= m->m_netdrv_net_dl_task.flags; - - if (flags & DL_PACK_SEND) - write_int(loc_port); - if (flags & DL_PACK_RECV) - read_int(loc_port, m->m_netdrv_net_dl_task.count); - - break; - - default: - panic("invalid ethernet reply %d", m->m_type); - } - - if (loc_port->etp_osdep.etp_state == OEPS_IDLE && - loc_port->etp_osdep.etp_flags & OEPF_NEED_SEND) - { - loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_SEND; - if (loc_port->etp_wr_pack) - eth_issue_send(loc_port); - } - if (loc_port->etp_osdep.etp_state == OEPS_IDLE && - (loc_port->etp_osdep.etp_flags & OEPF_NEED_RECV)) - { - loc_port->etp_osdep.etp_flags &= ~OEPF_NEED_RECV; - if (!(loc_port->etp_flags & EPF_READ_IP)) - setup_read (loc_port); - } - if (loc_port->etp_osdep.etp_state == OEPS_IDLE && - (loc_port->etp_osdep.etp_flags & OEPF_NEED_CONF)) - { - eth_set_rec_conf(loc_port, - loc_port->etp_osdep.etp_recvconf); - } - if (loc_port->etp_osdep.etp_state == OEPS_IDLE && - (loc_port->etp_osdep.etp_flags & OEPF_NEED_STAT)) - { - send_getstat(loc_port); - } -} - -void eth_check_driver(char *label, endpoint_t endpoint) -{ - int i; - eth_port_t *loc_port; - struct eth_conf *ecp; - - /* Re-init ethernet interface */ - for (i= 0, ecp= eth_conf, loc_port= eth_port_table; - iec_label, label) != 0) - { - /* Wrong driver */ - continue; - } - eth_restart(loc_port, endpoint); - } -} - -int eth_get_stat(eth_port, eth_stat) -eth_port_t *eth_port; -eth_stat_t *eth_stat; -{ - cp_grant_id_t gid; - - assert(!eth_port->etp_vlan); - - if (eth_port->etp_osdep.etp_flags & OEPF_NEED_STAT) - ip_panic(( "eth_get_stat: getstat already in progress" )); - - gid= cpf_grant_direct(eth_port->etp_osdep.etp_task, - (vir_bytes)eth_stat, sizeof(*eth_stat), CPF_WRITE); - if (gid == -1) - { - ip_panic(( "eth_get_stat: cpf_grant_direct failed: %d\n", - errno)); - } - assert(eth_port->etp_osdep.etp_stat_gid == -1); - eth_port->etp_osdep.etp_stat_gid= gid; - eth_port->etp_osdep.etp_stat_buf= eth_stat; - - if (eth_port->etp_osdep.etp_state != OEPS_IDLE) - { - eth_port->etp_osdep.etp_flags |= OEPF_NEED_STAT; - return SUSPEND; - } - - send_getstat(eth_port); - - return SUSPEND; -} - -void eth_set_rec_conf (eth_port, flags) -eth_port_t *eth_port; -u32_t flags; -{ - int r; - unsigned dl_flags, mask; - message mess; - - assert(!eth_port->etp_vlan); - - if (!(eth_port->etp_flags & EPF_GOT_ADDR)) - { - /* We have never seen the device. */ -#if 0 - printf("eth_set_rec_conf: waiting for device to appear\n"); -#endif - return; - } - - if (eth_port->etp_osdep.etp_state != OEPS_IDLE) - { -#if 0 - printf( - "eth_set_rec_conf: setting OEPF_NEED_CONF, state = %d\n", - eth_port->etp_osdep.etp_state); -#endif - eth_port->etp_osdep.etp_flags |= OEPF_NEED_CONF; - return; - } - - mask = NWEO_EN_BROAD | NWEO_EN_MULTI | NWEO_EN_PROMISC; - if ((eth_port->etp_osdep.etp_recvconf & mask) == (flags & mask)) - { - /* No change for the driver, so don't send an update */ - return; - } - - eth_port->etp_osdep.etp_recvconf= flags; - dl_flags= DL_NOMODE; - if (flags & NWEO_EN_BROAD) - dl_flags |= DL_BROAD_REQ; - if (flags & NWEO_EN_MULTI) - dl_flags |= DL_MULTI_REQ; - if (flags & NWEO_EN_PROMISC) - dl_flags |= DL_PROMISC_REQ; - - mess.m_type= DL_CONF; - mess.m_net_netdrv_dl_conf.mode = dl_flags; - - assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); - r= asynsend(eth_port->etp_osdep.etp_task, &mess); - eth_port->etp_osdep.etp_state= OEPS_CONF_SENT; - - if (r < 0) - { - printf("eth_set_rec_conf: asynsend to %d failed: %d\n", - eth_port->etp_osdep.etp_task, r); - return; - } -} - -static void eth_issue_send(eth_port) -eth_port_t *eth_port; -{ - int i, r, pack_size; - acc_t *pack, *pack_ptr; - iovec_s_t *iovec; - message m; - - iovec= eth_port->etp_osdep.etp_wr_iovec; - pack= eth_port->etp_wr_pack; - pack_size= 0; - for (i=0, pack_ptr= pack; iacc_next) - { - r= cpf_setgrant_direct(iovec[i].iov_grant, - eth_port->etp_osdep.etp_task, - (vir_bytes)ptr2acc_data(pack_ptr), - (vir_bytes)pack_ptr->acc_length, - CPF_READ); - if (r != 0) - { - ip_panic(( - "eth_write_port: cpf_setgrant_direct failed: %d\n", - errno)); - } - pack_size += iovec[i].iov_size= pack_ptr->acc_length; - } - if (i>= IOVEC_NR) - { - pack= bf_pack(pack); /* packet is too fragmented */ - eth_port->etp_wr_pack= pack; - pack_size= 0; - for (i=0, pack_ptr= pack; iacc_next) - { - r= cpf_setgrant_direct(iovec[i].iov_grant, - eth_port->etp_osdep.etp_task, - (vir_bytes)ptr2acc_data(pack_ptr), - (vir_bytes)pack_ptr->acc_length, - CPF_READ); - if (r != 0) - { - ip_panic(( - "eth_write_port: cpf_setgrant_direct failed: %d\n", - errno)); - } - pack_size += iovec[i].iov_size= pack_ptr->acc_length; - } - } - assert (i< IOVEC_NR); - assert (pack_size >= ETH_MIN_PACK_SIZE); - - r= cpf_setgrant_direct(eth_port->etp_osdep.etp_wr_vec_grant, - eth_port->etp_osdep.etp_task, - (vir_bytes)iovec, - (vir_bytes)(i * sizeof(iovec[0])), - CPF_READ); - if (r != 0) - { - ip_panic(( - "eth_write_port: cpf_setgrant_direct failed: %d\n", - errno)); - } - m.m_type= DL_WRITEV_S; - m.m_net_netdrv_dl_writev_s.count= i; - m.m_net_netdrv_dl_writev_s.grant= eth_port->etp_osdep.etp_wr_vec_grant; - - assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); - r= asynsend(eth_port->etp_osdep.etp_task, &m); - - if (r < 0) - { - printf("eth_issue_send: send to %d failed: %d\n", - eth_port->etp_osdep.etp_task, r); - return; - } - eth_port->etp_osdep.etp_state= OEPS_SEND_SENT; -} - -static void write_int(eth_port_t *eth_port) -{ - acc_t *pack; - int multicast; - u8_t *eth_dst_ptr; - - pack= eth_port->etp_wr_pack; - if (pack == NULL) - { - printf("write_int: strange no packet on eth port %d\n", - (int)(eth_port-eth_port_table)); - eth_restart_write(eth_port); - return; - } - - eth_port->etp_wr_pack= NULL; - - eth_dst_ptr= (u8_t *)ptr2acc_data(pack); - multicast= (*eth_dst_ptr & 1); /* low order bit indicates multicast */ - if (multicast || (eth_port->etp_osdep.etp_recvconf & NWEO_EN_PROMISC)) - { - assert(!no_ethWritePort); - no_ethWritePort= 1; - eth_arrive(eth_port, pack, bf_bufsize(pack)); - assert(no_ethWritePort); - no_ethWritePort= 0; - } - else - bf_afree(pack); - - eth_restart_write(eth_port); -} - -static void read_int(eth_port, count) -eth_port_t *eth_port; -int count; -{ - acc_t *pack, *pack_ptr, *cut_pack; - iovec_s_t *iovec; - int i, r; - - /* A buggy driver might try to feed us a reply for a request we never - * sent. Don't let this cause a crash further up. - */ - if (!(eth_port->etp_flags & EPF_READ_IP)) - { - printf("mnx_eth`read_int: read reply with no read going on\n"); - return; - } - - pack= eth_port->etp_rd_pack; - eth_port->etp_rd_pack= NULL; - - /* Invalidate the grants first, so that the ethernet driver can no - * longer modify the contents of the packet. - */ - iovec= eth_port->etp_osdep.etp_rd_iovec; - for (i=0, pack_ptr= pack; iacc_next) - { - r= cpf_setgrant_disable(iovec[i].iov_grant); - if (r != 0) - { - ip_panic(( - "mnx_eth`read_int: cpf_setgrant_disable failed: %d\n", - errno)); - } - } - - if (count < ETH_MIN_PACK_SIZE) - { - printf("mnx_eth`read_int: packet size too small (%d)\n", - count); - bf_afree(pack); - } - else if (count > ETH_MAX_PACK_SIZE_TAGGED) - { - printf("mnx_eth`read_int: packet size too big (%d)\n", - count); - bf_afree(pack); - } - else - { - cut_pack= bf_cut(pack, 0, count); - bf_afree(pack); - - assert(!no_ethWritePort); - no_ethWritePort= 1; - eth_arrive(eth_port, cut_pack, count); - assert(no_ethWritePort); - no_ethWritePort= 0; - } - - eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP); - setup_read(eth_port); -} - -static void setup_read(eth_port) -eth_port_t *eth_port; -{ - acc_t *pack, *pack_ptr; - message mess; - iovec_s_t *iovec; - int i, r; - - assert(!eth_port->etp_vlan); - assert(!(eth_port->etp_flags & (EPF_READ_IP|EPF_READ_SP))); - - if (eth_port->etp_osdep.etp_state != OEPS_IDLE) - { - eth_port->etp_osdep.etp_flags |= OEPF_NEED_RECV; - - return; - } - - assert (!eth_port->etp_rd_pack); - - iovec= eth_port->etp_osdep.etp_rd_iovec; - pack= bf_memreq (ETH_MAX_PACK_SIZE_TAGGED); - - for (i=0, pack_ptr= pack; iacc_next) - { - r= cpf_setgrant_direct(iovec[i].iov_grant, - eth_port->etp_osdep.etp_task, - (vir_bytes)ptr2acc_data(pack_ptr), - (vir_bytes)pack_ptr->acc_length, - CPF_WRITE); - if (r != 0) - { - ip_panic(( - "mnx_eth`setup_read: cpf_setgrant_direct failed: %d\n", - errno)); - } - iovec[i].iov_size= (vir_bytes)pack_ptr->acc_length; - } - assert (!pack_ptr); - - r= cpf_setgrant_direct(eth_port->etp_osdep.etp_rd_vec_grant, - eth_port->etp_osdep.etp_task, - (vir_bytes)iovec, - (vir_bytes)(i * sizeof(iovec[0])), - CPF_READ); - if (r != 0) - { - ip_panic(( - "mnx_eth`setup_read: cpf_setgrant_direct failed: %d\n", - errno)); - } - - mess.m_type= DL_READV_S; - mess.m_net_netdrv_dl_readv_s.count= i; - mess.m_net_netdrv_dl_readv_s.grant= eth_port->etp_osdep.etp_rd_vec_grant; - - assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); - - r= asynsend(eth_port->etp_osdep.etp_task, &mess); - eth_port->etp_osdep.etp_state= OEPS_RECV_SENT; - - if (r < 0) - { - printf( - "mnx_eth`setup_read: asynsend to %d failed: %d\n", - eth_port->etp_osdep.etp_task, r); - } - eth_port->etp_rd_pack= pack; - eth_port->etp_flags |= EPF_READ_IP; - eth_port->etp_flags |= EPF_READ_SP; -} - -static void eth_restart(eth_port_t *eth_port, endpoint_t endpoint) -{ - int r; - unsigned flags, dl_flags; - cp_grant_id_t gid; - message mess; - - eth_port->etp_osdep.etp_task= endpoint; - - switch(eth_port->etp_osdep.etp_state) - { - case OEPS_INIT: - case OEPS_CONF_SENT: - case OEPS_RECV_SENT: - case OEPS_SEND_SENT: - /* We can safely ignore the pending CONF, RECV, and SEND - * requests. If this is the first time that we see this - * driver at all, that's fine too. - */ - eth_port->etp_osdep.etp_state= OEPS_IDLE; - break; - case OEPS_GETSTAT_SENT: - /* Set the OEPF_NEED_STAT to trigger a new request */ - eth_port->etp_osdep.etp_flags |= OEPF_NEED_STAT; - eth_port->etp_osdep.etp_state= OEPS_IDLE; - break; - } - - /* If there is a pending GETSTAT request then we have to create a - * new grant. - */ - if (eth_port->etp_osdep.etp_flags & OEPF_NEED_STAT) - { - assert(eth_port->etp_osdep.etp_stat_gid != -1); - cpf_revoke(eth_port->etp_osdep.etp_stat_gid); - - gid= cpf_grant_direct(eth_port->etp_osdep.etp_task, - (vir_bytes)eth_port->etp_osdep.etp_stat_buf, - sizeof(*eth_port->etp_osdep.etp_stat_buf), CPF_WRITE); - if (gid == -1) - { - ip_panic(( - "eth_restart: cpf_grant_direct failed: %d\n", - errno)); - } - eth_port->etp_osdep.etp_stat_gid= gid; - } - - flags= eth_port->etp_osdep.etp_recvconf; - dl_flags= DL_NOMODE; - if (flags & NWEO_EN_BROAD) - dl_flags |= DL_BROAD_REQ; - if (flags & NWEO_EN_MULTI) - dl_flags |= DL_MULTI_REQ; - if (flags & NWEO_EN_PROMISC) - dl_flags |= DL_PROMISC_REQ; - mess.m_type= DL_CONF; - mess.m_net_netdrv_dl_conf.mode= dl_flags; - - compare(eth_port->etp_osdep.etp_state, ==, OEPS_IDLE); - r= asynsend(eth_port->etp_osdep.etp_task, &mess); - if (r<0) - { - printf( - "eth_restart: send to ethernet task %d failed: %d\n", - eth_port->etp_osdep.etp_task, r); - return; - } - eth_port->etp_osdep.etp_state= OEPS_CONF_SENT; - - if (eth_port->etp_wr_pack) - { - bf_afree(eth_port->etp_wr_pack); - eth_port->etp_wr_pack= NULL; - eth_restart_write(eth_port); - } - if (eth_port->etp_rd_pack) - { - bf_afree(eth_port->etp_rd_pack); - eth_port->etp_rd_pack= NULL; - eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP); - } - -} - -static void send_getstat(eth_port) -eth_port_t *eth_port; -{ - int r; - message mess; - - mess.m_type= DL_GETSTAT_S; - mess.m_net_netdrv_dl_getstat_s.grant= eth_port->etp_osdep.etp_stat_gid; - - assert(eth_port->etp_osdep.etp_state == OEPS_IDLE); - - r= asynsend(eth_port->etp_osdep.etp_task, &mess); - eth_port->etp_osdep.etp_state= OEPS_GETSTAT_SENT; - - if (r != OK) - ip_panic(( "eth_get_stat: asynsend failed: %d", r)); -} - -/* - * $PchId: mnx_eth.c,v 1.16 2005/06/28 14:24:37 philip Exp $ - */ diff --git a/minix/net/inet/mq.c b/minix/net/inet/mq.c deleted file mode 100644 index c0299776e..000000000 --- a/minix/net/inet/mq.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -inet/mq.c - -Created: Jan 3, 1992 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#include "inet.h" -#include "mq.h" -#include "generic/assert.h" - -THIS_FILE - -#define MQ_SIZE 128 - -static mq_t mq_list[MQ_SIZE]; -static mq_t *mq_freelist; - -void mq_init() -{ - int i; - - mq_freelist= NULL; - for (i= 0; imq_next; - mq->mq_next= NULL; - assert(mq->mq_allocated == 0); - mq->mq_allocated= 1; - return mq; -} - -void mq_free(mq) -mq_t *mq; -{ - mq->mq_next= mq_freelist; - mq_freelist= mq; - assert(mq->mq_allocated == 1); - mq->mq_allocated= 0; -} - -/* - * $PchId: mq.c,v 1.7 1998/10/23 20:10:47 philip Exp $ - */ diff --git a/minix/net/inet/mq.h b/minix/net/inet/mq.h deleted file mode 100644 index 73199f52a..000000000 --- a/minix/net/inet/mq.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -inet/mq.h - -Created: Jan 3, 1992 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__MQ_H -#define INET__MQ_H - -#include - -typedef struct sr_req { - enum { - SRR_READ, - SRR_WRITE, - SRR_IOCTL - } srr_type; - devminor_t srr_minor; - endpoint_t srr_endpt; - cp_grant_id_t srr_grant; - union { - size_t srr_size; /* for SRR_READ, SRR_WRITE */ - unsigned long srr_req; /* for SRR_IOCTL */ - }; - int srr_flags; - cdev_id_t srr_id; -} sr_req_t; - -typedef struct mq -{ - sr_req_t mq_req; - struct mq *mq_next; - int mq_allocated; -} mq_t; - -mq_t *mq_get(void); -void mq_free(mq_t *mq); -void mq_init(void); - -#endif /* INET__MQ_H */ - -/* - * $PchId: mq.h,v 1.4 1995/11/21 06:40:30 philip Exp $ - */ diff --git a/minix/net/inet/osdep_eth.h b/minix/net/inet/osdep_eth.h deleted file mode 100644 index a683ecc9b..000000000 --- a/minix/net/inet/osdep_eth.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -inet/osdep_eth.h - -Created: Dec 30, 1991 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__OSDEP_ETH_H -#define INET__OSDEP_ETH_H - -#include "generic/event.h" - -#define IOVEC_NR 16 -#define RD_IOVEC ((ETH_MAX_PACK_SIZE + BUF_S -1)/BUF_S) - -typedef struct osdep_eth_port -{ - int etp_state; - int etp_flags; - endpoint_t etp_task; - int etp_recvconf; - iovec_s_t etp_wr_iovec[IOVEC_NR]; - cp_grant_id_t etp_wr_vec_grant; - iovec_s_t etp_rd_iovec[RD_IOVEC]; - cp_grant_id_t etp_rd_vec_grant; - event_t etp_recvev; - cp_grant_id_t etp_stat_gid; - eth_stat_t *etp_stat_buf; -} osdep_eth_port_t; - -#define OEPS_INIT 0 /* Not initialized */ -#define OEPS_CONF_SENT 1 /* Conf. request has been sent */ -#define OEPS_IDLE 2 /* Device is ready to accept requests */ -#define OEPS_RECV_SENT 3 /* Recv. request has been sent */ -#define OEPS_SEND_SENT 4 /* Send request has been sent */ -#define OEPS_GETSTAT_SENT 5 /* GETSTAT request has been sent */ - -#define OEPF_EMPTY 0 -#define OEPF_NEED_RECV 1 /* Issue recv. request when the state becomes - * idle - */ -#define OEPF_NEED_SEND 2 /* Issue send request when the state becomes - * idle - */ -#define OEPF_NEED_CONF 4 /* Issue conf request when the state becomes - * idle - */ -#define OEPF_NEED_STAT 8 /* Issue getstat request when the state becomes - * idle - */ - -#endif /* INET__OSDEP_ETH_H */ - -/* - * $PchId: osdep_eth.h,v 1.6 2001/04/20 06:39:54 philip Exp $ - */ diff --git a/minix/net/inet/proto.h b/minix/net/inet/proto.h deleted file mode 100644 index 17decabf8..000000000 --- a/minix/net/inet/proto.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -inet/proto.h - -Created: Jan 2, 1992 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -/* clock.c */ - -void clck_tick(message *mess); - -/* mnx_eth.c */ - -void eth_rec(message *m); -void eth_check_driver(char *label, endpoint_t endpoint); - -/* rtinfo.c */ - -void rtinfo_init(void); - -/* sr.c */ - -void sr_rec(message *m, int ipc_status); - -/* - * $PchId: proto.h,v 1.4 1995/11/21 06:36:37 philip Exp $ - */ diff --git a/minix/net/inet/qp.c b/minix/net/inet/qp.c deleted file mode 100644 index 7350a0931..000000000 --- a/minix/net/inet/qp.c +++ /dev/null @@ -1,384 +0,0 @@ -/* -inet/qp.c - -Query parameters - -Created: June 1995 by Philip Homburg -*/ - -#include "inet.h" -#include "generic/assert.h" - -#include "queryparam.h" - -#include "generic/buf.h" -#include "generic/clock.h" -#include "generic/event.h" -#include "generic/type.h" -#include "generic/sr.h" - -#include "generic/tcp_int.h" -#include "generic/udp_int.h" -#include "mq.h" -#include "qp.h" -#include "sr_int.h" - -THIS_FILE - -#define MAX_REQ 1024 /* Maximum size of a request */ - -#define QP_FD_NR 4 - -typedef struct qp_fd -{ - int qf_flags; - int qf_srfd; - get_userdata_t qf_get_userdata; - put_userdata_t qf_put_userdata; - acc_t *qf_req_pkt; -} qp_fd_t; - -#define QFF_EMPTY 0 -#define QFF_INUSE 1 - -static qp_fd_t qp_fd_table[QP_FD_NR]; - -static struct export_param_list inet_ex_list[]= -{ - QP_VARIABLE(sr_fd_table), - QP_VARIABLE(ip_dev), - QP_VARIABLE(tcp_fd_table), - QP_VARIABLE(tcp_conn_table), - QP_VARIABLE(tcp_cancel_f), - QP_VECTOR(udp_port_table, udp_port_table, ip_conf_nr), - QP_VARIABLE(udp_fd_table), - QP_END() -}; - -static struct export_params inet_ex_params= { inet_ex_list, NULL }; - -static struct queryvars { - /* Input */ - acc_t *param; - - /* Output */ - qp_fd_t *qp_fd; - off_t fd_offset; - size_t rd_bytes_left; - off_t outbuf_off; - char outbuf[256]; - - int r; /* result */ -} *qvars; - - -static int qp_open ARGS(( int port, int srfd, - get_userdata_t get_userdata, put_userdata_t put_userdata, - put_pkt_t put_pkt, select_res_t select_res )); -static void qp_close ARGS(( int fd )); -static int qp_read ARGS(( int fd, size_t count )); -static int qp_write ARGS(( int fd, size_t count )); -static int qp_ioctl ARGS(( int fd, ioreq_t req )); -static int qp_cancel ARGS(( int fd, int which_operation )); -static int qp_select ARGS(( int fd, unsigned operations )); -static qp_fd_t *get_qp_fd ARGS(( int fd )); -static int do_query ARGS(( qp_fd_t *qp_fd, acc_t *pkt, int count )); -static int qp_getc ARGS(( void )); -static void qp_putc ARGS(( struct queryvars *qv, int c )); -static void qp_buffree ARGS(( int priority )); -#ifdef BUF_CONSISTENCY_CHECK -static void qp_bufcheck ARGS(( void )); -#endif - -void qp_init() -{ - int i; - - qp_export(&inet_ex_params); - - for (i= 0; i= QP_FD_NR) - return EAGAIN; - qp_fd= &qp_fd_table[i]; - qp_fd->qf_flags= QFF_INUSE; - qp_fd->qf_srfd= srfd; - qp_fd->qf_get_userdata= get_userdata; - qp_fd->qf_put_userdata= put_userdata; - qp_fd->qf_req_pkt= NULL; - - return i; -} - -static void qp_close(fd) -int fd; -{ - qp_fd_t *qp_fd; - - qp_fd= get_qp_fd(fd); - qp_fd->qf_flags= QFF_EMPTY; - if (qp_fd->qf_req_pkt) - { - bf_afree(qp_fd->qf_req_pkt); - qp_fd->qf_req_pkt= NULL; - } -} - -static int qp_read(fd, count) -int fd; -size_t count; -{ - int r; - acc_t *pkt; - qp_fd_t *qp_fd; - - qp_fd= get_qp_fd(fd); - pkt= qp_fd->qf_req_pkt; - qp_fd->qf_req_pkt= NULL; - if (!pkt) - { - /* Nothing to do */ - qp_fd->qf_put_userdata(qp_fd->qf_srfd, EIO, 0, - FALSE /* !for_ioctl*/); - return OK; - } - r= do_query(qp_fd, pkt, count); - qp_fd->qf_put_userdata(qp_fd->qf_srfd, r, 0, - FALSE /* !for_ioctl*/); - return OK; -} - -static int qp_write(fd, count) -int fd; -size_t count; -{ - acc_t *pkt; - qp_fd_t *qp_fd; - - qp_fd= get_qp_fd(fd); - if (count > MAX_REQ) - { - qp_fd->qf_get_userdata(qp_fd->qf_srfd, ENOMEM, 0, - FALSE /* !for_ioctl*/); - return OK; - } - pkt= qp_fd->qf_get_userdata(qp_fd->qf_srfd, 0, count, - FALSE /* !for_ioctl*/); - if (!pkt) - { - qp_fd->qf_get_userdata(qp_fd->qf_srfd, EFAULT, 0, - FALSE /* !for_ioctl*/); - return OK; - } - if (qp_fd->qf_req_pkt) - { - bf_afree(qp_fd->qf_req_pkt); - qp_fd->qf_req_pkt= NULL; - } - qp_fd->qf_req_pkt= pkt; - qp_fd->qf_get_userdata(qp_fd->qf_srfd, count, 0, - FALSE /* !for_ioctl*/); - return OK; -} - -static int qp_ioctl(fd, req) -int fd; -ioreq_t req; -{ - qp_fd_t *qp_fd; - - qp_fd= get_qp_fd(fd); - qp_fd->qf_get_userdata(qp_fd->qf_srfd, ENOTTY, 0, - TRUE /* for_ioctl*/); - return OK; -} - -static int qp_cancel(fd, which_operation) -int fd; -int which_operation; -{ - ip_panic(( "qp_cancel: should not be here, no blocking calls" )); - return OK; -} - -static int qp_select(fd, operations) -int fd; -unsigned operations; -{ - unsigned resops; - - resops= 0; - if (operations & SR_SELECT_READ) - resops |= SR_SELECT_READ; - if (operations & SR_SELECT_WRITE) - resops |= SR_SELECT_WRITE; - return resops; -} - -static qp_fd_t *get_qp_fd(fd) -int fd; -{ - qp_fd_t *qp_fd; - - assert(fd >= 0 && fd < QP_FD_NR); - qp_fd= &qp_fd_table[fd]; - assert(qp_fd->qf_flags & QFF_INUSE); - return qp_fd; -} - -static int do_query(qp_fd, pkt, count) -qp_fd_t *qp_fd; -acc_t *pkt; -int count; -{ - struct queryvars qv; - void *addr; - size_t n, size; - int byte; - int more; - static char hex[]= "0123456789ABCDEF"; - - qvars= &qv; - qv.param= pkt; pkt= NULL; - qv.qp_fd= qp_fd; - qv.fd_offset= 0; - qv.outbuf_off= 0; - qv.rd_bytes_left= count; - qv.r= 0; - - do { - more= queryparam(qp_getc, &addr, &size); - for (n= 0; n < size; n++) { - byte= ((u8_t *) addr)[n]; - qp_putc(&qv, hex[byte >> 4]); - qp_putc(&qv, hex[byte & 0x0F]); - } - qp_putc(&qv, more ? ',' : 0); - if (qv.r) - break; - } while (more); - if (qv.param) - { - assert(0); - bf_afree(qv.param); - qv.param= NULL; - } - if (qv.r) - return qv.r; - return qv.fd_offset; -} - -static int qp_getc() -{ - /* Return one character of the names to search for. */ - acc_t *pkt; - struct queryvars *qv= qvars; - u8_t c; - - pkt= qv->param; - qv->param= NULL; - if (pkt == NULL) - return 0; - - assert(bf_bufsize(pkt) > 0); - c= ptr2acc_data(pkt)[0]; - if (bf_bufsize(pkt) > 1) - qv->param= bf_delhead(pkt, 1); - else - { - bf_afree(pkt); - qv->param= NULL; - } - - return c; -} - -static void qp_putc(qv, c) -struct queryvars *qv; -int c; -{ - /* Send one character back to the user. */ - acc_t *pkt; - qp_fd_t *qp_fd; - size_t bytes_left; - off_t off; - - bytes_left= qv->rd_bytes_left; - if (qv->r || bytes_left == 0) - return; - - off= qv->outbuf_off; - assert(off < sizeof(qv->outbuf)); - qv->outbuf[off]= c; - off++; - bytes_left--; - qv->rd_bytes_left= bytes_left; - if (c != '\0' && off < sizeof(qv->outbuf) && bytes_left != 0) - { - qv->outbuf_off= off; - return; - } - - pkt= bf_memreq(off); - assert(pkt->acc_next == NULL); - memcpy(ptr2acc_data(pkt), qv->outbuf, off); - qp_fd= qv->qp_fd; - qv->r= qp_fd->qf_put_userdata(qp_fd->qf_srfd, qv->fd_offset, - pkt, FALSE /* !for_ioctl*/ ); - qv->fd_offset += off; - qv->outbuf_off= 0; -} - -static void qp_buffree (priority) -int priority; -{ - /* For the moment, we are not going to free anything */ -} - -#ifdef BUF_CONSISTENCY_CHECK -static void qp_bufcheck() -{ - int i; - qp_fd_t *qp_fd; - - for (i= 0, qp_fd= qp_fd_table; iqf_flags & QFF_INUSE)) - continue; - if (qp_fd->qf_req_pkt) - bf_check_acc(qp_fd->qf_req_pkt); - } -} -#endif - -/* - * $PchId: qp.c,v 1.7 2005/06/28 14:25:25 philip Exp $ - */ diff --git a/minix/net/inet/qp.h b/minix/net/inet/qp.h deleted file mode 100644 index d2456a6f4..000000000 --- a/minix/net/inet/qp.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -inet/qp.h - -Handle queryparams requests - -Created: June 1995 by Philip Homburg - -Copyright 1995 Philip Homburg -*/ - -#ifndef INET__QP_H -#define INET__QP_H - -void qp_init ARGS(( void )); - -#endif /* INET__QP_H */ - -/* - * $PchId: qp.h,v 1.4 2005/01/29 18:08:06 philip Exp $ - */ diff --git a/minix/net/inet/queryparam.c b/minix/net/inet/queryparam.c deleted file mode 100644 index d505423ea..000000000 --- a/minix/net/inet/queryparam.c +++ /dev/null @@ -1,150 +0,0 @@ -/* queryparam() - allow program parameters to be queried - * Author: Kees J. Bot - * 21 Apr 1994 - */ -#define nil 0 -#include -#include -#include -#include "queryparam.h" - -#if EXAMPLE -struct stat st[2]; - -struct export_param_list ex_st_list[]= { - QP_VARIABLE(st), - QP_ARRAY(st), - QP_FIELD(st_dev, struct stat), - QP_FIELD(st_ino, struct stat), - ... - QP_END() -}; - -struct buf { block_t b_blocknr; ... } *buf; -size_t nr_bufs; - -struct export_param_list ex_buf_list[]= - QP_VECTOR(buf, buf, nr_bufs), - QP_FIELD(b_blocknr), - ... - QP_END() -}; - -struct export_params ex_st= { ex_st_list, 0 }; -struct export_params ex_buf= { ex_buf_list, 0 }; -#endif - -#define between(a, c, z) ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a))) - -static int isvar(int c) -{ - return between('a', c, 'z') || between('A', c, 'Z') - || between('0', c, '9') || c == '_'; -} - -static struct export_params *params; - -void qp_export(struct export_params *ex_params) -{ - /* Add a set of exported parameters. */ - - if (ex_params->next == nil) { - ex_params->next= params; - params= ex_params; - } -} - -int queryparam(int qgetc(void), void **poffset, size_t *psize) -{ - char *prefix; - struct export_params *ep; - struct export_param_list *epl; - size_t offset= 0; - size_t size= -1; - size_t n; - static size_t retval; - int c, firstc; - - firstc= c= (*qgetc)(); - if (c == '&' || c == '$') c= (*qgetc)(); - if (!isvar(c)) goto fail; - - if ((ep= params) == nil) goto fail; - epl= ep->list; - - while (c != 0 && c != ',') { - prefix= (char *) "x"; - n= 0; - - for (;;) { - while (epl->name == nil) { - if ((ep= ep->next) == nil) goto fail; - epl= ep->list; - } - if (strncmp(prefix, epl->name, n) == 0) { - prefix= epl->name; - while (prefix[n] != 0 && c == prefix[n]) { - n++; - c= (*qgetc)(); - } - } - if (prefix[n] == 0 && (!isvar(c) || prefix[0] == '[')) { - /* Got a match. */ - break; - } - epl++; - } - - if (prefix[0] == '[') { - /* Array reference. */ - size_t idx= 0, cnt= 1, max= size / epl->size; - - while (between('0', c, '9')) { - idx= idx * 10 + (c - '0'); - if (idx > max) goto fail; - c= (*qgetc)(); - } - if (c == ':') { - cnt= 0; - while (between('0', (c= (*qgetc)()), '9')) { - cnt= cnt * 10 + (c - '0'); - } - } - if (c != ']') goto fail; - if (idx + cnt > max) cnt= max - idx; - offset+= idx * epl->size; - size= cnt * epl->size; - c= (*qgetc)(); - } else - if (epl->size == -1) { - /* Vector. */ - offset= (size_t) * (void **) epl->offset; - size= (* (size_t *) epl[1].offset) * epl[1].size; - } else { - /* Variable or struct field. */ - offset+= (size_t) epl->offset; - if ((size_t) epl->offset > size) goto fail; - size-= (size_t) epl->offset; - if (size < epl->size) goto fail; - size= epl->size; - } - } - if (firstc == '&' || firstc == '$') { - retval= firstc == '&' ? offset : size; - offset= (size_t) &retval; - size= sizeof(retval); - } - if (c != 0 && c != ',') goto fail; - *poffset= (void *) offset; - *psize= size; - return c != 0; -fail: - while (c != 0 && c != ',') c= (*qgetc)(); - *poffset= nil; - *psize= 0; - return c != 0; -} - -/* - * $PchId: queryparam.c,v 1.1 2005/06/28 14:30:56 philip Exp $ - */ diff --git a/minix/net/inet/queryparam.h b/minix/net/inet/queryparam.h deleted file mode 100644 index 8f3b4e9af..000000000 --- a/minix/net/inet/queryparam.h +++ /dev/null @@ -1,44 +0,0 @@ -/* queryparam.h - query program parameters Author: Kees J. Bot - * 22 Apr 1994 - */ -#ifndef _MINIX__QUERYPARAM_H -#define _MINIX__QUERYPARAM_H - - -typedef size_t _mnx_size_t; - -struct export_param_list { - char *name; /* "variable", "[", ".field", or NULL. */ - void *offset; /* Address of a variable or field offset. */ - size_t size; /* Size of the resulting object. */ -}; - -struct export_params { - struct export_param_list *list; /* List of exported parameters. */ - struct export_params *next; /* Link several sets of parameters. */ -}; - -#ifdef __STDC__ -#define qp_stringize(var) (char *) #var -#define qp_dotstringize(var) "." (char *) #var -#else -#define qp_stringize(var) "var" -#define qp_dotstringize(var) ".var" -#endif -#define QP_VARIABLE(var) { qp_stringize(var), &(var), sizeof(var) } -#define QP_ARRAY(var) { (char *) "[", 0, sizeof((var)[0]) } -#define QP_VECTOR(var,ptr,len) { qp_stringize(var), &(ptr), -1 },\ - { (char *) "[", &(len), sizeof(*(ptr)) } -#define QP_FIELD(field, type) { qp_dotstringize(field), \ - (void *)offsetof(type, field), \ - sizeof(((type *)0)->field) } -#define QP_END() { 0, 0, 0 } - -void qp_export(struct export_params *_ex_params); -int queryparam(int (*_qgetc) (void), void **_paddress, _mnx_size_t - *_psize); -_mnx_size_t paramvalue(char **_value, void *_address, _mnx_size_t - _size); -#endif /* _MINIX__QUERYPARAM_H */ - -/* $PchId: queryparam.h,v 1.1 2005/06/28 14:31:26 philip Exp $ */ diff --git a/minix/net/inet/rtinfo.c b/minix/net/inet/rtinfo.c deleted file mode 100644 index 7235abfa4..000000000 --- a/minix/net/inet/rtinfo.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Mock net.route sysctl(2) subtree implementation using RMIB. This code - * serves as a temporary bridge to allow libc to switch from the original, - * native MINIX3 getifaddrs(3) to the NetBSD getifaddrs(3). As such, it - * implements only a small subset of NetBSD's full net.route functionality, - * although also more than needed only to imitate the MINIX3 getifaddrs(3). - */ - -#include "inet.h" -#include "generic/type.h" -#include "generic/buf.h" -#include "generic/event.h" -#include "generic/ip_int.h" -#include "osdep_eth.h" -#include "generic/eth_int.h" -#include -#include -#include -#include -#include -#include -#include - -/* Max. number of bytes for a full sockaddr_dl structure, including data. */ -#define SDL_BUFSIZE (sizeof(struct sockaddr_dl) + 32) - -static const char padbuf[RT_ROUNDUP(0)] = { 0 }; - -/* - * Compute the length for, and possibly copy out, an interface information or - * interface address record with an associated set of zero or more routing - * table addresses. The addresses are padded as necessary. Store the full - * record length and the address bitmap before copying out the entire record. - */ -static ssize_t -copyout_rta(void * hdr, size_t size, u_short * msglen, int * addrs, - void * rta_map[RTAX_MAX], size_t rta_len[RTAX_MAX], - struct rmib_oldp * oldp, ssize_t off) -{ - iovec_t iov[1 + RTAX_MAX * 2]; - size_t len, total, padlen; - unsigned int i, iovcnt; - int mask; - - iovcnt = 0; - iov[iovcnt].iov_addr = (vir_bytes)hdr; - iov[iovcnt++].iov_size = size; - - total = size; - mask = 0; - - /* - * Any addresses in the given map should be stored in the numbering - * order of the map. - */ - for (i = 0; i < RTAX_MAX; i++) { - if (rta_map[i] == NULL) - continue; - - assert(iovcnt < __arraycount(iov)); - iov[iovcnt].iov_addr = (vir_bytes)rta_map[i]; - iov[iovcnt++].iov_size = len = rta_len[i]; - - padlen = RT_ROUNDUP(len) - len; - if (padlen > 0) { - assert(iovcnt < __arraycount(iov)); - iov[iovcnt].iov_addr = (vir_bytes)padbuf; - iov[iovcnt++].iov_size = padlen; - } - - total += len + padlen; - mask |= (1 << i); - } - - /* If only the length was requested, return it now. */ - if (oldp == NULL) - return total; - - /* - * Casting 'hdr' would violate C99 strict aliasing rules, so store the - * computed header values through direct pointers. Bah. - */ - *msglen = total; - *addrs = mask; - - return rmib_vcopyout(oldp, off, iov, iovcnt); -} - -/* - * Given an INET ip-layer datalink type, return a matching BSD interface type. - */ -static unsigned char -ipdl_to_ift(int ip_dl_type) -{ - - switch (ip_dl_type) { - case IPDL_ETH: - return IFT_ETHER; - case IPDL_PSIP: - return IFT_LOOP; - default: - return IFT_OTHER; - } -} - -/* - * Compute the length for, and possibly generate, a sockaddr_dl structure for - * the given interface. The complication here is that the structure contains - * various field packed together dynamically, making it variable sized. - */ -static size_t -make_sdl(const ip_port_t * ip_port, int ndx, char * buf, size_t max) -{ - const eth_port_t *eth_port; - struct sockaddr_dl sdl; - static char namebuf[8]; - const void *addrptr; - size_t hdrlen, namelen, addrlen, padlen, len; - - /* Normally the interface name would be pregenerated somewhere. */ - snprintf(namebuf, sizeof(namebuf), "ip%u", ip_port->ip_port); - namelen = strlen(namebuf); - - addrlen = 0; - if (ip_port->ip_dl_type == IPDL_ETH) { - eth_port = ð_port_table[ip_port->ip_dl.dl_eth.de_port]; - if (eth_port->etp_flags & EPF_GOT_ADDR) { - addrptr = ð_port->etp_ethaddr; - addrlen = sizeof(eth_port->etp_ethaddr); - } - } - - /* - * Compute the unpadded and padded length of the structure. We pad the - * structure ourselves here, even though the caller will otherwise pad - * it later, because it is easy to do so and saves on a vector element. - */ - hdrlen = offsetof(struct sockaddr_dl, sdl_data); - len = hdrlen + namelen + addrlen; - padlen = RT_ROUNDUP(len) - len; - assert(len + padlen <= max); - - /* If we are asked not to generate the actual data, stop here. */ - if (buf == NULL) - return len + padlen; - - /* - * Fill the sockaddr_dl structure header. The C99 strict aliasing - * rules prevent us from filling 'buf' through a pointer structure - * directly. - */ - memset(&sdl, 0, hdrlen); - sdl.sdl_len = len; - sdl.sdl_family = AF_LINK; - sdl.sdl_index = ndx; - sdl.sdl_type = ipdl_to_ift(ip_port->ip_dl_type); - sdl.sdl_nlen = namelen; - sdl.sdl_alen = addrlen; - sdl.sdl_slen = 0; - - /* - * Generate the full sockaddr_dl structure in the given buffer. These - * memory sizes are typically small, so the extra memory copies are not - * too expensive. The advantage of generating a single sockaddr_dl - * structure buffer is that we can use copyout_rta() on it. - */ - memcpy(buf, &sdl, hdrlen); - if (namelen > 0) - memcpy(&buf[hdrlen], namebuf, namelen); - if (addrlen > 0) - memcpy(&buf[hdrlen + namelen], addrptr, addrlen); - if (padlen > 0) - memset(&buf[len], 0, padlen); - - return len + padlen; -} - -/* - * Compute the length for, and possibly generate, an interface information - * record for the given interface. - */ -static ssize_t -gen_ifm(const ip_port_t * ip_port, int ndx, int is_up, struct rmib_oldp * oldp, - ssize_t off) -{ - struct if_msghdr ifm; - char buf[SDL_BUFSIZE]; - void *rta_map[RTAX_MAX]; - size_t rta_len[RTAX_MAX], size; - - if (oldp != NULL) { - memset(&ifm, 0, sizeof(ifm)); - ifm.ifm_version = RTM_VERSION; - ifm.ifm_type = RTM_IFINFO; - ifm.ifm_flags = (is_up) ? (IFF_UP | IFF_RUNNING) : 0; - ifm.ifm_index = ndx; - ifm.ifm_data.ifi_type = ipdl_to_ift(ip_port->ip_dl_type); - if (ifm.ifm_data.ifi_type == IFT_LOOP) - ifm.ifm_flags |= IFF_LOOPBACK; - /* TODO: other ifm_flags, other ifm_data fields, etc. */ - } - - /* - * Note that we add padding even in this case, to ensure that the - * following structures are properly aligned as well. - */ - size = make_sdl(ip_port, ndx, (oldp != NULL) ? buf : NULL, - sizeof(buf)); - - memset(rta_map, 0, sizeof(rta_map)); - rta_map[RTAX_IFP] = buf; - rta_len[RTAX_IFP] = size; - - return copyout_rta(&ifm, sizeof(ifm), &ifm.ifm_msglen, &ifm.ifm_addrs, - rta_map, rta_len, oldp, off); -} - -/* - * Compute the length for, and possibly generate, an AF_LINK-family interface - * address record. - */ -static ssize_t -gen_ifam_dl(const ip_port_t * ip_port, int ndx, int is_up, - struct rmib_oldp * oldp, ssize_t off) -{ - struct ifa_msghdr ifam; - char buf[SDL_BUFSIZE]; - void *rta_map[RTAX_MAX]; - size_t rta_len[RTAX_MAX], size; - - if (oldp != NULL) { - memset(&ifam, 0, sizeof(ifam)); - ifam.ifam_version = RTM_VERSION; - ifam.ifam_type = RTM_NEWADDR; - ifam.ifam_index = ndx; - ifam.ifam_metric = 0; /* unknown and irrelevant */ - } - - size = make_sdl(ip_port, ndx, (oldp != NULL) ? buf : NULL, - sizeof(buf)); - - /* - * We do not generate a netmask. NetBSD seems to generate a netmask - * with all-one bits for the number of bytes equal to the name length, - * for reasons unknown to me. If we did the same, we would end up with - * a conflict on the static 'namebuf' buffer. - */ - memset(rta_map, 0, sizeof(rta_map)); - rta_map[RTAX_IFA] = buf; - rta_len[RTAX_IFA] = size; - - return copyout_rta(&ifam, sizeof(ifam), &ifam.ifam_msglen, - &ifam.ifam_addrs, rta_map, rta_len, oldp, off); -} - -/* - * Compute the length for, and possibly generate, an AF_INET-family interface - * address record. - */ -static ssize_t -gen_ifam_inet(const ip_port_t * ip_port, int ndx, int is_up, - struct rmib_oldp * oldp, ssize_t off) -{ - struct ifa_msghdr ifam; - struct sockaddr_in ipaddr, netmask; - void *rta_map[RTAX_MAX]; - size_t rta_len[RTAX_MAX]; - - if (oldp != NULL) { - memset(&ifam, 0, sizeof(ifam)); - ifam.ifam_msglen = sizeof(ifam); - ifam.ifam_version = RTM_VERSION; - ifam.ifam_type = RTM_NEWADDR; - ifam.ifam_addrs = 0; - ifam.ifam_index = ndx; - ifam.ifam_metric = 0; /* unknown and irrelevant */ - } - - memset(rta_map, 0, sizeof(rta_map)); - - if (ip_port->ip_flags & IPF_IPADDRSET) { - if (oldp != NULL) { - memset(&ipaddr, 0, sizeof(ipaddr)); - ipaddr.sin_family = AF_INET; - ipaddr.sin_len = sizeof(ipaddr); - ipaddr.sin_addr.s_addr = ip_port->ip_ipaddr; - } - - rta_map[RTAX_IFA] = &ipaddr; - rta_len[RTAX_IFA] = sizeof(ipaddr); - } - - if (ip_port->ip_flags & IPF_NETMASKSET) { - /* - * TODO: BSD goes through the trouble of compressing the - * netmask for some reason. We need to figure out if - * compression is actually required by any part of userland. - */ - if (oldp != NULL) { - memset(&netmask, 0, sizeof(netmask)); - netmask.sin_family = AF_INET; - netmask.sin_len = sizeof(netmask); - netmask.sin_addr.s_addr = ip_port->ip_subnetmask; - } - - rta_map[RTAX_NETMASK] = &netmask; - rta_len[RTAX_NETMASK] = sizeof(netmask); - } - - return copyout_rta(&ifam, sizeof(ifam), &ifam.ifam_msglen, - &ifam.ifam_addrs, rta_map, rta_len, oldp, off); -} - -/* - * Compute the size needed for, and optionally copy out, the interface and - * address information for the given interface. - */ -static ssize_t -do_one_if(const ip_port_t * ip_port, int ndx, struct rmib_oldp * oldp, - ssize_t off, int filter) -{ - ssize_t r, len; - int is_up; - - /* - * If the interface is not configured, we mark it as down and do not - * provide IP address information. - */ - is_up = (ip_port->ip_flags & IPF_IPADDRSET); - - len = 0; - - /* There is always a full interface information record. */ - if ((r = gen_ifm(ip_port, ndx, is_up, oldp, off)) < 0) - return r; - len += r; - - /* If not filtered, there is a datalink address record. */ - if (filter == 0 || filter == AF_LINK) { - if ((r = gen_ifam_dl(ip_port, ndx, is_up, oldp, - off + len)) < 0) - return r; - len += r; - } - - /* If configured and not filtered, there is an IPv4 address record. */ - if (is_up && (filter == 0 || filter == AF_INET)) { - if ((r = gen_ifam_inet(ip_port, ndx, is_up, oldp, - off + len)) < 0) - return r; - len += r; - } - - /* - * Whether or not anything was copied out, upon success we return the - * full length of the data. - */ - return len; -} - -/* - * Remote MIB implementation of CTL_NET PF_ROUTE 0. This function handles all - * queries on the "net.route.rtable" sysctl(2) node. - */ -static ssize_t -net_route_rtable(struct rmib_call * call, struct rmib_node * node __unused, - struct rmib_oldp * oldp, struct rmib_newp * newp __unused) -{ - const ip_port_t *ip_port; - ssize_t r, off; - int i, filter, ndx; - - if (call->call_namelen != 3) - return EINVAL; - - /* We only support listing interfaces for now. */ - if (call->call_name[1] != NET_RT_IFLIST) - return EOPNOTSUPP; - - filter = call->call_name[0]; - ndx = call->call_name[2]; - - off = 0; - - for (i = 0, ip_port = ip_port_table; i < ip_conf_nr; i++, ip_port++) { - if (!(ip_port->ip_flags & IPF_CONFIGURED)) - continue; - - /* - * If information about a specific interface index is requested - * then skip all other entries. Interface indices must be - * nonzero, so we shift the numbers by one. We can avoid going - * through the loop altogether here, but getifaddrs(3) does not - * query specific interfaces anyway. - */ - if (ndx != 0 && ndx != ip_port->ip_port + 1) - continue; - - /* Avoid generating results that are never copied out. */ - if (oldp != NULL && !rmib_inrange(oldp, off)) - oldp = NULL; - - if ((r = do_one_if(ip_port, ip_port->ip_port + 1, oldp, off, - filter)) < 0) - return r; - - off += r; - } - - return off; -} - -/* The CTL_NET PF_ROUTE subtree. */ -static struct rmib_node net_route_table[] = { - [0] = RMIB_FUNC(RMIB_RO | CTLTYPE_NODE, 0, net_route_rtable, - "rtable", "Routing table information") -}; - -/* The CTL_NET PF_ROUTE node. */ -static struct rmib_node net_route_node = - RMIB_NODE(RMIB_RO, net_route_table, "route", "PF_ROUTE information"); - -/* - * Register the net.route RMIB subtree with the MIB service. Since inet does - * not support clean shutdowns, there is no matching cleanup function. - */ -void -rtinfo_init(void) -{ - const int mib[] = { CTL_NET, PF_ROUTE }; - int r; - - if ((r = rmib_register(mib, __arraycount(mib), &net_route_node)) != OK) - panic("unable to register remote MIB tree: %d", r); -} diff --git a/minix/net/inet/sr.c b/minix/net/inet/sr.c deleted file mode 100644 index 8cf5d950c..000000000 --- a/minix/net/inet/sr.c +++ /dev/null @@ -1,836 +0,0 @@ -/* this file contains the interface of the network software with the file - * system. - * - * Copyright 1995 Philip Homburg - */ - -#include "inet.h" - -#include "mq.h" -#include "qp.h" -#include "proto.h" -#include "generic/type.h" - -#include "generic/assert.h" -#include "generic/buf.h" -#include "generic/event.h" -#include "generic/sr.h" -#include "sr_int.h" - -THIS_FILE - -sr_fd_t sr_fd_table[FD_NR]; - -static struct vscp_vec s_cp_req[SCPVEC_NR]; - -static int sr_open(devminor_t minor, int access, endpoint_t user_endpt); -static int sr_close(devminor_t minor); -static ssize_t sr_read(devminor_t minor, u64_t position, endpoint_t endpt, - cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); -static ssize_t sr_write(devminor_t minor, u64_t position, endpoint_t endpt, - cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); -static int sr_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, - cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id); -static int sr_rwio(sr_req_t *req); -static int sr_restart_read(sr_fd_t *fdp); -static int sr_restart_write(sr_fd_t *fdp); -static int sr_restart_ioctl(sr_fd_t *fdp); -static int sr_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id); -static int sr_select(devminor_t minor, unsigned int ops, endpoint_t endpt); -static sr_fd_t *sr_getchannel(int minor); -static acc_t *sr_get_userdata(int fd, size_t offset, size_t count, int - for_ioctl); -static int sr_put_userdata(int fd, size_t offset, acc_t *data, int - for_ioctl); -static void sr_select_res(int fd, unsigned ops); -static int walk_queue(sr_fd_t *sr_fd, mq_t **q_head_ptr, mq_t **q_tail_ptr, - int type, endpoint_t endpt, cdev_id_t id, int first_flag); -static void sr_event(event_t *evp, ev_arg_t arg); -static int cp_u2b(endpoint_t proc, cp_grant_id_t gid, vir_bytes offset, - acc_t **var_acc_ptr, int size); -static int cp_b2u(acc_t *acc_ptr, endpoint_t proc, cp_grant_id_t gid, - vir_bytes offset); - -static struct chardriver inet_tab = { - .cdr_open = sr_open, - .cdr_close = sr_close, - .cdr_read = sr_read, - .cdr_write = sr_write, - .cdr_ioctl = sr_ioctl, - .cdr_cancel = sr_cancel, - .cdr_select = sr_select -}; - -void sr_init() -{ - int i; - - for (i=0; i=0 && minorsrf_flags & SFF_INUSE)); - - sr_fd->srf_flags= SFF_INUSE | SFF_MINOR; - sr_fd->srf_port= port; - sr_fd->srf_open= openf; - sr_fd->srf_close= closef; - sr_fd->srf_write= writef; - sr_fd->srf_read= readf; - sr_fd->srf_ioctl= ioctlf; - sr_fd->srf_cancel= cancelf; - sr_fd->srf_select= selectf; -} - -static int sr_open(devminor_t minor, int UNUSED(access), - endpoint_t UNUSED(user_endpt)) -{ - sr_fd_t *sr_fd; - int i, fd; - - if (minor<0 || minor>FD_NR) - { - DBLOCK(1, printf("replying EINVAL\n")); - return EINVAL; - } - if (!(sr_fd_table[minor].srf_flags & SFF_MINOR)) - { - DBLOCK(1, printf("replying ENXIO\n")); - return ENXIO; - } - for (i=0; i=FD_NR) - { - DBLOCK(1, printf("replying ENFILE\n")); - return ENFILE; - } - - sr_fd= &sr_fd_table[i]; - *sr_fd= sr_fd_table[minor]; - sr_fd->srf_flags= SFF_INUSE; - fd= (*sr_fd->srf_open)(sr_fd->srf_port, i, sr_get_userdata, - sr_put_userdata, 0 /* no put_pkt */, sr_select_res); - if (fd<0) - { - sr_fd->srf_flags= SFF_FREE; - DBLOCK(1, printf("replying %d\n", fd)); - return fd; - } - sr_fd->srf_fd= fd; - return CDEV_CLONED | i; -} - -static int sr_close(devminor_t minor) -{ - sr_fd_t *sr_fd; - - sr_fd= sr_getchannel(minor); - assert (sr_fd); - - if (sr_fd->srf_flags & SFF_BUSY) - ip_panic(("close on busy channel")); - - assert (!(sr_fd->srf_flags & SFF_MINOR)); - (*sr_fd->srf_close)(sr_fd->srf_fd); - sr_fd->srf_flags= SFF_FREE; - - return OK; -} - -static int sr_rwio(sr_req_t *req) -{ - sr_fd_t *sr_fd; - mq_t *m, **q_head_ptr = NULL, **q_tail_ptr = NULL; - int ip_flag = 0, susp_flag = 0, first_flag = 0; - int r = OK; - ioreq_t request; - size_t size; - - if (!(m = mq_get())) - ip_panic(("out of messages")); - m->mq_req = *req; - - sr_fd= sr_getchannel(m->mq_req.srr_minor); - assert (sr_fd); - - switch(m->mq_req.srr_type) - { - case SRR_READ: - q_head_ptr= &sr_fd->srf_read_q; - q_tail_ptr= &sr_fd->srf_read_q_tail; - ip_flag= SFF_READ_IP; - susp_flag= SFF_READ_SUSP; - first_flag= SFF_READ_FIRST; - break; - case SRR_WRITE: - q_head_ptr= &sr_fd->srf_write_q; - q_tail_ptr= &sr_fd->srf_write_q_tail; - ip_flag= SFF_WRITE_IP; - susp_flag= SFF_WRITE_SUSP; - first_flag= SFF_WRITE_FIRST; - break; - case SRR_IOCTL: - q_head_ptr= &sr_fd->srf_ioctl_q; - q_tail_ptr= &sr_fd->srf_ioctl_q_tail; - ip_flag= SFF_IOCTL_IP; - susp_flag= SFF_IOCTL_SUSP; - first_flag= SFF_IOCTL_FIRST; - break; - default: - ip_panic(("illegal request type")); - } - - if (sr_fd->srf_flags & ip_flag) - { - assert(sr_fd->srf_flags & susp_flag); - assert(*q_head_ptr); - - if (m->mq_req.srr_flags & CDEV_NONBLOCK) { - mq_free(m); - return EAGAIN; - } - - (*q_tail_ptr)->mq_next= m; - *q_tail_ptr= m; - return EDONTREPLY; - } - assert(!*q_head_ptr); - - *q_tail_ptr= *q_head_ptr= m; - sr_fd->srf_flags |= ip_flag; - assert(!(sr_fd->srf_flags & first_flag)); - sr_fd->srf_flags |= first_flag; - - switch(m->mq_req.srr_type) - { - case SRR_READ: - r= (*sr_fd->srf_read)(sr_fd->srf_fd, m->mq_req.srr_size); - break; - case SRR_WRITE: - r= (*sr_fd->srf_write)(sr_fd->srf_fd, m->mq_req.srr_size); - break; - case SRR_IOCTL: - request= m->mq_req.srr_req; - size= _MINIX_IOCTL_SIZE(request); - if (size>MAX_IOCTL_S) - { - DBLOCK(1, printf("replying EINVAL\n")); - r= sr_put_userdata(sr_fd-sr_fd_table, EINVAL, - NULL, 1); - assert(r == OK); - assert(sr_fd->srf_flags & first_flag); - sr_fd->srf_flags &= ~first_flag; - return EDONTREPLY; - } - r= (*sr_fd->srf_ioctl)(sr_fd->srf_fd, request); - break; - default: - ip_panic(("illegal case entry")); - } - - assert(sr_fd->srf_flags & first_flag); - sr_fd->srf_flags &= ~first_flag; - - assert(r == OK || r == SUSPEND || - (printf("r= %d\n", r), 0)); - if (r == SUSPEND) { - sr_fd->srf_flags |= susp_flag; - if (m->mq_req.srr_flags & CDEV_NONBLOCK) { - r= sr_cancel(m->mq_req.srr_minor, m->mq_req.srr_endpt, - m->mq_req.srr_id); - assert(r == EDONTREPLY); /* head of the queue */ - } - } else - mq_free(m); - return EDONTREPLY; /* request already completed */ -} - -static ssize_t sr_read(devminor_t minor, u64_t UNUSED(position), - endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, - cdev_id_t id) -{ - sr_req_t req; - - req.srr_type = SRR_READ; - req.srr_minor = minor; - req.srr_endpt = endpt; - req.srr_grant = grant; - req.srr_size = size; - req.srr_flags = flags; - req.srr_id = id; - - return sr_rwio(&req); -} - -static ssize_t sr_write(devminor_t minor, u64_t UNUSED(position), - endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, - cdev_id_t id) -{ - sr_req_t req; - - req.srr_type = SRR_WRITE; - req.srr_minor = minor; - req.srr_endpt = endpt; - req.srr_grant = grant; - req.srr_size = size; - req.srr_flags = flags; - req.srr_id = id; - - return sr_rwio(&req); -} - -static int sr_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, - cp_grant_id_t grant, int flags, endpoint_t UNUSED(user_endpt), - cdev_id_t id) -{ - sr_req_t req; - - req.srr_type = SRR_IOCTL; - req.srr_minor = minor; - req.srr_req = request; - req.srr_endpt = endpt; - req.srr_grant = grant; - req.srr_flags = flags; - req.srr_id = id; - - return sr_rwio(&req); -} - -static int sr_restart_read(sr_fd) -sr_fd_t *sr_fd; -{ - mq_t *mp; - int r; - - mp= sr_fd->srf_read_q; - assert(mp); - - if (sr_fd->srf_flags & SFF_READ_IP) - { - assert(sr_fd->srf_flags & SFF_READ_SUSP); - return SUSPEND; - } - sr_fd->srf_flags |= SFF_READ_IP; - - r= (*sr_fd->srf_read)(sr_fd->srf_fd, mp->mq_req.srr_size); - - assert(r == OK || r == SUSPEND || - (printf("r= %d\n", r), 0)); - if (r == SUSPEND) - sr_fd->srf_flags |= SFF_READ_SUSP; - return r; -} - -static int sr_restart_write(sr_fd) -sr_fd_t *sr_fd; -{ - mq_t *mp; - int r; - - mp= sr_fd->srf_write_q; - assert(mp); - - if (sr_fd->srf_flags & SFF_WRITE_IP) - { - assert(sr_fd->srf_flags & SFF_WRITE_SUSP); - return SUSPEND; - } - sr_fd->srf_flags |= SFF_WRITE_IP; - - r= (*sr_fd->srf_write)(sr_fd->srf_fd, mp->mq_req.srr_size); - - assert(r == OK || r == SUSPEND || - (printf("r= %d\n", r), 0)); - if (r == SUSPEND) - sr_fd->srf_flags |= SFF_WRITE_SUSP; - return r; -} - -static int sr_restart_ioctl(sr_fd) -sr_fd_t *sr_fd; -{ - mq_t *mp; - int r; - - mp= sr_fd->srf_ioctl_q; - assert(mp); - - if (sr_fd->srf_flags & SFF_IOCTL_IP) - { - assert(sr_fd->srf_flags & SFF_IOCTL_SUSP); - return SUSPEND; - } - sr_fd->srf_flags |= SFF_IOCTL_IP; - - r= (*sr_fd->srf_ioctl)(sr_fd->srf_fd, mp->mq_req.srr_req); - - assert(r == OK || r == SUSPEND || - (printf("r= %d\n", r), 0)); - if (r == SUSPEND) - sr_fd->srf_flags |= SFF_IOCTL_SUSP; - return r; -} - -static int sr_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id) -{ - sr_fd_t *sr_fd; - int result; - - sr_fd= sr_getchannel(minor); - assert (sr_fd); - - result= walk_queue(sr_fd, &sr_fd->srf_ioctl_q, - &sr_fd->srf_ioctl_q_tail, SR_CANCEL_IOCTL, - endpt, id, SFF_IOCTL_FIRST); - if (result != EAGAIN) - return (result == OK) ? EDONTREPLY : EINTR; - - result= walk_queue(sr_fd, &sr_fd->srf_read_q, - &sr_fd->srf_read_q_tail, SR_CANCEL_READ, - endpt, id, SFF_READ_FIRST); - if (result != EAGAIN) - return (result == OK) ? EDONTREPLY : EINTR; - - result= walk_queue(sr_fd, &sr_fd->srf_write_q, - &sr_fd->srf_write_q_tail, SR_CANCEL_WRITE, - endpt, id, SFF_WRITE_FIRST); - if (result != EAGAIN) - return (result == OK) ? EDONTREPLY : EINTR; - - /* We already replied to the request, so don't reply to the CANCEL. */ - return EDONTREPLY; -} - -static int sr_select(devminor_t minor, unsigned int ops, endpoint_t endpt) -{ - sr_fd_t *sr_fd; - int r, m_ops; - unsigned int i_ops; - - sr_fd= sr_getchannel(minor); - assert (sr_fd); - - sr_fd->srf_select_proc= endpt; - - i_ops= 0; - if (ops & CDEV_OP_RD) i_ops |= SR_SELECT_READ; - if (ops & CDEV_OP_WR) i_ops |= SR_SELECT_WRITE; - if (ops & CDEV_OP_ERR) i_ops |= SR_SELECT_EXCEPTION; - if (!(ops & CDEV_NOTIFY)) i_ops |= SR_SELECT_POLL; - - r= (*sr_fd->srf_select)(sr_fd->srf_fd, i_ops); - if (r < 0) { - m_ops= r; - } else { - m_ops= 0; - if (r & SR_SELECT_READ) m_ops |= CDEV_OP_RD; - if (r & SR_SELECT_WRITE) m_ops |= CDEV_OP_WR; - if (r & SR_SELECT_EXCEPTION) m_ops |= CDEV_OP_ERR; - } - - return m_ops; -} - -static int walk_queue(sr_fd, q_head_ptr, q_tail_ptr, type, endpt, id, - first_flag) -sr_fd_t *sr_fd; -mq_t **q_head_ptr; -mq_t **q_tail_ptr; -int type; -endpoint_t endpt; -cdev_id_t id; -int first_flag; -{ - mq_t *q_ptr_prv, *q_ptr; - int result; - - for(q_ptr_prv= NULL, q_ptr= *q_head_ptr; q_ptr; - q_ptr_prv= q_ptr, q_ptr= q_ptr->mq_next) - { - if (q_ptr->mq_req.srr_endpt != endpt) - continue; - if (q_ptr->mq_req.srr_id != id) - continue; - if (!q_ptr_prv) - { - assert(!(sr_fd->srf_flags & first_flag)); - sr_fd->srf_flags |= first_flag; - - /* This will also send a reply. */ - result= (*sr_fd->srf_cancel)(sr_fd->srf_fd, type); - assert(result == OK); - - *q_head_ptr= q_ptr->mq_next; - mq_free(q_ptr); - - assert(sr_fd->srf_flags & first_flag); - sr_fd->srf_flags &= ~first_flag; - - return OK; - } - q_ptr_prv->mq_next= q_ptr->mq_next; - mq_free(q_ptr); - if (!q_ptr_prv->mq_next) - *q_tail_ptr= q_ptr_prv; - return EINTR; - } - return EAGAIN; -} - -static sr_fd_t *sr_getchannel(minor) -int minor; -{ - sr_fd_t *loc_fd; - - compare(minor, >=, 0); - compare(minor, <, FD_NR); - - loc_fd= &sr_fd_table[minor]; - - assert (!(loc_fd->srf_flags & SFF_MINOR) && - (loc_fd->srf_flags & SFF_INUSE)); - - return loc_fd; -} - -static acc_t *sr_get_userdata (fd, offset, count, for_ioctl) -int fd; -size_t offset; -size_t count; -int for_ioctl; -{ - sr_fd_t *loc_fd; - mq_t **head_ptr, *m, *mq; - int ip_flag, susp_flag, first_flag; - int result, suspended, is_revive; - acc_t *acc; - event_t *evp; - ev_arg_t arg; - - loc_fd= &sr_fd_table[fd]; - - if (for_ioctl) - { - head_ptr= &loc_fd->srf_ioctl_q; - evp= &loc_fd->srf_ioctl_ev; - ip_flag= SFF_IOCTL_IP; - susp_flag= SFF_IOCTL_SUSP; - first_flag= SFF_IOCTL_FIRST; - } - else - { - head_ptr= &loc_fd->srf_write_q; - evp= &loc_fd->srf_write_ev; - ip_flag= SFF_WRITE_IP; - susp_flag= SFF_WRITE_SUSP; - first_flag= SFF_WRITE_FIRST; - } - - assert (loc_fd->srf_flags & ip_flag); - - if (!count) - { - m= *head_ptr; - mq= m->mq_next; - *head_ptr= mq; - result= (int)offset; - is_revive= !(loc_fd->srf_flags & first_flag); - chardriver_reply_task(m->mq_req.srr_endpt, m->mq_req.srr_id, - result); - if (is_revive) - mq_free(m); - suspended= (loc_fd->srf_flags & susp_flag); - loc_fd->srf_flags &= ~(ip_flag|susp_flag); - if (suspended) - { - if (mq) - { - arg.ev_ptr= loc_fd; - ev_enqueue(evp, sr_event, arg); - } - } - return NULL; - } - - result= cp_u2b ((*head_ptr)->mq_req.srr_endpt, - (*head_ptr)->mq_req.srr_grant, offset, &acc, count); - - return result<0 ? NULL : acc; -} - -static int sr_put_userdata (fd, offset, data, for_ioctl) -int fd; -size_t offset; -acc_t *data; -int for_ioctl; -{ - sr_fd_t *loc_fd; - mq_t **head_ptr, *m, *mq; - int ip_flag, susp_flag, first_flag; - int result, suspended, is_revive; - event_t *evp; - ev_arg_t arg; - - loc_fd= &sr_fd_table[fd]; - - if (for_ioctl) - { - head_ptr= &loc_fd->srf_ioctl_q; - evp= &loc_fd->srf_ioctl_ev; - ip_flag= SFF_IOCTL_IP; - susp_flag= SFF_IOCTL_SUSP; - first_flag= SFF_IOCTL_FIRST; - } - else - { - head_ptr= &loc_fd->srf_read_q; - evp= &loc_fd->srf_read_ev; - ip_flag= SFF_READ_IP; - susp_flag= SFF_READ_SUSP; - first_flag= SFF_READ_FIRST; - } - - assert (loc_fd->srf_flags & ip_flag); - - if (!data) - { - m= *head_ptr; - mq= m->mq_next; - *head_ptr= mq; - result= (int)offset; - is_revive= !(loc_fd->srf_flags & first_flag); - chardriver_reply_task(m->mq_req.srr_endpt, m->mq_req.srr_id, - result); - if (is_revive) - mq_free(m); - suspended= (loc_fd->srf_flags & susp_flag); - loc_fd->srf_flags &= ~(ip_flag|susp_flag); - if (suspended) - { - if (mq) - { - arg.ev_ptr= loc_fd; - ev_enqueue(evp, sr_event, arg); - } - } - return OK; - } - - return cp_b2u (data, (*head_ptr)->mq_req.srr_endpt, - (*head_ptr)->mq_req.srr_grant, offset); -} - -static void sr_select_res(int fd, unsigned ops) -{ - sr_fd_t *sr_fd; - unsigned int m_ops; - - sr_fd= &sr_fd_table[fd]; - - m_ops= 0; - if (ops & SR_SELECT_READ) m_ops |= CDEV_OP_RD; - if (ops & SR_SELECT_WRITE) m_ops |= CDEV_OP_WR; - if (ops & SR_SELECT_EXCEPTION) m_ops |= CDEV_OP_ERR; - - chardriver_reply_select(sr_fd->srf_select_proc, fd, m_ops); -} - -static void sr_event(evp, arg) -event_t *evp; -ev_arg_t arg; -{ - sr_fd_t *sr_fd; - int r; - - sr_fd= arg.ev_ptr; - if (evp == &sr_fd->srf_write_ev) - { - while(sr_fd->srf_write_q) - { - r= sr_restart_write(sr_fd); - if (r == SUSPEND) - return; - } - return; - } - if (evp == &sr_fd->srf_read_ev) - { - while(sr_fd->srf_read_q) - { - r= sr_restart_read(sr_fd); - if (r == SUSPEND) - return; - } - return; - } - if (evp == &sr_fd->srf_ioctl_ev) - { - while(sr_fd->srf_ioctl_q) - { - r= sr_restart_ioctl(sr_fd); - if (r == SUSPEND) - return; - } - return; - } - ip_panic(("sr_event: unknown event\n")); -} - -static int cp_u2b(proc, gid, offset, var_acc_ptr, size) -endpoint_t proc; -cp_grant_id_t gid; -vir_bytes offset; -acc_t **var_acc_ptr; -int size; -{ - acc_t *acc; - int i, r; - - acc= bf_memreq(size); - - *var_acc_ptr= acc; - i=0; - - while (acc) - { - size= (vir_bytes)acc->acc_length; - - s_cp_req[i].v_from= proc; - s_cp_req[i].v_to= SELF; - s_cp_req[i].v_gid= gid; - s_cp_req[i].v_offset= offset; - s_cp_req[i].v_addr= (vir_bytes) ptr2acc_data(acc); - s_cp_req[i].v_bytes= size; - - offset += size; - acc= acc->acc_next; - i++; - - if (acc == NULL && i == 1) - { - r= sys_safecopyfrom(s_cp_req[0].v_from, - s_cp_req[0].v_gid, s_cp_req[0].v_offset, - s_cp_req[0].v_addr, s_cp_req[0].v_bytes); - if (r <0) - { - printf("sys_safecopyfrom failed: %d\n", r); - bf_afree(*var_acc_ptr); - *var_acc_ptr= 0; - return r; - } - i= 0; - continue; - } - if (i == SCPVEC_NR || acc == NULL) - { - r= sys_vsafecopy(s_cp_req, i); - - if (r <0) - { - printf("cp_u2b: sys_vsafecopy failed: %d\n", - r); - bf_afree(*var_acc_ptr); - *var_acc_ptr= 0; - return r; - } - i= 0; - } - } - return OK; -} - -static int cp_b2u(acc_ptr, proc, gid, offset) -acc_t *acc_ptr; -endpoint_t proc; -cp_grant_id_t gid; -vir_bytes offset; -{ - acc_t *acc; - int i, r, size; - - acc= acc_ptr; - i=0; - - while (acc) - { - size= (vir_bytes)acc->acc_length; - - if (size) - { - s_cp_req[i].v_from= SELF; - s_cp_req[i].v_to= proc; - s_cp_req[i].v_gid= gid; - s_cp_req[i].v_offset= offset; - s_cp_req[i].v_addr= (vir_bytes) ptr2acc_data(acc); - s_cp_req[i].v_bytes= size; - - i++; - } - - offset += size; - acc= acc->acc_next; - - if (acc == NULL && i == 1) - { - r= sys_safecopyto(s_cp_req[0].v_to, - s_cp_req[0].v_gid, s_cp_req[0].v_offset, - s_cp_req[0].v_addr, s_cp_req[0].v_bytes); - if (r <0) - { - printf("sys_safecopyto failed: %d\n", r); - bf_afree(acc_ptr); - return r; - } - i= 0; - continue; - } - if (i == SCPVEC_NR || acc == NULL) - { - r= sys_vsafecopy(s_cp_req, i); - - if (r <0) - { - printf("cp_b2u: sys_vsafecopy failed: %d\n", - r); - bf_afree(acc_ptr); - return r; - } - i= 0; - } - } - bf_afree(acc_ptr); - return OK; -} - -/* - * $PchId: sr.c,v 1.17 2005/06/28 14:26:16 philip Exp $ - */ diff --git a/minix/net/inet/sr_int.h b/minix/net/inet/sr_int.h deleted file mode 100644 index 4699c9da4..000000000 --- a/minix/net/inet/sr_int.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -inet/sr_int.h - -SR internals - -Created: Aug 2004 by Philip Homburg -*/ - -#define FD_NR (16*IP_PORT_MAX) - -typedef struct sr_fd -{ - int srf_flags; - int srf_fd; - int srf_port; - endpoint_t srf_select_proc; - sr_open_t srf_open; - sr_close_t srf_close; - sr_write_t srf_write; - sr_read_t srf_read; - sr_ioctl_t srf_ioctl; - sr_cancel_t srf_cancel; - sr_select_t srf_select; - mq_t *srf_ioctl_q, *srf_ioctl_q_tail; - mq_t *srf_read_q, *srf_read_q_tail; - mq_t *srf_write_q, *srf_write_q_tail; - event_t srf_ioctl_ev; - event_t srf_read_ev; - event_t srf_write_ev; -} sr_fd_t; - -# define SFF_FREE 0x00 -# define SFF_MINOR 0x01 -# define SFF_INUSE 0x02 -#define SFF_BUSY 0x1C -# define SFF_IOCTL_IP 0x04 -# define SFF_READ_IP 0x08 -# define SFF_WRITE_IP 0x10 -#define SFF_SUSPENDED 0x1C0 -# define SFF_IOCTL_SUSP 0x40 -# define SFF_READ_SUSP 0x80 -# define SFF_WRITE_SUSP 0x100 -#define SFF_IOCTL_FIRST 0x200 -#define SFF_READ_FIRST 0x400 -#define SFF_WRITE_FIRST 0x800 - -EXTERN sr_fd_t sr_fd_table[FD_NR]; - -/* - * $PchId: sr_int.h,v 1.2 2005/06/28 14:28:17 philip Exp $ - */ diff --git a/minix/net/inet/version.c b/minix/net/inet/version.c deleted file mode 100644 index 9b7ba36e6..000000000 --- a/minix/net/inet/version.c +++ /dev/null @@ -1,11 +0,0 @@ -/* -version.c -*/ - -#include "inet.h" - -char version[]= "inet 0.79, last compiled on " __DATE__ " " __TIME__; - -/* - * $PchId: version.c,v 1.54 2005/06/28 14:35:01 philip Exp $ - */ diff --git a/minix/servers/vfs/cdev.c b/minix/servers/vfs/cdev.c index 8f58a5bd8..08f1aa934 100644 --- a/minix/servers/vfs/cdev.c +++ b/minix/servers/vfs/cdev.c @@ -463,11 +463,11 @@ cdev_generic_reply(message * m_ptr) proc_e, m_ptr->m_source); } else { /* - * Some services (e.g., inet) use the same infrastructure for - * nonblocking and cancelled requests, resulting in one of - * EINTR or EAGAIN when the other is really the appropriate - * code. Thus, cdev_cancel converts EAGAIN into EINTR, and we - * convert EINTR into EAGAIN here. + * Some services use the same infrastructure for nonblocking + * and cancelled requests, resulting in one of EINTR or EAGAIN + * when the other is really the appropriate code. Thus, + * cdev_cancel converts EAGAIN into EINTR, and we convert EINTR + * into EAGAIN here. TODO: this may be obsolete by now..? */ r = m_ptr->m_lchardriver_vfs_reply.status; revive(proc_e, (r == EINTR) ? EAGAIN : r); diff --git a/releasetools/release.functions b/releasetools/release.functions index 2e9866cd7..4fa6d39dd 100644 --- a/releasetools/release.functions +++ b/releasetools/release.functions @@ -63,8 +63,8 @@ cat >$CDFILES/boot.cfg <${ROOT_DIR}/boot.cfg <