aboutsummaryrefslogtreecommitdiffstats
path: root/slirp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:21 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-09 17:51:21 -0800
commitc2db2b6accc7888df514261a7240e7759df95a4c (patch)
tree0d7ecd37a534c15348cbad01d0d1f84183b7b4d8 /slirp
parentdf7881f07f53b041dc0568be8528e9dbb74994cc (diff)
downloadexternal_qemu-c2db2b6accc7888df514261a7240e7759df95a4c.zip
external_qemu-c2db2b6accc7888df514261a7240e7759df95a4c.tar.gz
external_qemu-c2db2b6accc7888df514261a7240e7759df95a4c.tar.bz2
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'slirp')
-rw-r--r--slirp/COPYRIGHT64
-rw-r--r--slirp/bootp.c259
-rw-r--r--slirp/bootp.h113
-rw-r--r--slirp/cksum.c141
-rw-r--r--slirp/ctl.h10
-rw-r--r--slirp/debug.c352
-rw-r--r--slirp/debug.h50
-rw-r--r--slirp/icmp_var.h69
-rw-r--r--slirp/if.c322
-rw-r--r--slirp/if.h50
-rw-r--r--slirp/ip.h313
-rw-r--r--slirp/ip_icmp.c372
-rw-r--r--slirp/ip_icmp.h164
-rw-r--r--slirp/ip_input.c697
-rw-r--r--slirp/ip_output.c205
-rw-r--r--slirp/libslirp.h45
-rw-r--r--slirp/main.h57
-rw-r--r--slirp/mbuf.c287
-rw-r--r--slirp/mbuf.h121
-rw-r--r--slirp/misc.c288
-rw-r--r--slirp/misc.h64
-rw-r--r--slirp/sbuf.c176
-rw-r--r--slirp/sbuf.h37
-rw-r--r--slirp/slirp.c749
-rw-r--r--slirp/slirp.h339
-rw-r--r--slirp/slirp_config.h206
-rw-r--r--slirp/socket.c752
-rw-r--r--slirp/socket.h107
-rw-r--r--slirp/tcp.h173
-rw-r--r--slirp/tcp_input.c1707
-rw-r--r--slirp/tcp_output.c605
-rw-r--r--slirp/tcp_subr.c1011
-rw-r--r--slirp/tcp_timer.c326
-rw-r--r--slirp/tcp_timer.h142
-rw-r--r--slirp/tcp_var.h253
-rw-r--r--slirp/tcpip.h74
-rw-r--r--slirp/tftp.c422
-rw-r--r--slirp/tftp.h33
-rw-r--r--slirp/udp.c699
-rw-r--r--slirp/udp.h111
40 files changed, 0 insertions, 11965 deletions
diff --git a/slirp/COPYRIGHT b/slirp/COPYRIGHT
deleted file mode 100644
index 2e86862..0000000
--- a/slirp/COPYRIGHT
+++ /dev/null
@@ -1,64 +0,0 @@
-Slirp was written by Danny Gasparovski.
-Copyright (c), 1995,1996 All Rights Reserved.
-
-Slirp is maintained by Kelly Price <tygris+slirp@erols.com>
-
-Slirp is free software; "free" as in you don't have to pay for it, and you
-are free to do whatever you want with it. I do not accept any donations,
-monetary or otherwise, for Slirp. Instead, I would ask you to pass this
-potential donation to your favorite charity. In fact, I encourage
-*everyone* who finds Slirp useful to make a small donation to their
-favorite charity (for example, GreenPeace). This is not a requirement, but
-a suggestion from someone who highly values the service they provide.
-
-The copyright terms and conditions:
-
----BEGIN---
-
- Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this software
- must display the following acknowledgment:
- This product includes software developed by Danny Gasparovski.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- DANNY GASPAROVSKI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
----END---
-
-This basically means you can do anything you want with the software, except
-1) call it your own, and 2) claim warranty on it. There is no warranty for
-this software. None. Nada. If you lose a million dollars while using
-Slirp, that's your loss not mine. So, ***USE AT YOUR OWN RISK!***.
-
-If these conditions cannot be met due to legal restrictions (E.g. where it
-is against the law to give out Software without warranty), you must cease
-using the software and delete all copies you have.
-
-Slirp uses code that is copyrighted by the following people/organizations:
-
-Juha Pirkola.
-Gregory M. Christy.
-The Regents of the University of California.
-Carnegie Mellon University.
-The Australian National University.
-RSA Data Security, Inc.
-
-Please read the top of each source file for the details on the various
-copyrights.
diff --git a/slirp/bootp.c b/slirp/bootp.c
deleted file mode 100644
index 79f5f9f..0000000
--- a/slirp/bootp.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * QEMU BOOTP/DHCP server
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <slirp.h>
-
-/* XXX: only DHCP is supported */
-
-#define NB_ADDR 16
-
-#define START_ADDR 15
-
-#define LEASE_TIME (24 * 3600)
-
-typedef struct {
- uint8_t allocated;
- uint8_t macaddr[6];
-} BOOTPClient;
-
-BOOTPClient bootp_clients[NB_ADDR];
-
-const char *bootp_filename;
-
-static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
-
-#ifdef DEBUG
-#define dprintf(fmt, args...) \
-if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ## args); fflush(dfd); }
-#else
-#define dprintf(fmt, args...)
-#endif
-
-static BOOTPClient *get_new_addr(struct in_addr *paddr)
-{
- BOOTPClient *bc;
- int i;
-
- for(i = 0; i < NB_ADDR; i++) {
- if (!bootp_clients[i].allocated)
- goto found;
- }
- return NULL;
- found:
- bc = &bootp_clients[i];
- bc->allocated = 1;
- paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR));
- return bc;
-}
-
-static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr)
-{
- BOOTPClient *bc;
- int i;
-
- for(i = 0; i < NB_ADDR; i++) {
- if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
- goto found;
- }
- return NULL;
- found:
- bc = &bootp_clients[i];
- bc->allocated = 1;
- paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR));
- return bc;
-}
-
-static void dhcp_decode(const uint8_t *buf, int size,
- int *pmsg_type)
-{
- const uint8_t *p, *p_end;
- int len, tag;
-
- *pmsg_type = 0;
-
- p = buf;
- p_end = buf + size;
- if (size < 5)
- return;
- if (memcmp(p, rfc1533_cookie, 4) != 0)
- return;
- p += 4;
- while (p < p_end) {
- tag = p[0];
- if (tag == RFC1533_PAD) {
- p++;
- } else if (tag == RFC1533_END) {
- break;
- } else {
- p++;
- if (p >= p_end)
- break;
- len = *p++;
- dprintf("dhcp: tag=0x%02x len=%d\n", tag, len);
-
- switch(tag) {
- case RFC2132_MSG_TYPE:
- if (len >= 1)
- *pmsg_type = p[0];
- break;
- default:
- break;
- }
- p += len;
- }
- }
-}
-
-static void bootp_reply(struct bootp_t *bp)
-{
- BOOTPClient *bc;
- MBuf m;
- struct bootp_t *rbp;
- struct sockaddr_in saddr, daddr;
- struct in_addr dns_addr;
- int dhcp_msg_type, val;
- uint8_t *q;
-
- /* extract exact DHCP msg type */
- dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
- dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
-
- if (dhcp_msg_type == 0)
- dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
-
- if (dhcp_msg_type != DHCPDISCOVER &&
- dhcp_msg_type != DHCPREQUEST)
- return;
- /* XXX: this is a hack to get the client mac address */
- memcpy(client_ethaddr, bp->bp_hwaddr, 6);
-
- if ((m = mbuf_alloc()) == NULL)
- return;
- m->m_data += if_maxlinkhdr;
- rbp = (struct bootp_t *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
- memset(rbp, 0, sizeof(struct bootp_t));
-
- if (dhcp_msg_type == DHCPDISCOVER) {
- new_addr:
- bc = get_new_addr(&daddr.sin_addr);
- if (!bc) {
- dprintf("no address left\n");
- return;
- }
- memcpy(bc->macaddr, client_ethaddr, 6);
- } else {
- bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
- if (!bc) {
- /* if never assigned, behaves as if it was already
- assigned (windows fix because it remembers its address) */
- goto new_addr;
- }
- }
- if (bootp_filename)
- snprintf((char*)rbp->bp_file, sizeof(rbp->bp_file), "%s", bootp_filename);
-
- dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr));
-
- saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
- saddr.sin_port = htons(BOOTP_SERVER);
-
- daddr.sin_port = htons(BOOTP_CLIENT);
-
- rbp->bp_op = BOOTP_REPLY;
- rbp->bp_xid = bp->bp_xid;
- rbp->bp_htype = 1;
- rbp->bp_hlen = 6;
- memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);
-
- rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
- rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
-
- q = rbp->bp_vend;
- memcpy(q, rfc1533_cookie, 4);
- q += 4;
-
- if (dhcp_msg_type == DHCPDISCOVER) {
- *q++ = RFC2132_MSG_TYPE;
- *q++ = 1;
- *q++ = DHCPOFFER;
- } else if (dhcp_msg_type == DHCPREQUEST) {
- *q++ = RFC2132_MSG_TYPE;
- *q++ = 1;
- *q++ = DHCPACK;
- }
-
- if (dhcp_msg_type == DHCPDISCOVER ||
- dhcp_msg_type == DHCPREQUEST) {
- *q++ = RFC2132_SRV_ID;
- *q++ = 4;
- memcpy(q, &saddr.sin_addr, 4);
- q += 4;
-
- *q++ = RFC1533_NETMASK;
- *q++ = 4;
- *q++ = 0xff;
- *q++ = 0xff;
- *q++ = 0xff;
- *q++ = 0x00;
-
- *q++ = RFC1533_GATEWAY;
- *q++ = 4;
- memcpy(q, &saddr.sin_addr, 4);
- q += 4;
-
- *q++ = RFC1533_DNS;
- *q++ = 4;
- dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
- memcpy(q, &dns_addr, 4);
- q += 4;
-
- *q++ = RFC2132_LEASE_TIME;
- *q++ = 4;
- val = htonl(LEASE_TIME);
- memcpy(q, &val, 4);
- q += 4;
-
- if (*slirp_hostname) {
- val = strlen(slirp_hostname);
- *q++ = RFC1533_HOSTNAME;
- *q++ = val;
- memcpy(q, slirp_hostname, val);
- q += val;
- }
- }
- *q++ = RFC1533_END;
-
- m->m_len = sizeof(struct bootp_t) -
- sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-}
-
-void bootp_input(MBuf m)
-{
- struct bootp_t *bp = MBUF_TO(m, struct bootp_t *);
-
- if (bp->bp_op == BOOTP_REQUEST) {
- bootp_reply(bp);
- }
-}
diff --git a/slirp/bootp.h b/slirp/bootp.h
deleted file mode 100644
index 1fb42fa..0000000
--- a/slirp/bootp.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* bootp/dhcp defines */
-
-#define BOOTP_SERVER 67
-#define BOOTP_CLIENT 68
-
-#define BOOTP_REQUEST 1
-#define BOOTP_REPLY 2
-
-#define RFC1533_COOKIE 99, 130, 83, 99
-#define RFC1533_PAD 0
-#define RFC1533_NETMASK 1
-#define RFC1533_TIMEOFFSET 2
-#define RFC1533_GATEWAY 3
-#define RFC1533_TIMESERVER 4
-#define RFC1533_IEN116NS 5
-#define RFC1533_DNS 6
-#define RFC1533_LOGSERVER 7
-#define RFC1533_COOKIESERVER 8
-#define RFC1533_LPRSERVER 9
-#define RFC1533_IMPRESSSERVER 10
-#define RFC1533_RESOURCESERVER 11
-#define RFC1533_HOSTNAME 12
-#define RFC1533_BOOTFILESIZE 13
-#define RFC1533_MERITDUMPFILE 14
-#define RFC1533_DOMAINNAME 15
-#define RFC1533_SWAPSERVER 16
-#define RFC1533_ROOTPATH 17
-#define RFC1533_EXTENSIONPATH 18
-#define RFC1533_IPFORWARDING 19
-#define RFC1533_IPSOURCEROUTING 20
-#define RFC1533_IPPOLICYFILTER 21
-#define RFC1533_IPMAXREASSEMBLY 22
-#define RFC1533_IPTTL 23
-#define RFC1533_IPMTU 24
-#define RFC1533_IPMTUPLATEAU 25
-#define RFC1533_INTMTU 26
-#define RFC1533_INTLOCALSUBNETS 27
-#define RFC1533_INTBROADCAST 28
-#define RFC1533_INTICMPDISCOVER 29
-#define RFC1533_INTICMPRESPOND 30
-#define RFC1533_INTROUTEDISCOVER 31
-#define RFC1533_INTROUTESOLICIT 32
-#define RFC1533_INTSTATICROUTES 33
-#define RFC1533_LLTRAILERENCAP 34
-#define RFC1533_LLARPCACHETMO 35
-#define RFC1533_LLETHERNETENCAP 36
-#define RFC1533_TCPTTL 37
-#define RFC1533_TCPKEEPALIVETMO 38
-#define RFC1533_TCPKEEPALIVEGB 39
-#define RFC1533_NISDOMAIN 40
-#define RFC1533_NISSERVER 41
-#define RFC1533_NTPSERVER 42
-#define RFC1533_VENDOR 43
-#define RFC1533_NBNS 44
-#define RFC1533_NBDD 45
-#define RFC1533_NBNT 46
-#define RFC1533_NBSCOPE 47
-#define RFC1533_XFS 48
-#define RFC1533_XDM 49
-
-#define RFC2132_REQ_ADDR 50
-#define RFC2132_LEASE_TIME 51
-#define RFC2132_MSG_TYPE 53
-#define RFC2132_SRV_ID 54
-#define RFC2132_PARAM_LIST 55
-#define RFC2132_MAX_SIZE 57
-#define RFC2132_RENEWAL_TIME 58
-#define RFC2132_REBIND_TIME 59
-
-#define DHCPDISCOVER 1
-#define DHCPOFFER 2
-#define DHCPREQUEST 3
-#define DHCPACK 5
-
-#define RFC1533_VENDOR_MAJOR 0
-#define RFC1533_VENDOR_MINOR 0
-
-#define RFC1533_VENDOR_MAGIC 128
-#define RFC1533_VENDOR_ADDPARM 129
-#define RFC1533_VENDOR_ETHDEV 130
-#define RFC1533_VENDOR_HOWTO 132
-#define RFC1533_VENDOR_MNUOPTS 160
-#define RFC1533_VENDOR_SELECTION 176
-#define RFC1533_VENDOR_MOTD 184
-#define RFC1533_VENDOR_NUMOFMOTD 8
-#define RFC1533_VENDOR_IMG 192
-#define RFC1533_VENDOR_NUMOFIMG 16
-
-#define RFC1533_END 255
-#define BOOTP_VENDOR_LEN 64
-#define DHCP_OPT_LEN 312
-
-struct bootp_t {
- struct ip ip;
- struct udphdr udp;
- uint8_t bp_op;
- uint8_t bp_htype;
- uint8_t bp_hlen;
- uint8_t bp_hops;
- uint32_t bp_xid;
- uint16_t bp_secs;
- uint16_t unused;
- struct in_addr bp_ciaddr;
- struct in_addr bp_yiaddr;
- struct in_addr bp_siaddr;
- struct in_addr bp_giaddr;
- uint8_t bp_hwaddr[16];
- uint8_t bp_sname[64];
- uint8_t bp_file[128];
- uint8_t bp_vend[DHCP_OPT_LEN];
-};
-
-void bootp_input(MBuf m);
diff --git a/slirp/cksum.c b/slirp/cksum.c
deleted file mode 100644
index 9474b9e..0000000
--- a/slirp/cksum.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 1988, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
- * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
- */
-
-#include <slirp.h>
-
-/*
- * Checksum routine for Internet Protocol family headers (Portable Version).
- *
- * This routine is very heavily used in the network
- * code and should be modified for each CPU to be as fast as possible.
- *
- * XXX Since we will never span more than 1 mbuf, we can optimise this
- */
-
-#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
-#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
-
-int cksum(MBuf m, int len)
-{
- register u_int16_t *w;
- register int sum = 0;
- register int mlen = 0;
- int byte_swapped = 0;
-
- union {
- u_int8_t c[2];
- u_int16_t s;
- } s_util;
- union {
- u_int16_t s[2];
- u_int32_t l;
- } l_util;
-
- if (m->m_len == 0)
- goto cont;
- w = MBUF_TO(m, u_int16_t *);
-
- mlen = m->m_len;
-
- if (len < mlen)
- mlen = len;
- len -= mlen;
- /*
- * Force to even boundary.
- */
- if ((1 & (long) w) && (mlen > 0)) {
- REDUCE;
- sum <<= 8;
- s_util.c[0] = *(u_int8_t *)w;
- w = (u_int16_t *)((int8_t *)w + 1);
- mlen--;
- byte_swapped = 1;
- }
- /*
- * Unroll the loop to make overhead from
- * branches &c small.
- */
- while ((mlen -= 32) >= 0) {
- sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
- sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
- sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
- sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
- w += 16;
- }
- mlen += 32;
- while ((mlen -= 8) >= 0) {
- sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
- w += 4;
- }
- mlen += 8;
- if (mlen == 0 && byte_swapped == 0)
- goto cont;
- REDUCE;
- while ((mlen -= 2) >= 0) {
- sum += *w++;
- }
-
- if (byte_swapped) {
- REDUCE;
- sum <<= 8;
- byte_swapped = 0;
- if (mlen == -1) {
- s_util.c[1] = *(u_int8_t *)w;
- sum += s_util.s;
- mlen = 0;
- } else
-
- mlen = -1;
- } else if (mlen == -1)
- s_util.c[0] = *(u_int8_t *)w;
-
-cont:
-#ifdef DEBUG
- if (len) {
- DEBUG_ERROR((dfd, "cksum: out of data\n"));
- DEBUG_ERROR((dfd, " len = %d\n", len));
- }
-#endif
- if (mlen == -1) {
- /* The last mbuf has odd # of bytes. Follow the
- standard (the odd byte may be shifted left by 8 bits
- or not as determined by endian-ness of the machine) */
- s_util.c[1] = 0;
- sum += s_util.s;
- }
- REDUCE;
- return (~sum & 0xffff);
-}
diff --git a/slirp/ctl.h b/slirp/ctl.h
deleted file mode 100644
index 854ae9a..0000000
--- a/slirp/ctl.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#define CTL_CMD 0
-#define CTL_EXEC 1
-#define CTL_ALIAS 2
-#define CTL_DNS 3
-/* NOTE: DNS_ADDR_MAX addresses, starting from CTL_DNS, are reserved */
-
-#define CTL_IS_DNS(x) ((unsigned)((x)-CTL_DNS) < (unsigned)dns_addr_count)
-
-#define CTL_SPECIAL "10.0.2.0"
-#define CTL_LOCAL "10.0.2.15"
diff --git a/slirp/debug.c b/slirp/debug.c
deleted file mode 100644
index a46626b..0000000
--- a/slirp/debug.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- * Portions copyright (c) 2000 Kelly Price.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-FILE *dfd = NULL;
-#ifdef DEBUG
-int dostats = 1;
-#else
-int dostats = 0;
-#endif
-int slirp_debug = 0;
-
-extern char *strerror _P((int));
-
-/* Carry over one item from main.c so that the tty's restored.
- * Only done when the tty being used is /dev/tty --RedWolf */
-extern struct termios slirp_tty_settings;
-extern int slirp_tty_restore;
-
-
-void
-debug_init(file, dbg)
- char *file;
- int dbg;
-{
- /* Close the old debugging file */
- if (dfd)
- fclose(dfd);
-
- dfd = fopen(file,"w");
- if (dfd != NULL) {
-#if 0
- fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION);
-#endif
- fprintf(dfd,"Debugging Started level %i.\r\n",dbg);
- fflush(dfd);
- slirp_debug = dbg;
- } else {
- fprintf(stderr, "Error: Debugging file \"%s\" could not be opened: %s\r\n",
- file, strerror(errno));
- }
-}
-
-/*
- * Dump a packet in the same format as tcpdump -x
- */
-#ifdef DEBUG
-void
-dump_packet(dat, n)
- void *dat;
- int n;
-{
- u_char *pptr = (u_char *)dat;
- int j,k;
-
- n /= 16;
- n++;
- DEBUG_MISC((dfd, "PACKET DUMPED: \n"));
- for(j = 0; j < n; j++) {
- for(k = 0; k < 6; k++)
- DEBUG_MISC((dfd, "%02x ", *pptr++));
- DEBUG_MISC((dfd, "\n"));
- fflush(dfd);
- }
-}
-#endif
-
-#if 0
-/*
- * Statistic routines
- *
- * These will print statistics to the screen, the debug file (dfd), or
- * a buffer, depending on "type", so that the stats can be sent over
- * the link as well.
- */
-
-void
-ttystats(ttyp)
- struct ttys *ttyp;
-{
- struct slirp_ifstats *is = &ttyp->ifstats;
- char buff[512];
-
- lprint(" \r\n");
-
- if (if_comp & IF_COMPRESS)
- strcpy(buff, "on");
- else if (if_comp & IF_NOCOMPRESS)
- strcpy(buff, "off");
- else
- strcpy(buff, "off (for now)");
- lprint("Unit %d:\r\n", ttyp->unit);
- lprint(" using %s encapsulation (VJ compression is %s)\r\n", (
-#ifdef USE_PPP
- ttyp->proto==PROTO_PPP?"PPP":
-#endif
- "SLIP"), buff);
- lprint(" %d baudrate\r\n", ttyp->baud);
- lprint(" interface is %s\r\n", ttyp->up?"up":"down");
- lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid);
-#ifndef FULL_BOLT
- lprint(" towrite is %d bytes\r\n", ttyp->towrite);
-#endif
- if (ttyp->zeros)
- lprint(" %d zeros have been typed\r\n", ttyp->zeros);
- else if (ttyp->ones)
- lprint(" %d ones have been typed\r\n", ttyp->ones);
- lprint("Interface stats:\r\n");
- lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes);
- lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes);
- lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes);
- lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes);
- lprint(" %6d bad input packets\r\n", is->in_mbad);
-}
-
-void
-allttystats()
-{
- struct ttys *ttyp;
-
- for (ttyp = ttys; ttyp; ttyp = ttyp->next)
- ttystats(ttyp);
-}
-#endif
-
-void
-ipstats()
-{
- lprint(" \r\n");
-
- lprint("IP stats:\r\n");
- lprint(" %6d total packets received (%d were unaligned)\r\n",
- ipstat.ips_total, ipstat.ips_unaligned);
- lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers);
- lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum);
- lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort);
- lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall);
- lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen);
- lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen);
- lprint(" %6d fragments received\r\n", ipstat.ips_fragments);
- lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped);
- lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout);
- lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled);
- lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented);
- lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments);
- lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto);
- lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered);
-}
-
-#if 0
-void
-vjstats()
-{
- lprint(" \r\n");
-
- lprint("VJ compression stats:\r\n");
-
- lprint(" %6d outbound packets (%d compressed)\r\n",
- comp_s.sls_packets, comp_s.sls_compressed);
- lprint(" %6d searches for connection stats (%d misses)\r\n",
- comp_s.sls_searches, comp_s.sls_misses);
- lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin);
- lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin);
- lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin);
- lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed);
-}
-#endif
-
-void
-tcpstats()
-{
- lprint(" \r\n");
-
- lprint("TCP stats:\r\n");
-
- lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal);
- lprint(" %6d data packets (%d bytes)\r\n",
- tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte);
- lprint(" %6d data packets retransmitted (%d bytes)\r\n",
- tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte);
- lprint(" %6d ack-only packets (%d delayed)\r\n",
- tcpstat.tcps_sndacks, tcpstat.tcps_delack);
- lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg);
- lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe);
- lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup);
- lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl);
- lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin);
-
- lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal);
- lprint(" %6d acks (for %d bytes)\r\n",
- tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte);
- lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack);
- lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch);
- lprint(" %6d packets received in sequence (%d bytes)\r\n",
- tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte);
- lprint(" %6d completely duplicate packets (%d bytes)\r\n",
- tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte);
-
- lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n",
- tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte);
- lprint(" %6d out-of-order packets (%d bytes)\r\n",
- tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte);
- lprint(" %6d packets of data after window (%d bytes)\r\n",
- tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin);
- lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe);
- lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd);
- lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose);
- lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum);
- lprint(" %6d discarded for bad header offset fields\r\n",
- tcpstat.tcps_rcvbadoff);
-
- lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt);
- lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts);
- lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects);
- lprint(" %6d connections closed (including %d drop)\r\n",
- tcpstat.tcps_closed, tcpstat.tcps_drops);
- lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops);
- lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n",
- tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated);
- lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo);
- lprint(" %6d connections dropped by rxmt timeout\r\n",
- tcpstat.tcps_timeoutdrop);
- lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo);
- lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo);
- lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe);
- lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops);
- lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack);
- lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat);
- lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss);
-
-
-/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */
-/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */
-
-}
-
-void
-udpstats()
-{
- lprint(" \r\n");
-
- lprint("UDP stats:\r\n");
- lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets);
- lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops);
- lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum);
- lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen);
- lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss);
- lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets);
-}
-
-void
-icmpstats()
-{
- lprint(" \r\n");
- lprint("ICMP stats:\r\n");
- lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received);
- lprint(" %6d were too short\r\n", icmpstat.icps_tooshort);
- lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum);
- lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp);
- lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype);
- lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
-}
-
-void
-sockstats()
-{
- char buff[256];
- int n;
- struct socket *so;
-
- lprint(" \r\n");
-
- lprint(
- "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n");
-
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
-
- n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");
- while (n < 17)
- buff[n++] = ' ';
- buff[17] = 0;
- lprint("%s %3d %15s %5d ",
- buff, so->s,
- inet_ntoa(so->so_laddr), ntohs(so->so_lport));
- lprint("%15s %5d %5d %5d\r\n",
- inet_ntoa(so->so_faddr), ntohs(so->so_fport),
- so->so_rcv.sb_cc, so->so_snd.sb_cc);
- }
-
- for (so = udb.so_next; so != &udb; so = so->so_next) {
-
- n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);
- while (n < 17)
- buff[n++] = ' ';
- buff[17] = 0;
- lprint("%s %3d %15s %5d ",
- buff, so->s,
- inet_ntoa(so->so_laddr), ntohs(so->so_lport));
- lprint("%15s %5d %5d %5d\r\n",
- inet_ntoa(so->so_faddr), ntohs(so->so_fport),
- so->so_rcv.sb_cc, so->so_snd.sb_cc);
- }
-}
-
-#if 0
-void
-slirp_exit(exit_status)
- int exit_status;
-{
- struct ttys *ttyp;
-
- DEBUG_CALL("slirp_exit");
- DEBUG_ARG("exit_status = %d", exit_status);
-
- if (dostats) {
- lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf;
- if (!dfd)
- debug_init("slirp_stats", 0xf);
- lprint_arg = (char **)&dfd;
-
- ipstats();
- tcpstats();
- udpstats();
- icmpstats();
- mbufstats();
- sockstats();
- allttystats();
- vjstats();
- }
-
- for (ttyp = ttys; ttyp; ttyp = ttyp->next)
- tty_detached(ttyp, 1);
-
- if (slirp_forked) {
- /* Menendez time */
- if (kill(getppid(), SIGQUIT) < 0)
- lprint("Couldn't kill parent process %ld!\n",
- (long) getppid());
- }
-
- /* Restore the terminal if we gotta */
- if(slirp_tty_restore)
- tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */
- exit(exit_status);
-}
-#endif
diff --git a/slirp/debug.h b/slirp/debug.h
deleted file mode 100644
index 6e8444d..0000000
--- a/slirp/debug.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define PRN_STDERR 1
-#define PRN_SPRINTF 2
-
-extern FILE *dfd;
-extern FILE *lfd;
-extern int dostats;
-extern int slirp_debug;
-
-#define DBG_CALL 0x1
-#define DBG_MISC 0x2
-#define DBG_ERROR 0x4
-#define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR
-
-#ifdef DEBUG
-#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); }
-#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); }
-#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); }
-#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); }
-#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); }
-
-
-#else
-
-#define DEBUG_CALL(x)
-#define DEBUG_ARG(x, y)
-#define DEBUG_ARGS(x)
-#define DEBUG_MISC(x)
-#define DEBUG_ERROR(x)
-
-#endif
-
-void debug_init _P((char *, int));
-//void ttystats _P((struct ttys *));
-void allttystats _P((void));
-void ipstats _P((void));
-void vjstats _P((void));
-void tcpstats _P((void));
-void udpstats _P((void));
-void icmpstats _P((void));
-void mbufstats _P((void));
-void sockstats _P((void));
-void slirp_exit _P((int));
-
diff --git a/slirp/icmp_var.h b/slirp/icmp_var.h
deleted file mode 100644
index 03fc8c3..0000000
--- a/slirp/icmp_var.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93
- * icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp
- */
-
-#ifndef _NETINET_ICMP_VAR_H_
-#define _NETINET_ICMP_VAR_H_
-
-/*
- * Variables related to this implementation
- * of the internet control message protocol.
- */
-struct icmpstat {
-/* statistics related to input messages processed */
- u_long icps_received; /* #ICMP packets received */
- u_long icps_tooshort; /* packet < ICMP_MINLEN */
- u_long icps_checksum; /* bad checksum */
- u_long icps_notsupp; /* #ICMP packets not supported */
- u_long icps_badtype; /* #with bad type feild */
- u_long icps_reflect; /* number of responses */
-};
-
-/*
- * Names for ICMP sysctl objects
- */
-#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */
-#define ICMPCTL_STATS 2 /* statistics (read-only) */
-#define ICMPCTL_MAXID 3
-
-#define ICMPCTL_NAMES { \
- { 0, 0 }, \
- { "maskrepl", CTLTYPE_INT }, \
- { "stats", CTLTYPE_STRUCT }, \
-}
-
-extern struct icmpstat icmpstat;
-
-#endif
diff --git a/slirp/if.c b/slirp/if.c
deleted file mode 100644
index 9d814c2..0000000
--- a/slirp/if.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-int if_mtu, if_mru;
-int if_comp;
-int if_maxlinkhdr;
-int if_queued = 0; /* Number of packets queued so far */
-int if_thresh = 10; /* Number of packets queued before we start sending
- * (to prevent allocing too many mbufs) */
-
-struct mbuf if_fastq; /* fast queue (for interactive data) */
-struct mbuf if_batchq; /* queue for non-interactive data */
-struct mbuf *next_m; /* Pointer to next mbuf to output */
-
-#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
-
-void
-ifs_insque(ifm, ifmhead)
- MBuf ifm, ifmhead;
-{
- ifm->ifs_next = ifmhead->ifs_next;
- ifmhead->ifs_next = ifm;
- ifm->ifs_prev = ifmhead;
- ifm->ifs_next->ifs_prev = ifm;
-}
-
-void
-ifs_remque(ifm)
- MBuf ifm;
-{
- ifm->ifs_prev->ifs_next = ifm->ifs_next;
- ifm->ifs_next->ifs_prev = ifm->ifs_prev;
-}
-
-void
-if_init()
-{
-#if 0
- /*
- * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP,
- * and 8 bytes for PPP, but need to have it on an 8byte boundary
- */
-#ifdef USE_PPP
- if_maxlinkhdr = 48;
-#else
- if_maxlinkhdr = 40;
-#endif
-#else
- /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
- if_maxlinkhdr = 2 + 14 + 40;
-#endif
- if_mtu = 1500;
- if_mru = 1500;
- if_comp = IF_AUTOCOMP;
- if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
- if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
- // sl_compress_init(&comp_s);
- next_m = &if_batchq;
-}
-
-#if 0
-/*
- * This shouldn't be needed since the modem is blocking and
- * we don't expect any signals, but what the hell..
- */
-inline int
-writen(fd, bptr, n)
- int fd;
- char *bptr;
- int n;
-{
- int ret;
- int total;
-
- /* This should succeed most of the time */
- ret = send(fd, bptr, n,0);
- if (ret == n || ret <= 0)
- return ret;
-
- /* Didn't write everything, go into the loop */
- total = ret;
- while (n > total) {
- ret = send(fd, bptr+total, n-total,0);
- if (ret <= 0)
- return ret;
- total += ret;
- }
- return total;
-}
-
-/*
- * if_input - read() the tty, do "top level" processing (ie: check for any escapes),
- * and pass onto (*ttyp->if_input)
- *
- * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet.
- */
-#define INBUFF_SIZE 2048 /* XXX */
-void
-if_input(ttyp)
- struct ttys *ttyp;
-{
- u_char if_inbuff[INBUFF_SIZE];
- int if_n;
-
- DEBUG_CALL("if_input");
- DEBUG_ARG("ttyp = %lx", (long)ttyp);
-
- if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0);
-
- DEBUG_MISC((dfd, " read %d bytes\n", if_n));
-
- if (if_n <= 0) {
- if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) {
- if (ttyp->up)
- link_up--;
- tty_detached(ttyp, 0);
- }
- return;
- }
- if (if_n == 1) {
- if (*if_inbuff == '0') {
- ttyp->ones = 0;
- if (++ttyp->zeros >= 5)
- slirp_exit(0);
- return;
- }
- if (*if_inbuff == '1') {
- ttyp->zeros = 0;
- if (++ttyp->ones >= 5)
- tty_detached(ttyp, 0);
- return;
- }
- }
- ttyp->ones = ttyp->zeros = 0;
-
- (*ttyp->if_input)(ttyp, if_inbuff, if_n);
-}
-#endif
-
-/*
- * if_output: Queue packet into an output queue.
- * There are 2 output queue's, if_fastq and if_batchq.
- * Each output queue is a doubly linked list of double linked lists
- * of mbufs, each list belonging to one "session" (socket). This
- * way, we can output packets fairly by sending one packet from each
- * session, instead of all the packets from one session, then all packets
- * from the next session, etc. Packets on the if_fastq get absolute
- * priority, but if one session hogs the link, it gets "downgraded"
- * to the batchq until it runs out of packets, then it'll return
- * to the fastq (eg. if the user does an ls -alR in a telnet session,
- * it'll temporarily get downgraded to the batchq)
- */
-void
-if_output(so, ifm)
- struct socket *so;
- MBuf ifm;
-{
- MBuf ifq;
- int on_fastq = 1;
-
- DEBUG_CALL("if_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("ifm = %lx", (long)ifm);
-
- /*
- * First remove the mbuf from m_usedlist,
- * since we're gonna use m_next and m_prev ourselves
- * XXX Shouldn't need this, gotta change dtom() etc.
- */
- if (ifm->m_flags & M_USEDLIST) {
- remque(ifm);
- ifm->m_flags &= ~M_USEDLIST;
- }
-
- /*
- * See if there's already a batchq list for this session.
- * This can include an interactive session, which should go on fastq,
- * but gets too greedy... hence it'll be downgraded from fastq to batchq.
- * We mustn't put this packet back on the fastq (or we'll send it out of order)
- * XXX add cache here?
- */
- for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) {
- if (so == ifq->ifq_so) {
- /* A match! */
- ifm->ifq_so = so;
- ifs_insque(ifm, ifq->ifs_prev);
- goto diddit;
- }
- }
-
- /* No match, check which queue to put it on */
- if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
- ifq = if_fastq.ifq_prev;
- on_fastq = 1;
- /*
- * Check if this packet is a part of the last
- * packet's session
- */
- if (ifq->ifq_so == so) {
- ifm->ifq_so = so;
- ifs_insque(ifm, ifq->ifs_prev);
- goto diddit;
- }
- } else
- ifq = if_batchq.ifq_prev;
-
- /* Create a new doubly linked list for this session */
- ifm->ifq_so = so;
- ifs_init(ifm);
- insque(ifm, ifq);
-
-diddit:
- ++if_queued;
-
- if (so) {
- /* Update *_queued */
- so->so_queued++;
- so->so_nqueued++;
- /*
- * Check if the interactive session should be downgraded to
- * the batchq. A session is downgraded if it has queued 6
- * packets without pausing, and at least 3 of those packets
- * have been sent over the link
- * (XXX These are arbitrary numbers, probably not optimal..)
- */
- if (on_fastq && ((so->so_nqueued >= 6) &&
- (so->so_nqueued - so->so_queued) >= 3)) {
-
- /* Remove from current queue... */
- remque(ifm->ifs_next);
-
- /* ...And insert in the new. That'll teach ya! */
- insque(ifm->ifs_next, &if_batchq);
- }
- }
-
-#ifndef FULL_BOLT
- /*
- * This prevents us from malloc()ing too many mbufs
- */
- if (link_up) {
- /* if_start will check towrite */
- if_start();
- }
-#endif
-}
-
-/*
- * Send a packet
- * We choose a packet based on it's position in the output queues;
- * If there are packets on the fastq, they are sent FIFO, before
- * everything else. Otherwise we choose the first packet from the
- * batchq and send it. the next packet chosen will be from the session
- * after this one, then the session after that one, and so on.. So,
- * for example, if there are 3 ftp session's fighting for bandwidth,
- * one packet will be sent from the first session, then one packet
- * from the second session, then one packet from the third, then back
- * to the first, etc. etc.
- */
-void
-if_start(void)
-{
- MBuf ifm, ifqt;
-
- DEBUG_CALL("if_start");
-
- if (if_queued == 0)
- return; /* Nothing to do */
-
- again:
- /* check if we can really output */
- if (!slirp_can_output())
- return;
-
- /*
- * See which queue to get next packet from
- * If there's something in the fastq, select it immediately
- */
- if (if_fastq.ifq_next != &if_fastq) {
- ifm = if_fastq.ifq_next;
- } else {
- /* Nothing on fastq, see if next_m is valid */
- if (next_m != &if_batchq)
- ifm = next_m;
- else
- ifm = if_batchq.ifq_next;
-
- /* Set which packet to send on next iteration */
- next_m = ifm->ifq_next;
- }
- /* Remove it from the queue */
- ifqt = ifm->ifq_prev;
- remque(ifm);
- --if_queued;
-
- /* If there are more packets for this session, re-queue them */
- if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
- insque(ifm->ifs_next, ifqt);
- ifs_remque(ifm);
- }
-
- /* Update so_queued */
- if (ifm->ifq_so) {
- if (--ifm->ifq_so->so_queued == 0)
- /* If there's no more queued, reset nqueued */
- ifm->ifq_so->so_nqueued = 0;
- }
-
- /* Encapsulate the packet for sending */
- if_encap(ifm->m_data, ifm->m_len);
-
- mbuf_free(ifm);
-
- if (if_queued)
- goto again;
-}
diff --git a/slirp/if.h b/slirp/if.h
deleted file mode 100644
index f22f161..0000000
--- a/slirp/if.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifndef _IF_H_
-#define _IF_H_
-
-#define IF_COMPRESS 0x01 /* We want compression */
-#define IF_NOCOMPRESS 0x02 /* Do not do compression */
-#define IF_AUTOCOMP 0x04 /* Autodetect (default) */
-#define IF_NOCIDCOMP 0x08 /* CID compression */
-
-/* Needed for FreeBSD */
-#undef if_mtu
-extern int if_mtu;
-extern int if_mru; /* MTU and MRU */
-extern int if_comp; /* Flags for compression */
-extern int if_maxlinkhdr;
-extern int if_queued; /* Number of packets queued so far */
-extern int if_thresh; /* Number of packets queued before we start sending
- * (to prevent allocing too many mbufs) */
-
-extern struct mbuf if_fastq; /* fast queue (for interactive data) */
-extern struct mbuf if_batchq; /* queue for non-interactive data */
-extern MBuf next_m;
-
-#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
-
-/* Interface statistics */
-struct slirp_ifstats {
- u_int out_pkts; /* Output packets */
- u_int out_bytes; /* Output bytes */
- u_int out_errpkts; /* Output Error Packets */
- u_int out_errbytes; /* Output Error Bytes */
- u_int in_pkts; /* Input packets */
- u_int in_bytes; /* Input bytes */
- u_int in_errpkts; /* Input Error Packets */
- u_int in_errbytes; /* Input Error Bytes */
-
- u_int bytes_saved; /* Number of bytes that compression "saved" */
- /* ie: number of bytes that didn't need to be sent over the link
- * because of compression */
-
- u_int in_mbad; /* Bad incoming packets */
-};
-
-#endif
diff --git a/slirp/ip.h b/slirp/ip.h
deleted file mode 100644
index 371537d..0000000
--- a/slirp/ip.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip.h 8.1 (Berkeley) 6/10/93
- * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp
- */
-
-#ifndef _IP_H_
-#define _IP_H_
-
-#ifdef WORDS_BIGENDIAN
-# ifndef NTOHL
-# define NTOHL(d)
-# endif
-# ifndef NTOHS
-# define NTOHS(d)
-# endif
-# ifndef HTONL
-# define HTONL(d)
-# endif
-# ifndef HTONS
-# define HTONS(d)
-# endif
-#else
-# ifndef NTOHL
-# define NTOHL(d) ((d) = ntohl((d)))
-# endif
-# ifndef NTOHS
-# define NTOHS(d) ((d) = ntohs((u_int16_t)(d)))
-# endif
-# ifndef HTONL
-# define HTONL(d) ((d) = htonl((d)))
-# endif
-# ifndef HTONS
-# define HTONS(d) ((d) = htons((u_int16_t)(d)))
-# endif
-#endif
-
-typedef u_int32_t n_long; /* long as received from the net */
-
-/*
- * Definitions for internet protocol version 4.
- * Per RFC 791, September 1981.
- */
-#define IPVERSION 4
-
-/*
- * Structure of an internet header, naked of options.
- */
-struct ip {
-#ifdef WORDS_BIGENDIAN
- u_int ip_v:4, /* version */
- ip_hl:4; /* header length */
-#else
- u_int ip_hl:4, /* header length */
- ip_v:4; /* version */
-#endif
- u_int8_t ip_tos; /* type of service */
- u_int16_t ip_len; /* total length */
- u_int16_t ip_id; /* identification */
- u_int16_t ip_off; /* fragment offset field */
-#define IP_DF 0x4000 /* don't fragment flag */
-#define IP_MF 0x2000 /* more fragments flag */
-#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
- u_int8_t ip_ttl; /* time to live */
- u_int8_t ip_p; /* protocol */
- u_int16_t ip_sum; /* checksum */
- struct in_addr ip_src,ip_dst; /* source and dest address */
-};
-
-#define IP_MAXPACKET 65535 /* maximum packet size */
-
-/*
- * Definitions for IP type of service (ip_tos)
- */
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-
-/*
- * Definitions for options.
- */
-#define IPOPT_COPIED(o) ((o)&0x80)
-#define IPOPT_CLASS(o) ((o)&0x60)
-#define IPOPT_NUMBER(o) ((o)&0x1f)
-
-#define IPOPT_CONTROL 0x00
-#define IPOPT_RESERVED1 0x20
-#define IPOPT_DEBMEAS 0x40
-#define IPOPT_RESERVED2 0x60
-
-#define IPOPT_EOL 0 /* end of option list */
-#define IPOPT_NOP 1 /* no operation */
-
-#define IPOPT_RR 7 /* record packet route */
-#define IPOPT_TS 68 /* timestamp */
-#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
-#define IPOPT_LSRR 131 /* loose source route */
-#define IPOPT_SATID 136 /* satnet id */
-#define IPOPT_SSRR 137 /* strict source route */
-
-/*
- * Offsets to fields in options other than EOL and NOP.
- */
-#define IPOPT_OPTVAL 0 /* option ID */
-#define IPOPT_OLEN 1 /* option length */
-#define IPOPT_OFFSET 2 /* offset within option */
-#define IPOPT_MINOFF 4 /* min value of above */
-
-/*
- * Time stamp option structure.
- */
-struct ip_timestamp {
- u_int8_t ipt_code; /* IPOPT_TS */
- u_int8_t ipt_len; /* size of structure (variable) */
- u_int8_t ipt_ptr; /* index of current entry */
-#ifdef WORDS_BIGENDIAN
- u_int ipt_oflw:4, /* overflow counter */
- ipt_flg:4; /* flags, see below */
-#else
- u_int ipt_flg:4, /* flags, see below */
- ipt_oflw:4; /* overflow counter */
-#endif
- union ipt_timestamp {
- n_long ipt_time[1];
- struct ipt_ta {
- struct in_addr ipt_addr;
- n_long ipt_time;
- } ipt_ta[1];
- } ipt_timestamp;
-};
-
-/* flag bits for ipt_flg */
-#define IPOPT_TS_TSONLY 0 /* timestamps only */
-#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
-#define IPOPT_TS_PRESPEC 3 /* specified modules only */
-
-/* bits for security (not byte swapped) */
-#define IPOPT_SECUR_UNCLASS 0x0000
-#define IPOPT_SECUR_CONFID 0xf135
-#define IPOPT_SECUR_EFTO 0x789a
-#define IPOPT_SECUR_MMMM 0xbc4d
-#define IPOPT_SECUR_RESTR 0xaf13
-#define IPOPT_SECUR_SECRET 0xd788
-#define IPOPT_SECUR_TOPSECRET 0x6bc5
-
-/*
- * Internet implementation parameters.
- */
-#define MAXTTL 255 /* maximum time to live (seconds) */
-#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
-#define IPFRAGTTL 60 /* time to live for frags, slowhz */
-#define IPTTLDEC 1 /* subtracted when forwarding */
-
-#define IP_MSS 576 /* default maximum segment size */
-
-#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */
-#include <sys/types32.h>
-#else
-#if SIZEOF_CHAR_P == 4
-typedef caddr_t caddr32_t;
-#else
-typedef u_int32_t caddr32_t;
-#endif
-#endif
-
-#if SIZEOF_CHAR_P == 4
-typedef struct ipq *ipqp_32;
-typedef struct ipasfrag *ipasfragp_32;
-#else
-typedef caddr32_t ipqp_32;
-typedef caddr32_t ipasfragp_32;
-#endif
-
-/*
- * Overlay for ip header used by other protocols (tcp, udp).
- */
-struct ipovly {
- caddr32_t ih_next, ih_prev; /* for protocol sequence q's */
- u_int8_t ih_x1; /* (unused) */
- u_int8_t ih_pr; /* protocol */
- u_int16_t ih_len; /* protocol length */
- struct in_addr ih_src; /* source internet address */
- struct in_addr ih_dst; /* destination internet address */
-};
-
-/*
- * Ip reassembly queue structure. Each fragment
- * being reassembled is attached to one of these structures.
- * They are timed out after ipq_ttl drops to 0, and may also
- * be reclaimed if memory becomes tight.
- * size 28 bytes
- */
-struct ipq {
- ipqp_32 next,prev; /* to other reass headers */
- u_int8_t ipq_ttl; /* time for reass q to live */
- u_int8_t ipq_p; /* protocol of this fragment */
- u_int16_t ipq_id; /* sequence id for reassembly */
- ipasfragp_32 ipq_next,ipq_prev;
- /* to ip headers of fragments */
- struct in_addr ipq_src,ipq_dst;
-};
-
-/*
- * Ip header, when holding a fragment.
- *
- * Note: ipf_next must be at same offset as ipq_next above
- */
-struct ipasfrag {
-#ifdef WORDS_BIGENDIAN
- u_int ip_v:4,
- ip_hl:4;
-#else
- u_int ip_hl:4,
- ip_v:4;
-#endif
- /* BUG : u_int changed to u_int8_t.
- * sizeof(u_int)==4 on linux 2.0
- */
- u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit
- * to avoid destroying tos (PPPDTRuu);
- * copied from (ip_off&IP_MF) */
- u_int16_t ip_len;
- u_int16_t ip_id;
- u_int16_t ip_off;
- u_int8_t ip_ttl;
- u_int8_t ip_p;
- u_int16_t ip_sum;
- ipasfragp_32 ipf_next; /* next fragment */
- ipasfragp_32 ipf_prev; /* previous fragment */
-};
-
-/*
- * Structure stored in mbuf in inpcb.ip_options
- * and passed to ip_output when ip options are in use.
- * The actual length of the options (including ipopt_dst)
- * is in m_len.
- */
-#define MAX_IPOPTLEN 40
-
-struct ipoption {
- struct in_addr ipopt_dst; /* first-hop dst if source routed */
- int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
-};
-
-/*
- * Structure attached to inpcb.ip_moptions and
- * passed to ip_output when IP multicast options are in use.
- */
-
-struct ipstat {
- u_long ips_total; /* total packets received */
- u_long ips_badsum; /* checksum bad */
- u_long ips_tooshort; /* packet too short */
- u_long ips_toosmall; /* not enough data */
- u_long ips_badhlen; /* ip header length < data size */
- u_long ips_badlen; /* ip length < ip header length */
- u_long ips_fragments; /* fragments received */
- u_long ips_fragdropped; /* frags dropped (dups, out of space) */
- u_long ips_fragtimeout; /* fragments timed out */
- u_long ips_forward; /* packets forwarded */
- u_long ips_cantforward; /* packets rcvd for unreachable dest */
- u_long ips_redirectsent; /* packets forwarded on same net */
- u_long ips_noproto; /* unknown or unsupported protocol */
- u_long ips_delivered; /* datagrams delivered to upper level*/
- u_long ips_localout; /* total ip packets generated here */
- u_long ips_odropped; /* lost packets due to nobufs, etc. */
- u_long ips_reassembled; /* total packets reassembled ok */
- u_long ips_fragmented; /* datagrams successfully fragmented */
- u_long ips_ofragments; /* output fragments created */
- u_long ips_cantfrag; /* don't fragment flag was set, etc. */
- u_long ips_badoptions; /* error in option processing */
- u_long ips_noroute; /* packets discarded due to no route */
- u_long ips_badvers; /* ip version != 4 */
- u_long ips_rawout; /* total raw ip packets generated */
- u_long ips_unaligned; /* times the ip packet was not aligned */
-};
-
-extern struct ipstat ipstat;
-extern struct ipq ipq; /* ip reass. queue */
-extern u_int16_t ip_id; /* ip packet ctr, for ids */
-extern int ip_defttl; /* default IP ttl */
-
-#endif
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
deleted file mode 100644
index 2d50629..0000000
--- a/slirp/ip_icmp.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
- * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
- */
-
-#include "slirp.h"
-#include "ip_icmp.h"
-
-struct icmpstat icmpstat;
-
-/* The message sent when emulating PING */
-/* Be nice and tell them it's just a psuedo-ping packet */
-char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n";
-
-/* list of actions for icmp_error() on RX of an icmp message */
-static int icmp_flush[19] = {
-/* ECHO REPLY (0) */ 0,
- 1,
- 1,
-/* DEST UNREACH (3) */ 1,
-/* SOURCE QUENCH (4)*/ 1,
-/* REDIRECT (5) */ 1,
- 1,
- 1,
-/* ECHO (8) */ 0,
-/* ROUTERADVERT (9) */ 1,
-/* ROUTERSOLICIT (10) */ 1,
-/* TIME EXCEEDED (11) */ 1,
-/* PARAMETER PROBLEM (12) */ 1,
-/* TIMESTAMP (13) */ 0,
-/* TIMESTAMP REPLY (14) */ 0,
-/* INFO (15) */ 0,
-/* INFO REPLY (16) */ 0,
-/* ADDR MASK (17) */ 0,
-/* ADDR MASK REPLY (18) */ 0
-};
-
-/*
- * Process a received ICMP message.
- */
-void
-icmp_input(m, hlen)
- MBuf m;
- int hlen;
-{
- register struct icmp *icp;
- register struct ip *ip=MBUF_TO(m, struct ip *);
- int icmplen=ip->ip_len;
- /* int code; */
-
- DEBUG_CALL("icmp_input");
- DEBUG_ARG("m = %lx", (long )m);
- DEBUG_ARG("m_len = %d", m->m_len);
-
- icmpstat.icps_received++;
-
- /*
- * Locate icmp structure in mbuf, and check
- * that its not corrupted and of at least minimum length.
- */
- if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */
- icmpstat.icps_tooshort++;
- freeit:
- mbuf_free(m);
- goto end_error;
- }
-
- m->m_len -= hlen;
- m->m_data += hlen;
- icp = MBUF_TO(m, struct icmp *);
- if (cksum(m, icmplen)) {
- icmpstat.icps_checksum++;
- goto freeit;
- }
- m->m_len += hlen;
- m->m_data -= hlen;
-
- /* icmpstat.icps_inhist[icp->icmp_type]++; */
- /* code = icp->icmp_code; */
-
- DEBUG_ARG("icmp_type = %d", icp->icmp_type);
- switch (icp->icmp_type) {
- case ICMP_ECHO:
- icp->icmp_type = ICMP_ECHOREPLY;
- ip->ip_len += hlen; /* since ip_input subtracts this */
- if (ip->ip_dst.s_addr == alias_addr.s_addr) {
- icmp_reflect(m);
- } else {
- struct socket *so;
- struct sockaddr_in addr;
- if ((so = socreate()) == NULL) goto freeit;
- if(udp_attach(so) == -1) {
- DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
- errno,strerror(errno)));
- sofree(so);
- mbuf_free(m);
- goto end_error;
- }
- so->so_m = m;
- so->so_faddr = ip->ip_dst;
- so->so_fport = htons(7);
- so->so_laddr = ip->ip_src;
- so->so_lport = htons(9);
- so->so_iptos = ip->ip_tos;
- so->so_type = IPPROTO_ICMP;
- so->so_state = SS_ISFCONNECTED;
-
- /* Send the packet */
- addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
- /* It's an alias */
- int low = ntohl(so->so_faddr.s_addr) & 0xff;
-
- if (low >= CTL_DNS && low < CTL_DNS + dns_addr_count)
- addr.sin_addr = dns_addr[low - CTL_DNS];
- else
- addr.sin_addr = loopback_addr;
- } else {
- addr.sin_addr = so->so_faddr;
- }
- addr.sin_port = so->so_fport;
- if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
- (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
- errno,strerror(errno)));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
- udp_detach(so);
- }
- } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
- break;
- case ICMP_UNREACH:
- /* XXX? report error? close socket? */
- case ICMP_TIMXCEED:
- case ICMP_PARAMPROB:
- case ICMP_SOURCEQUENCH:
- case ICMP_TSTAMP:
- case ICMP_MASKREQ:
- case ICMP_REDIRECT:
- icmpstat.icps_notsupp++;
- mbuf_free(m);
- break;
-
- default:
- icmpstat.icps_badtype++;
- mbuf_free(m);
- } /* swith */
-
-end_error:
- /* m is mbuf_free()'d xor put in a socket xor or given to ip_send */
- return;
-}
-
-
-/*
- * Send an ICMP message in response to a situation
- *
- * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we do).
- * MUST NOT change this header information.
- * MUST NOT reply to a multicast/broadcast IP address.
- * MUST NOT reply to a multicast/broadcast MAC address.
- * MUST reply to only the first fragment.
- */
-/*
- * Send ICMP_UNREACH back to the source regarding msrc.
- * mbuf *msrc is used as a template, but is NOT mbuf_free()'d.
- * It is reported as the bad ip packet. The header should
- * be fully correct and in host byte order.
- * ICMP fragmentation is illegal. All machines must accept 576 bytes in one
- * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548
- */
-
-#define ICMP_MAXDATALEN (IP_MSS-28)
-void
-icmp_error(msrc, type, code, minsize, message)
- MBuf msrc;
- u_char type;
- u_char code;
- int minsize;
- char *message;
-{
- unsigned hlen, shlen, s_ip_len;
- register struct ip *ip;
- register struct icmp *icp;
- register MBuf m;
-
- DEBUG_CALL("icmp_error");
- DEBUG_ARG("msrc = %lx", (long )msrc);
- DEBUG_ARG("msrc_len = %d", msrc->m_len);
-
- if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error;
-
- /* check msrc */
- if(!msrc) goto end_error;
- ip = MBUF_TO(msrc, struct ip *);
-#if DEBUG
- { char bufa[20], bufb[20];
- strcpy(bufa, inet_ntoa(ip->ip_src));
- strcpy(bufb, inet_ntoa(ip->ip_dst));
- DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb));
- }
-#endif
- if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */
-
- shlen=ip->ip_hl << 2;
- s_ip_len=ip->ip_len;
- if(ip->ip_p == IPPROTO_ICMP) {
- icp = (struct icmp *)((char *)ip + shlen);
- /*
- * Assume any unknown ICMP type is an error. This isn't
- * specified by the RFC, but think about it..
- */
- if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error;
- }
-
- /* make a copy */
- if(!(m=mbuf_alloc())) goto end_error; /* get mbuf */
- { int new_m_size;
- new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN;
- if(new_m_size>m->m_size) mbuf_ensure(m, new_m_size);
- }
- memcpy(m->m_data, msrc->m_data, msrc->m_len);
- m->m_len = msrc->m_len; /* copy msrc to m */
-
- /* make the header of the reply packet */
- ip = MBUF_TO(m, struct ip *);
- hlen= sizeof(struct ip ); /* no options in reply */
-
- /* fill in icmp */
- m->m_data += hlen;
- m->m_len -= hlen;
-
- icp = MBUF_TO(m, struct icmp *);
-
- if(minsize) s_ip_len=shlen+ICMP_MINLEN; /* return header+8b only */
- else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */
- s_ip_len=ICMP_MAXDATALEN;
-
- m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */
-
- /* min. size = 8+sizeof(struct ip)+8 */
-
- icp->icmp_type = type;
- icp->icmp_code = code;
- icp->icmp_id = 0;
- icp->icmp_seq = 0;
-
- memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */
- HTONS(icp->icmp_ip.ip_len);
- HTONS(icp->icmp_ip.ip_id);
- HTONS(icp->icmp_ip.ip_off);
-
-#if DEBUG
- if(message) { /* DEBUG : append message to ICMP packet */
- int message_len;
- char *cpnt;
- message_len=strlen(message);
- if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN;
- cpnt=(char *)m->m_data+m->m_len;
- memcpy(cpnt, message, message_len);
- m->m_len+=message_len;
- }
-#endif
-
- icp->icmp_cksum = 0;
- icp->icmp_cksum = cksum(m, m->m_len);
-
- m->m_data -= hlen;
- m->m_len += hlen;
-
- /* fill in ip */
- ip->ip_hl = hlen >> 2;
- ip->ip_len = m->m_len;
-
- ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */
-
- ip->ip_ttl = MAXTTL;
- ip->ip_p = IPPROTO_ICMP;
- ip->ip_dst = ip->ip_src; /* ip adresses */
- ip->ip_src = alias_addr;
-
- (void ) ip_output((struct socket *)NULL, m);
-
- icmpstat.icps_reflect++;
-
-end_error:
- return;
-}
-#undef ICMP_MAXDATALEN
-
-/*
- * Reflect the ip packet back to the source
- */
-void
-icmp_reflect(m)
- MBuf m;
-{
- register struct ip *ip = MBUF_TO(m, struct ip *);
- int hlen = ip->ip_hl << 2;
- int optlen = hlen - sizeof(struct ip );
- register struct icmp *icp;
-
- /*
- * Send an icmp packet back to the ip level,
- * after supplying a checksum.
- */
- m->m_data += hlen;
- m->m_len -= hlen;
- icp = MBUF_TO(m, struct icmp *);
-
- icp->icmp_cksum = 0;
- icp->icmp_cksum = cksum(m, ip->ip_len - hlen);
-
- m->m_data -= hlen;
- m->m_len += hlen;
-
- /* fill in ip */
- if (optlen > 0) {
- /*
- * Strip out original options by copying rest of first
- * mbuf's data back, and adjust the IP length.
- */
- memmove((caddr_t)(ip + 1), (caddr_t)ip + hlen,
- (unsigned )(m->m_len - hlen));
- hlen -= optlen;
- ip->ip_hl = hlen >> 2;
- ip->ip_len -= optlen;
- m->m_len -= optlen;
- }
-
- ip->ip_ttl = MAXTTL;
- { /* swap */
- struct in_addr icmp_dst;
- icmp_dst = ip->ip_dst;
- ip->ip_dst = ip->ip_src;
- ip->ip_src = icmp_dst;
- }
-
- (void ) ip_output((struct socket *)NULL, m);
-
- icmpstat.icps_reflect++;
-}
diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
deleted file mode 100644
index 42740db..0000000
--- a/slirp/ip_icmp.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
- * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp
- */
-
-#ifndef _NETINET_IP_ICMP_H_
-#define _NETINET_IP_ICMP_H_
-
-/*
- * Interface Control Message Protocol Definitions.
- * Per RFC 792, September 1981.
- */
-
-typedef u_int32_t n_time;
-
-/*
- * Structure of an icmp header.
- */
-struct icmp {
- u_char icmp_type; /* type of message, see below */
- u_char icmp_code; /* type sub code */
- u_short icmp_cksum; /* ones complement cksum of struct */
- union {
- u_char ih_pptr; /* ICMP_PARAMPROB */
- struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
- struct ih_idseq {
- u_short icd_id;
- u_short icd_seq;
- } ih_idseq;
- int ih_void;
-
- /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
- struct ih_pmtu {
- u_short ipm_void;
- u_short ipm_nextmtu;
- } ih_pmtu;
- } icmp_hun;
-#define icmp_pptr icmp_hun.ih_pptr
-#define icmp_gwaddr icmp_hun.ih_gwaddr
-#define icmp_id icmp_hun.ih_idseq.icd_id
-#define icmp_seq icmp_hun.ih_idseq.icd_seq
-#define icmp_void icmp_hun.ih_void
-#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
-#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
- union {
- struct id_ts {
- n_time its_otime;
- n_time its_rtime;
- n_time its_ttime;
- } id_ts;
- struct id_ip {
- struct ip idi_ip;
- /* options and then 64 bits of data */
- } id_ip;
- uint32_t id_mask;
- char id_data[1];
- } icmp_dun;
-#define icmp_otime icmp_dun.id_ts.its_otime
-#define icmp_rtime icmp_dun.id_ts.its_rtime
-#define icmp_ttime icmp_dun.id_ts.its_ttime
-#define icmp_ip icmp_dun.id_ip.idi_ip
-#define icmp_mask icmp_dun.id_mask
-#define icmp_data icmp_dun.id_data
-};
-
-/*
- * Lower bounds on packet lengths for various types.
- * For the error advice packets must first insure that the
- * packet is large enought to contain the returned ip header.
- * Only then can we do the check to see if 64 bits of packet
- * data have been returned, since we need to check the returned
- * ip header length.
- */
-#define ICMP_MINLEN 8 /* abs minimum */
-#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
-#define ICMP_MASKLEN 12 /* address mask */
-#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
-#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
- /* N.B.: must separately check that ip_hl >= 5 */
-
-/*
- * Definition of type and code field values.
- */
-#define ICMP_ECHOREPLY 0 /* echo reply */
-#define ICMP_UNREACH 3 /* dest unreachable, codes: */
-#define ICMP_UNREACH_NET 0 /* bad net */
-#define ICMP_UNREACH_HOST 1 /* bad host */
-#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
-#define ICMP_UNREACH_PORT 3 /* bad port */
-#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
-#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
-#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
-#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
-#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
-#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
-#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
-#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
-#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
-#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
-#define ICMP_REDIRECT 5 /* shorter route, codes: */
-#define ICMP_REDIRECT_NET 0 /* for network */
-#define ICMP_REDIRECT_HOST 1 /* for host */
-#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
-#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
-#define ICMP_ECHO 8 /* echo service */
-#define ICMP_ROUTERADVERT 9 /* router advertisement */
-#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
-#define ICMP_TIMXCEED 11 /* time exceeded, code: */
-#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
-#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
-#define ICMP_PARAMPROB 12 /* ip header bad */
-#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
-#define ICMP_TSTAMP 13 /* timestamp request */
-#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
-#define ICMP_IREQ 15 /* information request */
-#define ICMP_IREQREPLY 16 /* information reply */
-#define ICMP_MASKREQ 17 /* address mask request */
-#define ICMP_MASKREPLY 18 /* address mask reply */
-
-#define ICMP_MAXTYPE 18
-
-#define ICMP_INFOTYPE(type) \
- ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
- (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
- (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
- (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
- (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
-
-void icmp_input _P((MBuf , int));
-void icmp_error _P((MBuf , u_char, u_char, int, char *));
-void icmp_reflect _P((MBuf ));
-
-#endif
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
deleted file mode 100644
index cc320de..0000000
--- a/slirp/ip_input.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
- * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp
- */
-
-/*
- * Changes and additions relating to SLiRP are
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#include "ip_icmp.h"
-
-int ip_defttl;
-struct ipstat ipstat;
-struct ipq ipq;
-
-/*
- * IP initialization: fill in IP protocol switch table.
- * All protocols not implemented in kernel go to raw IP protocol handler.
- */
-void
-ip_init()
-{
- ipq.next = ipq.prev = (ipqp_32)&ipq;
- ip_id = tt.tv_sec & 0xffff;
- udp_init();
- tcp_init();
- ip_defttl = IPDEFTTL;
-}
-
-/*
- * Ip input routine. Checksum and byte swap header. If fragmented
- * try to reassemble. Process options. Pass to next level.
- */
-void
-ip_input(m)
- MBuf m;
-{
- register struct ip *ip;
- int hlen;
-
- DEBUG_CALL("ip_input");
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("m_len = %d", m->m_len);
-
- ipstat.ips_total++;
-
- if (m->m_len < sizeof (struct ip)) {
- ipstat.ips_toosmall++;
- return;
- }
-
- ip = MBUF_TO(m, struct ip *);
-
- if (ip->ip_v != IPVERSION) {
- ipstat.ips_badvers++;
- goto bad;
- }
-
- hlen = ip->ip_hl << 2;
- if (hlen<sizeof(struct ip ) || hlen>m->m_len) {/* min header length */
- ipstat.ips_badhlen++; /* or packet too short */
- goto bad;
- }
-
- /* keep ip header intact for ICMP reply
- * ip->ip_sum = cksum(m, hlen);
- * if (ip->ip_sum) {
- */
- if(cksum(m,hlen)) {
- ipstat.ips_badsum++;
- goto bad;
- }
-
- /*
- * Convert fields to host representation.
- */
- NTOHS(ip->ip_len);
- if (ip->ip_len < hlen) {
- ipstat.ips_badlen++;
- goto bad;
- }
- NTOHS(ip->ip_id);
- NTOHS(ip->ip_off);
-
- /*
- * Check that the amount of data in the buffers
- * is as at least much as the IP header would have us expect.
- * Trim mbufs if longer than we expect.
- * Drop packet if shorter than we expect.
- */
- if (m->m_len < ip->ip_len) {
- ipstat.ips_tooshort++;
- goto bad;
- }
- /* Should drop packet if mbuf too long? hmmm... */
- if (m->m_len > ip->ip_len)
- mbuf_trim(m, ip->ip_len - m->m_len);
-
- /* check ip_ttl for a correct ICMP reply */
- if(ip->ip_ttl==0 || ip->ip_ttl==1) {
- icmp_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl");
- goto bad;
- }
-
- /*
- * Process options and, if not destined for us,
- * ship it on. ip_dooptions returns 1 when an
- * error was detected (causing an icmp message
- * to be sent and the original packet to be freed).
- */
-/* We do no IP options */
-/* if (hlen > sizeof (struct ip) && ip_dooptions(m))
- * goto next;
- */
- /*
- * If offset or IP_MF are set, must reassemble.
- * Otherwise, nothing need be done.
- * (We could look in the reassembly queue to see
- * if the packet was previously fragmented,
- * but it's not worth the time; just let them time out.)
- *
- * XXX This should fail, don't fragment yet
- */
- if (ip->ip_off &~ IP_DF) {
- register struct ipq *fp;
- /*
- * Look for queue of fragments
- * of this datagram.
- */
- for (fp = (struct ipq *) ipq.next; fp != &ipq;
- fp = (struct ipq *) fp->next)
- if (ip->ip_id == fp->ipq_id &&
- ip->ip_src.s_addr == fp->ipq_src.s_addr &&
- ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
- ip->ip_p == fp->ipq_p)
- goto found;
- fp = 0;
- found:
-
- /*
- * Adjust ip_len to not reflect header,
- * set ip_mff if more fragments are expected,
- * convert offset of this to bytes.
- */
- ip->ip_len -= hlen;
- if (ip->ip_off & IP_MF)
- ((struct ipasfrag *)ip)->ipf_mff |= 1;
- else
- ((struct ipasfrag *)ip)->ipf_mff &= ~1;
-
- ip->ip_off <<= 3;
-
- /*
- * If datagram marked as having more fragments
- * or if this is not the first fragment,
- * attempt reassembly; if it succeeds, proceed.
- */
- if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
- ipstat.ips_fragments++;
- ip = ip_reass((struct ipasfrag *)ip, fp);
- if (ip == 0)
- return;
- ipstat.ips_reassembled++;
- m = MBUF_FROM(ip);
- } else
- if (fp)
- ip_freef(fp);
-
- } else
- ip->ip_len -= hlen;
-
- /*
- * Switch out to protocol's input routine.
- */
- ipstat.ips_delivered++;
- switch (ip->ip_p) {
- case IPPROTO_TCP:
- tcp_input(m, hlen, (struct socket *)NULL);
- break;
- case IPPROTO_UDP:
- udp_input(m, hlen);
- break;
- case IPPROTO_ICMP:
- icmp_input(m, hlen);
- break;
- default:
- ipstat.ips_noproto++;
- mbuf_free(m);
- }
- return;
-bad:
- mbuf_free(m);
- return;
-}
-
-/*
- * Take incoming datagram fragment and try to
- * reassemble it into whole datagram. If a chain for
- * reassembly of this datagram already exists, then it
- * is given as fp; otherwise have to make a chain.
- */
-struct ip *
-ip_reass(ip, fp)
- register struct ipasfrag *ip;
- register struct ipq *fp;
-{
- register MBuf m = MBUF_FROM(ip);
- register struct ipasfrag *q;
- int hlen = ip->ip_hl << 2;
- int i, next;
-
- DEBUG_CALL("ip_reass");
- DEBUG_ARG("ip = %lx", (long)ip);
- DEBUG_ARG("fp = %lx", (long)fp);
- DEBUG_ARG("m = %lx", (long)m);
-
- /*
- * Presence of header sizes in mbufs
- * would confuse code below.
- * Fragment m_data is concatenated.
- */
- m->m_data += hlen;
- m->m_len -= hlen;
-
- /*
- * If first fragment to arrive, create a reassembly queue.
- */
- if (fp == 0) {
- MBuf t;
- if ((t = mbuf_alloc()) == NULL) goto dropfrag;
- fp = MBUF_TO(t, struct ipq *);
- insque_32(fp, &ipq);
- fp->ipq_ttl = IPFRAGTTL;
- fp->ipq_p = ip->ip_p;
- fp->ipq_id = ip->ip_id;
- fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;
- fp->ipq_src = ((struct ip *)ip)->ip_src;
- fp->ipq_dst = ((struct ip *)ip)->ip_dst;
- q = (struct ipasfrag *)fp;
- goto insert;
- }
-
- /*
- * Find a segment which begins after this one does.
- */
- for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;
- q = (struct ipasfrag *)q->ipf_next)
- if (q->ip_off > ip->ip_off)
- break;
-
- /*
- * If there is a preceding segment, it may provide some of
- * our data already. If so, drop the data from the incoming
- * segment. If it provides all of our data, drop us.
- */
- if (q->ipf_prev != (ipasfragp_32)fp) {
- i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +
- ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off;
- if (i > 0) {
- if (i >= ip->ip_len)
- goto dropfrag;
- mbuf_trim(MBUF_FROM(ip), i);
- ip->ip_off += i;
- ip->ip_len -= i;
- }
- }
-
- /*
- * While we overlap succeeding segments trim them or,
- * if they are completely covered, dequeue them.
- */
- while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
- i = (ip->ip_off + ip->ip_len) - q->ip_off;
- if (i < q->ip_len) {
- q->ip_len -= i;
- q->ip_off += i;
- mbuf_trim(MBUF_FROM(q), i);
- break;
- }
- q = (struct ipasfrag *) q->ipf_next;
- mbuf_free(MBUF_FROM((struct ipasfrag *) q->ipf_prev));
- ip_deq((struct ipasfrag *) q->ipf_prev);
- }
-
-insert:
- /*
- * Stick new segment in its place;
- * check for complete reassembly.
- */
- ip_enq(ip, (struct ipasfrag *) q->ipf_prev);
- next = 0;
- for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
- q = (struct ipasfrag *) q->ipf_next) {
- if (q->ip_off != next)
- return (0);
- next += q->ip_len;
- }
- if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1)
- return (0);
-
- /*
- * Reassembly is complete; concatenate fragments.
- */
- q = (struct ipasfrag *) fp->ipq_next;
- m = MBUF_FROM(q);
-
- q = (struct ipasfrag *) q->ipf_next;
- while (q != (struct ipasfrag *)fp) {
- MBuf t;
- t = MBUF_FROM(q);
- q = (struct ipasfrag *) q->ipf_next;
- mbuf_append(m, t);
- }
-
- /*
- * Create header for new ip packet by
- * modifying header of first packet;
- * dequeue and discard fragment reassembly header.
- * Make header visible.
- */
- ip = (struct ipasfrag *) fp->ipq_next;
-
- /*
- * If the fragments concatenated to an mbuf that's
- * bigger than the total size of the fragment, then and
- * m_ext buffer was alloced. But fp->ipq_next points to
- * the old buffer (in the mbuf), so we must point ip
- * into the new buffer.
- */
- if (m->m_flags & M_EXT) {
- int delta;
- delta = (char *)ip - m->m_dat;
- ip = (struct ipasfrag *)(m->m_ext + delta);
- }
-
- /* DEBUG_ARG("ip = %lx", (long)ip);
- * ip=(struct ipasfrag *)m->m_data; */
-
- ip->ip_len = next;
- ip->ipf_mff &= ~1;
- ((struct ip *)ip)->ip_src = fp->ipq_src;
- ((struct ip *)ip)->ip_dst = fp->ipq_dst;
- remque_32(fp);
- (void) mbuf_free(MBUF_FROM(fp));
- m = MBUF_FROM(ip);
- m->m_len += (ip->ip_hl << 2);
- m->m_data -= (ip->ip_hl << 2);
-
- return ((struct ip *)ip);
-
-dropfrag:
- ipstat.ips_fragdropped++;
- mbuf_free(m);
- return (0);
-}
-
-/*
- * Free a fragment reassembly header and all
- * associated datagrams.
- */
-void
-ip_freef(fp)
- struct ipq *fp;
-{
- register struct ipasfrag *q, *p;
-
- for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
- q = p) {
- p = (struct ipasfrag *) q->ipf_next;
- ip_deq(q);
- mbuf_free(MBUF_FROM(q));
- }
- remque_32(fp);
- (void) mbuf_free(MBUF_FROM(fp));
-}
-
-/*
- * Put an ip fragment on a reassembly chain.
- * Like insque, but pointers in middle of structure.
- */
-void
-ip_enq(p, prev)
- register struct ipasfrag *p, *prev;
-{
- DEBUG_CALL("ip_enq");
- DEBUG_ARG("prev = %lx", (long)prev);
- p->ipf_prev = (ipasfragp_32) prev;
- p->ipf_next = prev->ipf_next;
- ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p;
- prev->ipf_next = (ipasfragp_32) p;
-}
-
-/*
- * To ip_enq as remque is to insque.
- */
-void
-ip_deq(p)
- register struct ipasfrag *p;
-{
- ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next;
- ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev;
-}
-
-/*
- * IP timer processing;
- * if a timer expires on a reassembly
- * queue, discard it.
- */
-void
-ip_slowtimo()
-{
- register struct ipq *fp;
-
- DEBUG_CALL("ip_slowtimo");
-
- fp = (struct ipq *) ipq.next;
- if (fp == 0)
- return;
-
- while (fp != &ipq) {
- --fp->ipq_ttl;
- fp = (struct ipq *) fp->next;
- if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
- ipstat.ips_fragtimeout++;
- ip_freef((struct ipq *) fp->prev);
- }
- }
-}
-
-/*
- * Do option processing on a datagram,
- * possibly discarding it if bad options are encountered,
- * or forwarding it if source-routed.
- * Returns 1 if packet has been forwarded/freed,
- * 0 if the packet should be processed further.
- */
-
-#ifdef notdef
-
-int
-ip_dooptions(m)
- MBuf m;
-{
- register struct ip *ip = MBUF_TO(m, struct ip *);
- register u_char *cp;
- register struct ip_timestamp *ipt;
- register struct in_ifaddr *ia;
-/* int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; */
- int opt, optlen, cnt, off, code, type, forward = 0;
- struct in_addr *sin, dst;
-typedef u_int32_t n_time;
- n_time ntime;
-
- dst = ip->ip_dst;
- cp = (u_char *)(ip + 1);
- cnt = (ip->ip_hl << 2) - sizeof (struct ip);
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[IPOPT_OPTVAL];
- if (opt == IPOPT_EOL)
- break;
- if (opt == IPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[IPOPT_OLEN];
- if (optlen <= 0 || optlen > cnt) {
- code = &cp[IPOPT_OLEN] - (u_char *)ip;
- goto bad;
- }
- }
- switch (opt) {
-
- default:
- break;
-
- /*
- * Source routing with record.
- * Find interface with current destination address.
- * If none on this machine then drop if strictly routed,
- * or do nothing if loosely routed.
- * Record interface address and bring up next address
- * component. If strictly routed make sure next
- * address is on directly accessible net.
- */
- case IPOPT_LSRR:
- case IPOPT_SSRR:
- if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
- code = &cp[IPOPT_OFFSET] - (u_char *)ip;
- goto bad;
- }
- ipaddr.sin_addr = ip->ip_dst;
- ia = (struct in_ifaddr *)
- ifa_ifwithaddr((struct sockaddr *)&ipaddr);
- if (ia == 0) {
- if (opt == IPOPT_SSRR) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_SRCFAIL;
- goto bad;
- }
- /*
- * Loose routing, and not at next destination
- * yet; nothing to do except forward.
- */
- break;
- }
- off--; / * 0 origin * /
- if (off > optlen - sizeof(struct in_addr)) {
- /*
- * End of source route. Should be for us.
- */
- save_rte(cp, ip->ip_src);
- break;
- }
- /*
- * locate outgoing interface
- */
- bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
- sizeof(ipaddr.sin_addr));
- if (opt == IPOPT_SSRR) {
-#define INA struct in_ifaddr *
-#define SA struct sockaddr *
- if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
- ia = (INA)ifa_ifwithnet((SA)&ipaddr);
- } else
- ia = ip_rtaddr(ipaddr.sin_addr);
- if (ia == 0) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_SRCFAIL;
- goto bad;
- }
- ip->ip_dst = ipaddr.sin_addr;
- bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
- (caddr_t)(cp + off), sizeof(struct in_addr));
- cp[IPOPT_OFFSET] += sizeof(struct in_addr);
- /*
- * Let ip_intr's mcast routing check handle mcast pkts
- */
- forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));
- break;
-
- case IPOPT_RR:
- if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
- code = &cp[IPOPT_OFFSET] - (u_char *)ip;
- goto bad;
- }
- /*
- * If no space remains, ignore.
- */
- off--; * 0 origin *
- if (off > optlen - sizeof(struct in_addr))
- break;
- bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
- sizeof(ipaddr.sin_addr));
- /*
- * locate outgoing interface; if we're the destination,
- * use the incoming interface (should be same).
- */
- if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
- (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_HOST;
- goto bad;
- }
- bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
- (caddr_t)(cp + off), sizeof(struct in_addr));
- cp[IPOPT_OFFSET] += sizeof(struct in_addr);
- break;
-
- case IPOPT_TS:
- code = cp - (u_char *)ip;
- ipt = (struct ip_timestamp *)cp;
- if (ipt->ipt_len < 5)
- goto bad;
- if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) {
- if (++ipt->ipt_oflw == 0)
- goto bad;
- break;
- }
- sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
- switch (ipt->ipt_flg) {
-
- case IPOPT_TS_TSONLY:
- break;
-
- case IPOPT_TS_TSANDADDR:
- if (ipt->ipt_ptr + sizeof(n_time) +
- sizeof(struct in_addr) > ipt->ipt_len)
- goto bad;
- ipaddr.sin_addr = dst;
- ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr,
- m->m_pkthdr.rcvif);
- if (ia == 0)
- continue;
- bcopy((caddr_t)&IA_SIN(ia)->sin_addr,
- (caddr_t)sin, sizeof(struct in_addr));
- ipt->ipt_ptr += sizeof(struct in_addr);
- break;
-
- case IPOPT_TS_PRESPEC:
- if (ipt->ipt_ptr + sizeof(n_time) +
- sizeof(struct in_addr) > ipt->ipt_len)
- goto bad;
- bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
- sizeof(struct in_addr));
- if (ifa_ifwithaddr((SA)&ipaddr) == 0)
- continue;
- ipt->ipt_ptr += sizeof(struct in_addr);
- break;
-
- default:
- goto bad;
- }
- ntime = iptime();
- bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
- sizeof(n_time));
- ipt->ipt_ptr += sizeof(n_time);
- }
- }
- if (forward) {
- ip_forward(m, 1);
- return (1);
- }
- }
- }
- return (0);
-bad:
- /* ip->ip_len -= ip->ip_hl << 2; XXX icmp_error adds in hdr length */
-
-/* Not yet */
- icmp_error(m, type, code, 0, 0);
-
- ipstat.ips_badoptions++;
- return (1);
-}
-
-#endif /* notdef */
-
-/*
- * Strip out IP options, at higher
- * level protocol in the kernel.
- * Second argument is buffer to which options
- * will be moved, and return value is their length.
- * (XXX) should be deleted; last arg currently ignored.
- */
-void
-ip_stripoptions(m, mopt)
- register MBuf m;
- MBuf mopt;
-{
- register int i;
- struct ip *ip = MBUF_TO(m, struct ip *);
- register caddr_t opts;
- int olen;
-
- olen = (ip->ip_hl<<2) - sizeof (struct ip);
- opts = (caddr_t)(ip + 1);
- i = m->m_len - (sizeof (struct ip) + olen);
- memcpy(opts, opts + olen, (unsigned)i);
- m->m_len -= olen;
-
- ip->ip_hl = sizeof(struct ip) >> 2;
-}
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
deleted file mode 100644
index 42d789c..0000000
--- a/slirp/ip_output.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
- * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp
- */
-
-/*
- * Changes and additions relating to SLiRP are
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-u_int16_t ip_id;
-
-/*
- * IP output. The packet in mbuf chain m contains a skeletal IP
- * header (with len, off, ttl, proto, tos, src, dst).
- * The mbuf chain containing the packet will be freed.
- * The mbuf opt, if present, will not be freed.
- */
-int
-ip_output(so, m0)
- struct socket *so;
- MBuf m0;
-{
- register struct ip *ip;
- register MBuf m = m0;
- register int hlen = sizeof(struct ip );
- int len, off, error = 0;
-
- DEBUG_CALL("ip_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m0 = %lx", (long)m0);
-
- /* We do no options */
-/* if (opt) {
- * m = ip_insertoptions(m, opt, &len);
- * hlen = len;
- * }
- */
- ip = MBUF_TO(m, struct ip *);
- /*
- * Fill in IP header.
- */
- ip->ip_v = IPVERSION;
- ip->ip_off &= IP_DF;
- ip->ip_id = htons(ip_id++);
- ip->ip_hl = hlen >> 2;
- ipstat.ips_localout++;
-
- /*
- * Verify that we have any chance at all of being able to queue
- * the packet or packet fragments
- */
- /* XXX Hmmm... */
-/* if (if_queued > if_thresh && towrite <= 0) {
- * error = ENOBUFS;
- * goto bad;
- * }
- */
-
- /*
- * If small enough for interface, can just send directly.
- */
- if ((u_int16_t)ip->ip_len <= if_mtu) {
- ip->ip_len = htons((u_int16_t)ip->ip_len);
- ip->ip_off = htons((u_int16_t)ip->ip_off);
- ip->ip_sum = 0;
- ip->ip_sum = cksum(m, hlen);
-
- if_output(so, m);
- goto done;
- }
-
- /*
- * Too large for interface; fragment if possible.
- * Must be able to put at least 8 bytes per fragment.
- */
- if (ip->ip_off & IP_DF) {
- error = -1;
- ipstat.ips_cantfrag++;
- goto bad;
- }
-
- len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */
- if (len < 8) {
- error = -1;
- goto bad;
- }
-
- {
- int mhlen, firstlen = len;
- MBuf *mnext = &m->m_nextpkt;
-
- /*
- * Loop through length of segment after first fragment,
- * make new header and copy data of each part and link onto chain.
- */
- m0 = m;
- mhlen = sizeof (struct ip);
- for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
- register struct ip *mhip;
- m = mbuf_alloc();
- if (m == 0) {
- error = -1;
- ipstat.ips_odropped++;
- goto sendorfree;
- }
- m->m_data += if_maxlinkhdr;
- mhip = MBUF_TO(m, struct ip *);
- *mhip = *ip;
-
- /* No options */
-/* if (hlen > sizeof (struct ip)) {
- * mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
- * mhip->ip_hl = mhlen >> 2;
- * }
- */
- m->m_len = mhlen;
- mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
- if (ip->ip_off & IP_MF)
- mhip->ip_off |= IP_MF;
- if (off + len >= (u_int16_t)ip->ip_len)
- len = (u_int16_t)ip->ip_len - off;
- else
- mhip->ip_off |= IP_MF;
- mhip->ip_len = htons((u_int16_t)(len + mhlen));
-
- if (mbuf_copy(m, m0, off, len) < 0) {
- error = -1;
- goto sendorfree;
- }
-
- mhip->ip_off = htons((u_int16_t)mhip->ip_off);
- mhip->ip_sum = 0;
- mhip->ip_sum = cksum(m, mhlen);
- *mnext = m;
- mnext = &m->m_nextpkt;
- ipstat.ips_ofragments++;
- }
- /*
- * Update first fragment by trimming what's been copied out
- * and updating header, then send each fragment (in order).
- */
- m = m0;
- mbuf_trim(m, hlen + firstlen - (u_int16_t)ip->ip_len);
- ip->ip_len = htons((u_int16_t)m->m_len);
- ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
- ip->ip_sum = 0;
- ip->ip_sum = cksum(m, hlen);
-sendorfree:
- for (m = m0; m; m = m0) {
- m0 = m->m_nextpkt;
- m->m_nextpkt = 0;
- if (error == 0)
- if_output(so, m);
- else
- mbuf_free(m);
- }
-
- if (error == 0)
- ipstat.ips_fragmented++;
- }
-
-done:
- return (error);
-
-bad:
- mbuf_free(m0);
- goto done;
-}
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
deleted file mode 100644
index 3ce34b7..0000000
--- a/slirp/libslirp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _LIBSLIRP_H
-#define _LIBSLIRP_H
-
-#include <stdint.h>
-#ifdef _WIN32
-#include <winsock2.h>
-int inet_aton(const char *cp, struct in_addr *ia);
-#else
-#include <sys/select.h>
-#include <arpa/inet.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void slirp_init(void);
-
-void slirp_select_fill(int *pnfds,
- fd_set *readfds, fd_set *writefds, fd_set *xfds);
-
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds);
-
-void slirp_input(const uint8_t *pkt, int pkt_len);
-
-/* you must provide the following functions: */
-int slirp_can_output(void);
-void slirp_output(const uint8_t *pkt, int pkt_len);
-
-int slirp_redir(int is_udp, int host_port,
- struct in_addr guest_addr, int guest_port);
-
-int slirp_unredir(int is_udp, int host_port);
-
-int slirp_add_dns_server(struct in_addr dns_addr);
-int slirp_get_system_dns_servers(void);
-
-extern const char *tftp_prefix;
-extern char slirp_hostname[33];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/slirp/main.h b/slirp/main.h
deleted file mode 100644
index 49dad00..0000000
--- a/slirp/main.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#define TOWRITEMAX 512
-
-extern struct timeval tt;
-extern int link_up;
-extern int slirp_socket;
-extern int slirp_socket_unit;
-extern int slirp_socket_port;
-extern u_int32_t slirp_socket_addr;
-extern char *slirp_socket_passwd;
-extern int ctty_closed;
-
-/*
- * Get the difference in 2 times from updtim()
- * Allow for wraparound times, "just in case"
- * x is the greater of the 2 (current time) and y is
- * what it's being compared against.
- */
-#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y)
-
-#define DNS_ADDR_MAX 4
-
-extern char *slirp_tty;
-extern char *exec_shell;
-extern u_int curtime;
-extern fd_set *global_readfds, *global_writefds, *global_xfds;
-extern struct in_addr ctl_addr;
-extern struct in_addr special_addr;
-extern struct in_addr alias_addr;
-extern struct in_addr our_addr;
-extern struct in_addr loopback_addr;
-extern struct in_addr dns_addr[DNS_ADDR_MAX];
-extern int dns_addr_count;
-extern char *username;
-extern char *socket_path;
-extern int towrite_max;
-extern int ppp_exit;
-extern int so_options;
-extern int tcp_keepintvl;
-extern uint8_t client_ethaddr[6];
-
-#define PROTO_SLIP 0x1
-#ifdef USE_PPP
-#define PROTO_PPP 0x2
-#endif
-
-void if_encap(const uint8_t *ip_data, int ip_data_len);
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
deleted file mode 100644
index efc8141..0000000
--- a/slirp/mbuf.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-/*
- * mbuf's in SLiRP are much simpler than the real mbufs in
- * FreeBSD. They are fixed size, determined by the MTU,
- * so that one whole packet can fit. Mbuf's cannot be
- * chained together. If there's more data than the mbuf
- * could hold, an external malloced buffer is pointed to
- * by m_ext (and the data pointers) and M_EXT is set in
- * the flags
- */
-
-#include <slirp.h>
-
-static int mbuf_alloced = 0;
-static MBufRec m_freelist, m_usedlist;
-static int mbuf_thresh = 30;
-static int mbuf_max = 0;
-static int msize;
-
-/*
- * How much room is in the mbuf, from m_data to the end of the mbuf
- */
-#define M_ROOM(m) ((m->m_flags & M_EXT)? \
- (((m)->m_ext + (m)->m_size) - (m)->m_data) \
- : \
- (((m)->m_dat + (m)->m_size) - (m)->m_data))
-
-/*
- * How much free room there is
- */
-#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len)
-
-
-void
-mbuf_init()
-{
- m_freelist.m_next = m_freelist.m_prev = &m_freelist;
- m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
- msize_init();
-}
-
-void
-msize_init()
-{
- /*
- * Find a nice value for msize
- * XXX if_maxlinkhdr already in mtu
- */
- msize = (if_mtu > if_mru ? if_mtu : if_mru) +
- if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
-}
-
-static void
-mbuf_insque(MBuf m, MBuf head)
-{
- m->m_next = head->m_next;
- m->m_prev = head;
- head->m_next = m;
- m->m_next->m_prev = m;
-}
-
-static void
-mbuf_remque(MBuf m)
-{
- m->m_prev->m_next = m->m_next;
- m->m_next->m_prev = m->m_prev;
- m->m_next = m->m_prev = m;
-}
-
-/*
- * Get an mbuf from the free list, if there are none
- * malloc one
- *
- * Because fragmentation can occur if we alloc new mbufs and
- * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
- * which tells m_free to actually free() it
- */
-MBuf
-mbuf_alloc(void)
-{
- register MBuf m;
- int flags = 0;
-
- DEBUG_CALL("mbuf_alloc");
-
- if (m_freelist.m_next == &m_freelist) {
- m = (MBuf) malloc(msize);
- if (m == NULL) goto end_error;
- mbuf_alloced++;
- if (mbuf_alloced > mbuf_thresh)
- flags = M_DOFREE;
- if (mbuf_alloced > mbuf_max)
- mbuf_max = mbuf_alloced;
- } else {
- m = m_freelist.m_next;
- mbuf_remque(m);
- }
-
- /* Insert it in the used list */
- mbuf_insque(m,&m_usedlist);
- m->m_flags = (flags | M_USEDLIST);
-
- /* Initialise it */
- m->m_size = msize - sizeof(struct m_hdr);
- m->m_data = m->m_dat;
- m->m_len = 0;
- m->m_next2 = NULL;
- m->m_prev2 = NULL;
-end_error:
- DEBUG_ARG("m = %lx", (long )m);
- return m;
-}
-
-void
-mbuf_free(MBuf m)
-{
-
- DEBUG_CALL("mbuf_free");
- DEBUG_ARG("m = %lx", (long )m);
-
- if(m) {
- /* Remove from m_usedlist */
- if (m->m_flags & M_USEDLIST)
- mbuf_remque(m);
-
- /* If it's M_EXT, free() it */
- if (m->m_flags & M_EXT)
- free(m->m_ext);
-
- /*
- * Either free() it or put it on the free list
- */
- if (m->m_flags & M_DOFREE) {
- free(m);
- mbuf_alloced--;
- } else if ((m->m_flags & M_FREELIST) == 0) {
- mbuf_insque(m,&m_freelist);
- m->m_flags = M_FREELIST; /* Clobber other flags */
- }
- } /* if(m) */
-}
-
-/*
- * Copy data from one mbuf to the end of
- * the other.. if result is too big for one mbuf, malloc()
- * an M_EXT data segment
- */
-void
-mbuf_append(MBuf m, MBuf n)
-{
- /*
- * If there's no room, realloc
- */
- if (M_FREEROOM(m) < n->m_len)
- mbuf_ensure(m, m->m_size+MINCSIZE);
-
- memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
- m->m_len += n->m_len;
-
- mbuf_free(n);
-}
-
-
-/* make m size bytes large */
-void
-mbuf_ensure(MBuf m, int size)
-{
- int datasize;
-
- /* some compiles throw up on gotos. This one we can fake. */
- if(m->m_size > size) return;
-
- if (m->m_flags & M_EXT) {
- datasize = m->m_data - m->m_ext;
- m->m_ext = (char *)realloc(m->m_ext,size);
- m->m_data = m->m_ext + datasize;
- } else {
- char *dat;
- datasize = m->m_data - m->m_dat;
- dat = (char *)malloc(size);
- memcpy(dat, m->m_dat, m->m_size);
-
- m->m_ext = dat;
- m->m_data = m->m_ext + datasize;
- m->m_flags |= M_EXT;
- }
-
- m->m_size = size;
-}
-
-
-
-void
-mbuf_trim(MBuf m, int len)
-{
- if (m == NULL)
- return;
- if (len >= 0) {
- /* Trim from head */
- m->m_data += len;
- m->m_len -= len;
- } else {
- /* Trim from tail */
- len = -len;
- m->m_len -= len;
- }
-}
-
-
-/*
- * Copy len bytes from m, starting off bytes into n
- */
-int
-mbuf_copy(MBuf n, MBuf m, int off, int len)
-{
- if (len > M_FREEROOM(n))
- return -1;
-
- memcpy((n->m_data + n->m_len), (m->m_data + off), len);
- n->m_len += len;
- return 0;
-}
-
-int
-mbuf_freeroom( MBuf m )
-{
- return M_FREEROOM(m);
-}
-
-/*
- * Given a pointer into an mbuf, return the mbuf
- * XXX This is a kludge, I should eliminate the need for it
- * Fortunately, it's not used often
- */
-MBuf
-mbuf_from(void* dat)
-{
- MBuf m;
-
- DEBUG_CALL("mbuf_from");
- DEBUG_ARG("dat = %lx", (long )dat);
-
- /* bug corrected for M_EXT buffers */
- for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
- if (m->m_flags & M_EXT) {
- if( (unsigned)((char*)dat - m->m_ext) < (unsigned)m->m_size )
- goto Exit;
- } else {
- if( (unsigned)((char *)dat - m->m_dat) < (unsigned)m->m_size )
- goto Exit;
- }
- }
- m = NULL;
- DEBUG_ERROR((dfd, "mbuf_from failed"));
-Exit:
- return m;
-}
-
-void
-mbufstats()
-{
- MBuf m;
- int i;
-
- lprint(" \r\n");
-
- lprint("Mbuf stats:\r\n");
-
- lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max);
-
- i = 0;
- for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next)
- i++;
- lprint(" %6d mbufs on free list\r\n", i);
-
- i = 0;
- for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
- i++;
- lprint(" %6d mbufs on used list\r\n", i);
- lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
-}
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
deleted file mode 100644
index ed83372..0000000
--- a/slirp/mbuf.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)mbuf.h 8.3 (Berkeley) 1/21/94
- * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp
- */
-
-#ifndef _MBUF_H_
-#define _MBUF_H_
-
-#define MINCSIZE 4096 /* Amount to increase mbuf if too small */
-
-/* flags for the mh_flags field */
-#define M_EXT 0x01 /* m_ext points to more (malloced) data */
-#define M_FREELIST 0x02 /* mbuf is on free list */
-#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */
-#define M_DOFREE 0x08 /* when mbuf_free is called on the mbuf, free()
- * it rather than putting it on the free list */
-
-
-/* XXX About mbufs for slirp:
- * Only one mbuf is ever used in a chain, for each "cell" of data.
- * m_nextpkt points to the next packet, if fragmented.
- * If the data is too large, the M_EXT is used, and a larger block
- * is alloced. Therefore, mbuf_free[m] must check for M_EXT and if set
- * free the m_ext. This is inefficient memory-wise, but who cares.
- */
-
-/* XXX should union some of these! */
-/* header at beginning of each mbuf: */
-
-/**
- * m_next, m_prev :: used to place the MBuf in free/used linked lists
- * m_next2, m_prev2 :: used to place the same MBuf in other linked lists
- * m_flags :: bit flags describing this MBuf
- * m_size :: total size of MBuf buffer
- * m_so :: socket this MBuf is attached to
- * m_data :: pointer to current cursor in MBuf buffer
- * m_len :: amount of data recorded in this MBuf
- */
-#define MBUF_HEADER \
- struct mbuf* m_next; \
- struct mbuf* m_prev; \
- struct mbuf* m_next2; \
- struct mbuf* m_prev2; \
- int m_flags; \
- int m_size; \
- struct socket* m_so; \
- caddr_t m_data; \
- int m_len;
-
-struct m_hdr {
- MBUF_HEADER
-};
-
-typedef struct mbuf {
- MBUF_HEADER
- union M_dat {
- char m_dat_[1]; /* ANSI doesn't like 0 sized arrays */
- char* m_ext_;
- } M_dat;
-} MBufRec, *MBuf;
-
-#define m_nextpkt m_next2
-#define m_prevpkt m_prev2
-#define m_dat M_dat.m_dat_
-#define m_ext M_dat.m_ext_
-
-#define ifq_prev m_prev
-#define ifq_next m_next
-
-#define ifs_prev m_prev2
-#define ifs_next m_next2
-
-#define ifq_so m_so
-
-void mbuf_init (void);
-void msize_init (void);
-MBuf mbuf_alloc (void);
-void mbuf_free (MBuf m);
-void mbuf_append(MBuf m1, MBuf m2);
-void mbuf_ensure(MBuf m, int size);
-void mbuf_trim (MBuf m, int len);
-int mbuf_copy (MBuf m, MBuf n, int n_offset, int n_length);
-
-#define MBUF_TO(m,t) ((t)(m)->m_data)
-#define MBUF_FROM(d) mbuf_from(d)
-MBuf mbuf_from (void *);
-
-int mbuf_freeroom( MBuf m );
-
-#endif
diff --git a/slirp/misc.c b/slirp/misc.c
deleted file mode 100644
index beffeee..0000000
--- a/slirp/misc.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define WANT_SYS_IOCTL_H
-#include <slirp.h>
-#define SLIRP_COMPILATION
-#include "sockets.h"
-
-u_int curtime, time_fasttimo, last_slowtimo, detach_time;
-u_int detach_wait = 600000; /* 10 minutes */
-struct emu_t *tcpemu;
-
-#ifndef HAVE_INET_ATON
-int
-inet_aton(const char* cp, struct in_addr* ia)
-{
- u_int32_t addr = inet_addr(cp);
- if (addr == 0xffffffff)
- return 0;
- ia->s_addr = addr;
- return 1;
-}
-#endif
-
-/*
- * Get our IP address and put it in our_addr
- */
-void
-getouraddr()
-{
- char buff[256];
- struct hostent *he = NULL;
-
- if (gethostname(buff,256) == 0)
- he = gethostbyname(buff);
- if (he)
- our_addr = *(struct in_addr *)he->h_addr;
- if (our_addr.s_addr == 0)
- our_addr.s_addr = loopback_addr.s_addr;
-}
-
-#if SIZEOF_CHAR_P == 8
-
-struct quehead_32 {
- u_int32_t qh_link;
- u_int32_t qh_rlink;
-};
-
-inline void
-insque_32(void* a, void* b)
-{
- register struct quehead_32 *element = (struct quehead_32 *) a;
- register struct quehead_32 *head = (struct quehead_32 *) b;
- element->qh_link = head->qh_link;
- head->qh_link = (u_int32_t)element;
- element->qh_rlink = (u_int32_t)head;
- ((struct quehead_32 *)(element->qh_link))->qh_rlink
- = (u_int32_t)element;
-}
-
-inline void
-remque_32(void* a)
-{
- register struct quehead_32 *element = (struct quehead_32 *) a;
- ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
- ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;
- element->qh_rlink = 0;
-}
-
-#endif /* SIZEOF_CHAR_P == 8 */
-
-struct quehead {
- struct quehead *qh_link;
- struct quehead *qh_rlink;
-};
-
-inline void
-insque(void* a, void* b)
-{
- register struct quehead *element = (struct quehead *) a;
- register struct quehead *head = (struct quehead *) b;
- element->qh_link = head->qh_link;
- head->qh_link = (struct quehead *)element;
- element->qh_rlink = (struct quehead *)head;
- ((struct quehead *)(element->qh_link))->qh_rlink
- = (struct quehead *)element;
-}
-
-inline void
-remque(void* a)
-{
- register struct quehead *element = (struct quehead *) a;
- ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
- ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
- element->qh_rlink = NULL;
- /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */
-}
-
-/* #endif */
-
-
-#ifndef HAVE_STRERROR
-
-/*
- * For systems with no strerror
- */
-
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-char *
-strerror(int error)
-{
- if (error < sys_nerr)
- return sys_errlist[error];
- else
- return "Unknown error.";
-}
-
-#endif
-
-
-
-#ifndef HAVE_STRDUP
-char *
-strdup(const char* str)
-{
- char *bptr;
- int len = strlen(str);
-
- bptr = (char *)malloc(len+1);
- memcpy(bptr, str, len+1);
-
- return bptr;
-}
-#endif
-
-
-int (*lprint_print) _P((void *, const char *, va_list));
-char *lprint_ptr, *lprint_ptr2, **lprint_arg;
-
-void
-lprint(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- if (lprint_print)
- lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
-
- /* Check if they want output to be logged to file as well */
- if (lfd) {
- /*
- * Remove \r's
- * otherwise you'll get ^M all over the file
- */
- int len = strlen(format);
- char *bptr1, *bptr2;
-
- bptr1 = bptr2 = strdup(format);
-
- while (len--) {
- if (*bptr1 == '\r')
- memcpy(bptr1, bptr1+1, len+1);
- else
- bptr1++;
- }
- vfprintf(lfd, bptr2, args);
- free(bptr2);
- }
- va_end(args);
-}
-
-void
-add_emu(char* buff)
-{
- u_int lport, fport;
- u_int8_t tos = 0, emu = 0;
- char buff1[256], buff2[256], buff4[128];
- char *buff3 = buff4;
- struct emu_t *emup;
- struct socket *so;
-
- if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
- lprint("Error: Bad arguments\r\n");
- return;
- }
-
- if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
- lport = 0;
- if (sscanf(buff1, "%d", &fport) != 1) {
- lprint("Error: Bad first argument\r\n");
- return;
- }
- }
-
- if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
- buff3 = 0;
- if (sscanf(buff2, "%256s", buff1) != 1) {
- lprint("Error: Bad second argument\r\n");
- return;
- }
- }
-
- if (buff3) {
- if (strcmp(buff3, "lowdelay") == 0)
- tos = IPTOS_LOWDELAY;
- else if (strcmp(buff3, "throughput") == 0)
- tos = IPTOS_THROUGHPUT;
- else {
- lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
- return;
- }
- }
-
- if (strcmp(buff1, "ftp") == 0)
- emu = EMU_FTP;
- else if (strcmp(buff1, "irc") == 0)
- emu = EMU_IRC;
- else if (strcmp(buff1, "none") == 0)
- emu = EMU_NONE; /* ie: no emulation */
- else {
- lprint("Error: Unknown service\r\n");
- return;
- }
-
- /* First, check that it isn't already emulated */
- for (emup = tcpemu; emup; emup = emup->next) {
- if (emup->lport == lport && emup->fport == fport) {
- lprint("Error: port already emulated\r\n");
- return;
- }
- }
-
- /* link it */
- emup = (struct emu_t *)malloc(sizeof (struct emu_t));
- emup->lport = (u_int16_t)lport;
- emup->fport = (u_int16_t)fport;
- emup->tos = tos;
- emup->emu = emu;
- emup->next = tcpemu;
- tcpemu = emup;
-
- /* And finally, mark all current sessions, if any, as being emulated */
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
- if ((lport && lport == ntohs(so->so_lport)) ||
- (fport && fport == ntohs(so->so_fport))) {
- if (emu)
- so->so_emu = emu;
- if (tos)
- so->so_iptos = tos;
- }
- }
-
- lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
-}
-
-#ifdef BAD_SPRINTF
-
-#undef vsprintf
-#undef sprintf
-
-/*
- * Some BSD-derived systems have a sprintf which returns char *
- */
-
-int
-vsprintf_len(char* string, const char* format, va_list args)
-{
- vsprintf(string, format, args);
- return strlen(string);
-}
-
-int
-sprintf_len(char *string, const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- vsprintf(string, format, args);
- return strlen(string);
-}
-
-#endif
-
diff --git a/slirp/misc.h b/slirp/misc.h
deleted file mode 100644
index aa4a0ce..0000000
--- a/slirp/misc.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifndef _MISC_H_
-#define _MISC_H_
-
-extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait;
-
-extern int (*lprint_print) _P((void *, const char *, va_list));
-extern char *lprint_ptr, *lprint_ptr2, **lprint_arg;
-//extern SBuf lprint_sb;
-
-#ifndef HAVE_STRDUP
-char *strdup _P((const char *));
-#endif
-
-void do_wait _P((int));
-
-#define EMU_NONE 0x0
-
-/* TCP emulations */
-#define EMU_CTL 0x1
-#define EMU_FTP 0x2
-#define EMU_KSH 0x3
-#define EMU_IRC 0x4
-#define EMU_REALAUDIO 0x5
-#define EMU_RLOGIN 0x6
-#define EMU_IDENT 0x7
-#define EMU_RSH 0x8
-
-#define EMU_NOCONNECT 0x10 /* Don't connect */
-
-/* UDP emulations */
-#define EMU_TALK 0x1
-#define EMU_NTALK 0x2
-#define EMU_CUSEEME 0x3
-
-struct tos_t {
- u_int16_t lport;
- u_int16_t fport;
- u_int8_t tos;
- u_int8_t emu;
-};
-
-struct emu_t {
- u_int16_t lport;
- u_int16_t fport;
- u_int8_t tos;
- u_int8_t emu;
- struct emu_t *next;
-};
-
-extern struct emu_t *tcpemu;
-
-void getouraddr _P((void));
-inline void slirp_insque _P((void *, void *));
-inline void slirp_remque _P((void *));
-void add_emu _P((char *));
-
-#endif
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
deleted file mode 100644
index 3d975f8..0000000
--- a/slirp/sbuf.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#define SLIRP_COMPILATION
-#include "sockets.h"
-
-void
-sbuf_free(SBuf sb)
-{
- free(sb->sb_data);
-}
-
-void
-sbuf_drop(SBuf sb, int num)
-{
- /*
- * We can only drop how much we have
- * This should never succeed
- */
- if(num > sb->sb_cc)
- num = sb->sb_cc;
- sb->sb_cc -= num;
- sb->sb_rptr += num;
- if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
- sb->sb_rptr -= sb->sb_datalen;
-
-}
-
-void
-sbuf_reserve(SBuf sb, int size)
-{
- if (sb->sb_datalen == size)
- return;
-
- sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
- sb->sb_cc = 0;
- if (sb->sb_wptr)
- sb->sb_datalen = size;
- else
- sb->sb_datalen = 0;
-}
-
-/*
- * Try and write() to the socket, whatever doesn't get written
- * append to the buffer... for a host with a fast net connection,
- * this prevents an unnecessary copy of the data
- * (the socket is non-blocking, so we won't hang)
- */
-void
-sbuf_append(struct socket *so, MBuf m)
-{
- int ret = 0;
-
- DEBUG_CALL("sbuf_append");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("m->m_len = %d", m->m_len);
-
- /* Shouldn't happen, but... e.g. foreign host closes connection */
- if (m->m_len <= 0) {
- mbuf_free(m);
- return;
- }
-
- /*
- * If there is urgent data, call sosendoob
- * if not all was sent, sowrite will take care of the rest
- * (The rest of this function is just an optimisation)
- */
- if (so->so_urgc) {
- sbuf_appendsb(&so->so_rcv, m);
- mbuf_free(m);
- sosendoob(so);
- return;
- }
-
- /*
- * We only write if there's nothing in the buffer,
- * ottherwise it'll arrive out of order, and hence corrupt
- */
- if (!so->so_rcv.sb_cc) {
- do {
- ret = send(so->s, m->m_data, m->m_len, 0);
- } while (ret == 0 && socket_errno == EINTR);
- }
-
- if (ret <= 0) {
- /*
- * Nothing was written
- * It's possible that the socket has closed, but
- * we don't need to check because if it has closed,
- * it will be detected in the normal way by soread()
- */
- sbuf_appendsb(&so->so_rcv, m);
- } else if (ret != m->m_len) {
- /*
- * Something was written, but not everything..
- * sbuf_appendsb the rest
- */
- m->m_len -= ret;
- m->m_data += ret;
- sbuf_appendsb(&so->so_rcv, m);
- } /* else */
- /* Whatever happened, we free the mbuf */
- mbuf_free(m);
-}
-
-/*
- * Copy the data from m into sb
- * The caller is responsible to make sure there's enough room
- */
-void
-sbuf_appendsb(SBuf sb, MBuf m)
-{
- int len, n, nn;
-
- len = m->m_len;
-
- if (sb->sb_wptr < sb->sb_rptr) {
- n = sb->sb_rptr - sb->sb_wptr;
- if (n > len) n = len;
- memcpy(sb->sb_wptr, m->m_data, n);
- } else {
- /* Do the right edge first */
- n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
- if (n > len) n = len;
- memcpy(sb->sb_wptr, m->m_data, n);
- len -= n;
- if (len) {
- /* Now the left edge */
- nn = sb->sb_rptr - sb->sb_data;
- if (nn > len) nn = len;
- memcpy(sb->sb_data,m->m_data+n,nn);
- n += nn;
- }
- }
-
- sb->sb_cc += n;
- sb->sb_wptr += n;
- if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
- sb->sb_wptr -= sb->sb_datalen;
-}
-
-/*
- * Copy data from sbuf to a normal, straight buffer
- * Don't update the sbuf rptr, this will be
- * done in sbdrop when the data is acked
- */
-void
-sbuf_copy(SBuf sb, int off, int len, char* to)
-{
- char *from;
-
- from = sb->sb_rptr + off;
- if (from >= sb->sb_data + sb->sb_datalen)
- from -= sb->sb_datalen;
-
- if (from < sb->sb_wptr) {
- if (len > sb->sb_cc) len = sb->sb_cc;
- memcpy(to,from,len);
- } else {
- /* re-use off */
- off = (sb->sb_data + sb->sb_datalen) - from;
- if (off > len) off = len;
- memcpy(to,from,off);
- len -= off;
- if (len)
- memcpy(to+off,sb->sb_data,len);
- }
-}
-
diff --git a/slirp/sbuf.h b/slirp/sbuf.h
deleted file mode 100644
index 05fa01a..0000000
--- a/slirp/sbuf.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifndef _SBUF_H_
-#define _SBUF_H_
-
-#include "mbuf.h"
-#include <stddef.h>
-
-/* a SBuf is a simple circular buffer used to hold RX and TX data in a struct socket
- */
-
-typedef struct sbuf {
- unsigned sb_cc; /* actual chars in buffer */
- unsigned sb_datalen; /* Length of data */
- char* sb_wptr; /* write pointer. points to where the next
- * bytes should be written in the sbuf */
- char* sb_rptr; /* read pointer. points to where the next
- * byte should be read from the sbuf */
- char* sb_data; /* Actual data */
-} SBufRec, *SBuf;
-
-void sbuf_free (SBuf sb);
-void sbuf_drop (SBuf sb, int num);
-void sbuf_reserve (SBuf sb, int count);
-void sbuf_append (struct socket *so, MBuf m);
-void sbuf_appendsb(SBuf sb, MBuf m);
-void sbuf_copy (SBuf sb, int offset, int length, char *to);
-
-#define sbuf_flush(sb) sbuf_drop((sb),(sb)->sb_cc)
-#define sbuf_space(sb) ((sb)->sb_datalen - (sb)->sb_cc)
-
-#endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
deleted file mode 100644
index d6eaac4..0000000
--- a/slirp/slirp.c
+++ /dev/null
@@ -1,749 +0,0 @@
-#include "slirp.h"
-#include "proxy_common.h"
-#include "android_utils.h" /* for dprint */
-#include "android.h"
-
-#define D(...) VERBOSE_PRINT(slirp,__VA_ARGS__)
-#define DN(...) do { if (VERBOSE_CHECK(slirp)) dprintn(__VA_ARGS__); } while (0)
-
-/* host address */
-struct in_addr our_addr;
-/* host dns address */
-struct in_addr dns_addr[DNS_ADDR_MAX];
-int dns_addr_count;
-
-/* host loopback address */
-struct in_addr loopback_addr;
-
-/* address for slirp virtual addresses */
-struct in_addr special_addr;
-/* virtual address alias for host */
-struct in_addr alias_addr;
-
-const uint8_t special_ethaddr[6] = {
- 0x52, 0x54, 0x00, 0x12, 0x35, 0x00
-};
-
-uint8_t client_ethaddr[6] = {
- 0x52, 0x54, 0x00, 0x12, 0x34, 0x56
-};
-
-int do_slowtimo;
-int link_up;
-struct timeval tt;
-FILE *lfd;
-
-/* XXX: suppress those select globals */
-fd_set *global_readfds, *global_writefds, *global_xfds;
-
-char slirp_hostname[33];
-
-int slirp_add_dns_server(struct in_addr new_dns_addr)
-{
- if (dns_addr_count >= DNS_ADDR_MAX)
- return -1;
-
- dns_addr[dns_addr_count++] = new_dns_addr;
- return 0;
-}
-
-
-#ifdef _WIN32
-
-int slirp_get_system_dns_servers()
-{
- FIXED_INFO *FixedInfo=NULL;
- ULONG BufLen;
- DWORD ret;
- IP_ADDR_STRING *pIPAddr;
- struct in_addr tmp_addr;
-
- if (dns_addr_count > 0)
- return dns_addr_count;
-
- FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
- BufLen = sizeof(FIXED_INFO);
-
- if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
- if (FixedInfo) {
- GlobalFree(FixedInfo);
- FixedInfo = NULL;
- }
- FixedInfo = GlobalAlloc(GPTR, BufLen);
- }
-
- if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
- printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
- if (FixedInfo) {
- GlobalFree(FixedInfo);
- FixedInfo = NULL;
- }
- return -1;
- }
-
- D( "DNS Servers:");
- pIPAddr = &(FixedInfo->DnsServerList);
- while (pIPAddr && dns_addr_count < DNS_ADDR_MAX) {
- D( " %s", pIPAddr->IpAddress.String );
- inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
- if (tmp_addr.s_addr == loopback_addr.s_addr)
- tmp_addr = our_addr;
- if (dns_addr_count < DNS_ADDR_MAX)
- dns_addr[dns_addr_count++] = tmp_addr;
- pIPAddr = pIPAddr->Next;
- }
-
- if (FixedInfo) {
- GlobalFree(FixedInfo);
- FixedInfo = NULL;
- }
- if (dns_addr_count <= 0)
- return -1;
-
- return dns_addr_count;
-}
-
-#else
-
-int slirp_get_system_dns_servers(void)
-{
- char buff[512];
- char buff2[256];
- FILE *f;
- struct in_addr tmp_addr;
-
- if (dns_addr_count > 0)
- return dns_addr_count;
-
-#ifdef CONFIG_DARWIN
- /* on Darwin /etc/resolv.conf is a symlink to /private/var/run/resolv.conf
- * in some siutations, the symlink can be destroyed and the system will not
- * re-create it. Darwin-aware applications will continue to run, but "legacy"
- * Unix ones will not.
- */
- f = fopen("/private/var/run/resolv.conf", "r");
- if (!f)
- f = fopen("/etc/resolv.conf", "r"); /* desperate attempt to sanity */
-#else
- f = fopen("/etc/resolv.conf", "r");
-#endif
- if (!f)
- return -1;
-
- DN("emulator: IP address of your DNS(s): ");
- while (fgets(buff, 512, f) != NULL) {
- if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
- if (!inet_aton(buff2, &tmp_addr))
- continue;
- if (tmp_addr.s_addr == loopback_addr.s_addr)
- tmp_addr = our_addr;
- if (dns_addr_count < DNS_ADDR_MAX) {
- dns_addr[dns_addr_count++] = tmp_addr;
- if (dns_addr_count > 1)
- DN(", ");
- DN("%s", inet_ntoa(tmp_addr));
- } else {
- DN("(more)");
- break;
- }
- }
- }
- DN("\n");
- fclose(f);
-
- if (!dns_addr_count)
- return -1;
-
- return dns_addr_count;
-}
-
-#endif
-
-extern void slirp_init_shapers();
-
-void slirp_init(void)
-{
-#if DEBUG
- int slirp_logmask = 0;
- char slirp_logfile[512];
-
- {
- const char* env = getenv( "ANDROID_SLIRP_LOGMASK" );
- if (env != NULL)
- slirp_logmask = atoi(env);
- else if (VERBOSE_CHECK(slirp))
- slirp_logmask = DEBUG_DEFAULT;
- }
-
- {
- char* p = slirp_logfile;
- char* end = p + sizeof(slirp_logfile);
-
- p = bufprint_temp_file( p, end, "slirp.log" );
- if (p >= end) {
- dprint( "cannot create slirp log file in temporary directory" );
- slirp_logmask = 0;
- }
- }
- if (slirp_logmask) {
- dprint( "sending slirp logs with mask %x to %s", slirp_logmask, slirp_logfile );
- debug_init( slirp_logfile, slirp_logmask );
- }
-#endif
-
- link_up = 1;
-
- if_init();
- ip_init();
-
- /* Initialise mbufs *after* setting the MTU */
- mbuf_init();
-
- /* set default addresses */
- inet_aton("127.0.0.1", &loopback_addr);
-
- if (dns_addr_count == 0) {
- if (slirp_get_system_dns_servers() < 0) {
- dns_addr[0] = loopback_addr;
- dns_addr_count = 1;
- fprintf (stderr, "Warning: No DNS servers found\n");
- }
- }
-
- inet_aton(CTL_SPECIAL, &special_addr);
- alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
- getouraddr();
-
- slirp_init_shapers();
-}
-
-#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
-
-/*
- * curtime kept to an accuracy of 1ms
- */
-#ifdef _WIN32
-static void updtime(void)
-{
- struct _timeb tb;
-
- _ftime(&tb);
- curtime = (u_int)tb.time * (u_int)1000;
- curtime += (u_int)tb.millitm;
-}
-#else
-static void updtime(void)
-{
- gettimeofday(&tt, 0);
-
- curtime = (u_int)tt.tv_sec * (u_int)1000;
- curtime += (u_int)tt.tv_usec / (u_int)1000;
-
- if ((tt.tv_usec % 1000) >= 500)
- curtime++;
-}
-#endif
-
-void slirp_select_fill(int *pnfds,
- fd_set *readfds, fd_set *writefds, fd_set *xfds)
-{
- struct socket *so, *so_next;
- struct timeval timeout;
- int nfds;
- int tmp_time;
-
- /* fail safe */
- global_readfds = NULL;
- global_writefds = NULL;
- global_xfds = NULL;
-
- nfds = *pnfds;
- /*
- * First, TCP sockets
- */
- do_slowtimo = 0;
- if (link_up) {
- /*
- * *_slowtimo needs calling if there are IP fragments
- * in the fragment queue, or there are TCP connections active
- */
- do_slowtimo = ((tcb.so_next != &tcb) ||
- ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
-
- for (so = tcb.so_next; so != &tcb; so = so_next) {
- so_next = so->so_next;
-
- /*
- * See if we need a tcp_fasttimo
- */
- if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
- time_fasttimo = curtime; /* Flag when we want a fasttimo */
-
- /*
- * NOFDREF can include still connecting to local-host,
- * newly socreated() sockets etc. Don't want to select these.
- */
- if (so->so_state & SS_NOFDREF || so->s == -1)
- continue;
-
- /*
- * don't register proxified socked connections here
- */
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- /*
- * Set for reading sockets which are accepting
- */
- if (so->so_state & SS_FACCEPTCONN) {
- FD_SET(so->s, readfds);
- UPD_NFDS(so->s);
- continue;
- }
-
- /*
- * Set for writing sockets which are connecting
- */
- if (so->so_state & SS_ISFCONNECTING) {
- FD_SET(so->s, writefds);
- UPD_NFDS(so->s);
- continue;
- }
-
- /*
- * Set for writing if we are connected, can send more, and
- * we have something to send
- */
- if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
- FD_SET(so->s, writefds);
- UPD_NFDS(so->s);
- }
-
- /*
- * Set for reading (and urgent data) if we are connected, can
- * receive more, and we have room for it XXX /2 ?
- */
- if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
- FD_SET(so->s, readfds);
- FD_SET(so->s, xfds);
- UPD_NFDS(so->s);
- }
- }
-
- /*
- * UDP sockets
- */
- for (so = udb.so_next; so != &udb; so = so_next) {
- so_next = so->so_next;
-
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- /*
- * See if it's timed out
- */
- if (so->so_expire) {
- if (so->so_expire <= curtime) {
- udp_detach(so);
- continue;
- } else
- do_slowtimo = 1; /* Let socket expire */
- }
-
- /*
- * When UDP packets are received from over the
- * link, they're sendto()'d straight away, so
- * no need for setting for writing
- * Limit the number of packets queued by this session
- * to 4. Note that even though we try and limit this
- * to 4 packets, the session could have more queued
- * if the packets needed to be fragmented
- * (XXX <= 4 ?)
- */
- if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
- FD_SET(so->s, readfds);
- UPD_NFDS(so->s);
- }
- }
- }
-
- /*
- * Setup timeout to use minimum CPU usage, especially when idle
- */
-
- /*
- * First, see the timeout needed by *timo
- */
- timeout.tv_sec = 0;
- timeout.tv_usec = -1;
- /*
- * If a slowtimo is needed, set timeout to 500ms from the last
- * slow timeout. If a fast timeout is needed, set timeout within
- * 200ms of when it was requested.
- */
- if (do_slowtimo) {
- /* XXX + 10000 because some select()'s aren't that accurate */
- timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
- if (timeout.tv_usec < 0)
- timeout.tv_usec = 0;
- else if (timeout.tv_usec > 510000)
- timeout.tv_usec = 510000;
-
- /* Can only fasttimo if we also slowtimo */
- if (time_fasttimo) {
- tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
- if (tmp_time < 0)
- tmp_time = 0;
-
- /* Choose the smallest of the 2 */
- if (tmp_time < timeout.tv_usec)
- timeout.tv_usec = (u_int)tmp_time;
- }
- }
-
- /*
- * now, the proxified sockets
- */
- proxy_manager_select_fill(&nfds, readfds, writefds, xfds);
-
- *pnfds = nfds;
-}
-
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
-{
- struct socket *so, *so_next;
- int ret;
-
- global_readfds = readfds;
- global_writefds = writefds;
- global_xfds = xfds;
-
- /* Update time */
- updtime();
-
- /*
- * See if anything has timed out
- */
- if (link_up) {
- if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
- tcp_fasttimo();
- time_fasttimo = 0;
- }
- if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
- ip_slowtimo();
- tcp_slowtimo();
- last_slowtimo = curtime;
- }
- }
-
- /*
- * Check sockets
- */
- if (link_up) {
- /*
- * Check TCP sockets
- */
- for (so = tcb.so_next; so != &tcb; so = so_next) {
- so_next = so->so_next;
-
- /*
- * FD_ISSET is meaningless on these sockets
- * (and they can crash the program)
- */
- if (so->so_state & SS_NOFDREF || so->s == -1)
- continue;
-
- /*
- * proxified sockets are polled later in this
- * function.
- */
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- /*
- * Check for URG data
- * This will soread as well, so no need to
- * test for readfds below if this succeeds
- */
- if (FD_ISSET(so->s, xfds))
- sorecvoob(so);
- /*
- * Check sockets for reading
- */
- else if (FD_ISSET(so->s, readfds)) {
- /*
- * Check for incoming connections
- */
- if (so->so_state & SS_FACCEPTCONN) {
- tcp_connect(so);
- continue;
- } /* else */
- ret = soread(so);
-
- /* Output it if we read something */
- if (ret > 0)
- tcp_output(sototcpcb(so));
- }
-
- /*
- * Check sockets for writing
- */
- if (FD_ISSET(so->s, writefds)) {
- /*
- * Check for non-blocking, still-connecting sockets
- */
- if (so->so_state & SS_ISFCONNECTING) {
- /* Connected */
- so->so_state &= ~SS_ISFCONNECTING;
-
- ret = send(so->s, (char*)&ret, 0, 0);
- if (ret < 0) {
- /* XXXXX Must fix, zero bytes is a NOP */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN)
- continue;
-
- /* else failed */
- so->so_state = SS_NOFDREF;
- }
- /* else so->so_state &= ~SS_ISFCONNECTING; */
-
- /*
- * Continue tcp_input
- */
- tcp_input((MBuf )NULL, sizeof(struct ip), so);
- /* continue; */
- } else
- ret = sowrite(so);
- /*
- * XXXXX If we wrote something (a lot), there
- * could be a need for a window update.
- * In the worst case, the remote will send
- * a window probe to get things going again
- */
- }
-
- /*
- * Probe a still-connecting, non-blocking socket
- * to check if it's still alive
- */
-#ifdef PROBE_CONN
- if (so->so_state & SS_ISFCONNECTING) {
- ret = recv(so->s, (char *)&ret, 0,0);
-
- if (ret < 0) {
- /* XXX */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN)
- continue; /* Still connecting, continue */
-
- /* else failed */
- so->so_state = SS_NOFDREF;
-
- /* tcp_input will take care of it */
- } else {
- ret = send(so->s, &ret, 0,0);
- if (ret < 0) {
- /* XXX */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN)
- continue;
- /* else failed */
- so->so_state = SS_NOFDREF;
- } else
- so->so_state &= ~SS_ISFCONNECTING;
-
- }
- tcp_input((MBuf )NULL, sizeof(struct ip),so);
- } /* SS_ISFCONNECTING */
-#endif
- }
-
- /*
- * Now UDP sockets.
- * Incoming packets are sent straight away, they're not buffered.
- * Incoming UDP data isn't buffered either.
- */
- for (so = udb.so_next; so != &udb; so = so_next) {
- so_next = so->so_next;
-
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- if (so->s != -1 && FD_ISSET(so->s, readfds)) {
- sorecvfrom(so);
- }
- }
- }
-
- /*
- * Now the proxified sockets
- */
- proxy_manager_poll(readfds, writefds, xfds);
-
- /*
- * See if we can start outputting
- */
- if (if_queued && link_up)
- if_start();
-
- /* clear global file descriptor sets.
- * these reside on the stack in vl.c
- * so they're unusable if we're not in
- * slirp_select_fill or slirp_select_poll.
- */
- global_readfds = NULL;
- global_writefds = NULL;
- global_xfds = NULL;
-}
-
-#define ETH_ALEN 6
-#define ETH_HLEN 14
-
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
-
-#define ARPOP_REQUEST 1 /* ARP request */
-#define ARPOP_REPLY 2 /* ARP reply */
-
-struct ethhdr
-{
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
-};
-
-struct arphdr
-{
- unsigned short ar_hrd; /* format of hardware address */
- unsigned short ar_pro; /* format of protocol address */
- unsigned char ar_hln; /* length of hardware address */
- unsigned char ar_pln; /* length of protocol address */
- unsigned short ar_op; /* ARP opcode (command) */
-
- /*
- * Ethernet looks like this : This bit is variable sized however...
- */
- unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
- unsigned char ar_sip[4]; /* sender IP address */
- unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
- unsigned char ar_tip[4]; /* target IP address */
-};
-
-void arp_input(const uint8_t *pkt, int pkt_len)
-{
- struct ethhdr *eh = (struct ethhdr *)pkt;
- struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
- uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
- struct ethhdr *reh = (struct ethhdr *)arp_reply;
- struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
- int ar_op;
-
- ar_op = ntohs(ah->ar_op);
- switch(ar_op) {
- case ARPOP_REQUEST:
- if (!memcmp(ah->ar_tip, &special_addr, 3)) {
- if ( CTL_IS_DNS(ah->ar_tip[3]) || ah->ar_tip[3] == CTL_ALIAS)
- goto arp_ok;
- return;
- arp_ok:
- /* XXX: make an ARP request to have the client address */
- memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
-
- /* ARP request for alias/dns mac address */
- memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
- memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
- reh->h_source[5] = ah->ar_tip[3];
- reh->h_proto = htons(ETH_P_ARP);
-
- rah->ar_hrd = htons(1);
- rah->ar_pro = htons(ETH_P_IP);
- rah->ar_hln = ETH_ALEN;
- rah->ar_pln = 4;
- rah->ar_op = htons(ARPOP_REPLY);
- memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
- memcpy(rah->ar_sip, ah->ar_tip, 4);
- memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
- memcpy(rah->ar_tip, ah->ar_sip, 4);
- slirp_output(arp_reply, sizeof(arp_reply));
- }
- break;
- default:
- break;
- }
-}
-
-void slirp_input(const uint8_t *pkt, int pkt_len)
-{
- MBuf m;
- int proto;
-
- if (pkt_len < ETH_HLEN)
- return;
-
- proto = ntohs(*(uint16_t *)(pkt + 12));
- switch(proto) {
- case ETH_P_ARP:
- arp_input(pkt, pkt_len);
- break;
- case ETH_P_IP:
- m = mbuf_alloc();
- if (!m)
- return;
- /* Note: we add to align the IP header */
- m->m_len = pkt_len + 2;
- memcpy(m->m_data + 2, pkt, pkt_len);
-
- m->m_data += 2 + ETH_HLEN;
- m->m_len -= 2 + ETH_HLEN;
-
- ip_input(m);
- break;
- default:
- break;
- }
-}
-
-/* output the IP packet to the ethernet device */
-void if_encap(const uint8_t *ip_data, int ip_data_len)
-{
- uint8_t buf[1600];
- struct ethhdr *eh = (struct ethhdr *)buf;
-
- if (ip_data_len + ETH_HLEN > sizeof(buf))
- return;
-
- memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
- memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
- /* XXX: not correct */
- eh->h_source[5] = CTL_ALIAS;
- eh->h_proto = htons(ETH_P_IP);
- memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
- slirp_output(buf, ip_data_len + ETH_HLEN);
-}
-
-int slirp_redir(int is_udp, int host_port,
- struct in_addr guest_addr, int guest_port)
-{
- if (is_udp) {
- if (!udp_listen(htons(host_port), guest_addr.s_addr,
- htons(guest_port), 0))
- return -1;
- } else {
- if (!solisten(htons(host_port), guest_addr.s_addr,
- htons(guest_port), 0))
- return -1;
- }
- return 0;
-}
-
-int slirp_unredir(int is_udp, int host_port)
-{
- if (is_udp)
- return udp_unlisten( host_port );
- else
- return sounlisten( host_port );
-}
-
diff --git a/slirp/slirp.h b/slirp/slirp.h
deleted file mode 100644
index 50c0a77..0000000
--- a/slirp/slirp.h
+++ /dev/null
@@ -1,339 +0,0 @@
-#ifndef __COMMON_H__
-#define __COMMON_H__
-
-#define CONFIG_QEMU
-
-#define DEBUG 1
-
-#ifndef CONFIG_QEMU
-#include "version.h"
-#endif
-#include "config.h"
-#include "slirp_config.h"
-
-#ifdef _WIN32
-# include <inttypes.h>
-
-typedef uint8_t u_int8_t;
-typedef uint16_t u_int16_t;
-typedef uint32_t u_int32_t;
-typedef uint64_t u_int64_t;
-typedef char *caddr_t;
-
-# include <windows.h>
-# include <winsock2.h>
-# include <sys/timeb.h>
-# include <iphlpapi.h>
-
-# define EWOULDBLOCK WSAEWOULDBLOCK
-# define EINPROGRESS WSAEINPROGRESS
-# define ENOTCONN WSAENOTCONN
-# define EHOSTUNREACH WSAEHOSTUNREACH
-# define ENETUNREACH WSAENETUNREACH
-# define ECONNREFUSED WSAECONNREFUSED
-#else
-# define ioctlsocket ioctl
-# define closesocket(s) close(s)
-# define O_BINARY 0
-#endif
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_BITYPES_H
-# include <sys/bitypes.h>
-#endif
-
-#include <sys/time.h>
-
-#ifdef NEED_TYPEDEFS
-typedef char int8_t;
-typedef unsigned char u_int8_t;
-
-# if SIZEOF_SHORT == 2
- typedef short int16_t;
- typedef unsigned short u_int16_t;
-# else
-# if SIZEOF_INT == 2
- typedef int int16_t;
- typedef unsigned int u_int16_t;
-# else
- #error Cannot find a type with sizeof() == 2
-# endif
-# endif
-
-# if SIZEOF_SHORT == 4
- typedef short int32_t;
- typedef unsigned short u_int32_t;
-# else
-# if SIZEOF_INT == 4
- typedef int int32_t;
- typedef unsigned int u_int32_t;
-# else
- #error Cannot find a type with sizeof() == 4
-# endif
-# endif
-#endif /* NEED_TYPEDEFS */
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef HAVE_MEMMOVE
-#define memmove(x, y, z) bcopy(y, x, z)
-#endif
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/uio.h>
-#endif
-
-#ifndef _P
-#ifndef NO_PROTOTYPES
-# define _P(x) x
-#else
-# define _P(x) ()
-#endif
-#endif
-
-#ifndef _WIN32
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-
-#ifdef GETTIMEOFDAY_ONE_ARG
-#define gettimeofday(x, y) gettimeofday(x)
-#endif
-
-/* Systems lacking strdup() definition in <string.h>. */
-#if defined(ultrix)
-char *strdup _P((const char *));
-#endif
-
-/* Systems lacking malloc() definition in <stdlib.h>. */
-#if defined(ultrix) || defined(hcx)
-void *malloc _P((size_t arg));
-void free _P((void *ptr));
-#endif
-
-#ifndef HAVE_INET_ATON
-int inet_aton _P((const char *cp, struct in_addr *ia));
-#endif
-
-#include <fcntl.h>
-#ifndef NO_UNIX_SOCKETS
-#include <sys/un.h>
-#endif
-#include <signal.h>
-#ifdef HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif
-#ifndef _WIN32
-#include <sys/socket.h>
-#endif
-
-#if defined(HAVE_SYS_IOCTL_H)
-# include <sys/ioctl.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-# include <sys/filio.h>
-#endif
-
-#ifdef USE_PPP
-#include <ppp/slirppp.h>
-#endif
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#include <sys/stat.h>
-
-/* Avoid conflicting with the libc insque() and remque(), which
- have different prototypes. */
-#define insque slirp_insque
-#define remque slirp_remque
-
-#ifdef HAVE_SYS_STROPTS_H
-#include <sys/stropts.h>
-#endif
-
-#include "debug.h"
-
-#include "ip.h"
-#include "tcp.h"
-#include "tcp_timer.h"
-#include "tcp_var.h"
-#include "tcpip.h"
-#include "udp.h"
-#include "icmp_var.h"
-#include "mbuf.h"
-#include "sbuf.h"
-#include "socket.h"
-#include "if.h"
-#include "main.h"
-#include "misc.h"
-#include "ctl.h"
-#ifdef USE_PPP
-#include "ppp/pppd.h"
-#include "ppp/ppp.h"
-#endif
-
-#include "bootp.h"
-#include "tftp.h"
-#include "libslirp.h"
-
-extern struct ttys *ttys_unit[MAX_INTERFACES];
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-#ifndef FULL_BOLT
-void if_start _P((void));
-#else
-void if_start _P((struct ttys *));
-#endif
-
-#ifdef BAD_SPRINTF
-# define vsprintf vsprintf_len
-# define sprintf sprintf_len
- extern int vsprintf_len _P((char *, const char *, va_list));
- extern int sprintf_len _P((char *, const char *, ...));
-#endif
-
-#ifdef DECLARE_SPRINTF
-# ifndef BAD_SPRINTF
- extern int vsprintf _P((char *, const char *, va_list));
-# endif
- extern int vfprintf _P((FILE *, const char *, va_list));
-#endif
-
-#ifndef HAVE_STRERROR
- extern char *strerror _P((int error));
-#endif
-
-#ifndef HAVE_INDEX
- char *index _P((const char *, int));
-#endif
-
-#ifndef HAVE_GETHOSTID
- long gethostid _P((void));
-#endif
-
-void lprint _P((const char *, ...));
-
-extern int do_echo;
-
-#if SIZEOF_CHAR_P == 4
-# define insque_32 insque
-# define remque_32 remque
-#else
- inline void insque_32 _P((void *, void *));
- inline void remque_32 _P((void *));
-#endif
-
-#ifndef _WIN32
-#include <netdb.h>
-#endif
-
-#define DEFAULT_BAUD 115200
-
-/* cksum.c */
-int cksum(MBuf m, int len);
-
-/* if.c */
-void if_init _P((void));
-void if_output _P((struct socket *, MBuf ));
-
-/* ip_input.c */
-void ip_init _P((void));
-void ip_input _P((MBuf ));
-struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *));
-void ip_freef _P((struct ipq *));
-void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *));
-void ip_deq _P((register struct ipasfrag *));
-void ip_slowtimo _P((void));
-void ip_stripoptions _P((register MBuf , MBuf ));
-
-/* ip_output.c */
-int ip_output _P((struct socket *, MBuf ));
-
-/* tcp_input.c */
-int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, MBuf ));
-void tcp_input _P((register MBuf , int, struct socket *));
-void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *));
-void tcp_xmit_timer _P((register struct tcpcb *, int));
-int tcp_mss _P((register struct tcpcb *, u_int));
-
-/* tcp_output.c */
-int tcp_output _P((register struct tcpcb *));
-void tcp_setpersist _P((register struct tcpcb *));
-
-/* tcp_subr.c */
-void tcp_init _P((void));
-void tcp_template _P((struct tcpcb *));
-void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register MBuf , tcp_seq, tcp_seq, int));
-struct tcpcb * tcp_newtcpcb _P((struct socket *));
-struct tcpcb * tcp_close _P((register struct tcpcb *));
-void tcp_drain _P((void));
-void tcp_sockclosed _P((struct tcpcb *));
-int tcp_fconnect _P((struct socket *));
-void tcp_connect _P((struct socket *));
-int tcp_attach _P((struct socket *));
-u_int8_t tcp_tos _P((struct socket *));
-int tcp_emu _P((struct socket *, MBuf ));
-int tcp_ctl _P((struct socket *));
-struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
-
-#ifdef USE_PPP
-#define MIN_MRU MINMRU
-#define MAX_MRU MAXMRU
-#else
-#define MIN_MRU 128
-#define MAX_MRU 16384
-#endif
-
-#ifndef _WIN32
-#define min(x,y) ((x) < (y) ? (x) : (y))
-#define max(x,y) ((x) > (y) ? (x) : (y))
-#endif
-
-#ifdef _WIN32
-#undef errno
-#define errno (WSAGetLastError())
-#endif
-
-#endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
deleted file mode 100644
index e7e95dd..0000000
--- a/slirp/slirp_config.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * User definable configuration options
- */
-
-/* Undefine if you don't want talk emulation */
-#undef EMULATE_TALK
-
-/* Define if you want the connection to be probed */
-/* XXX Not working yet, so ignore this for now */
-#undef PROBE_CONN
-
-/* Define to 1 if you want KEEPALIVE timers */
-#define DO_KEEPALIVE 0
-
-/* Define to MAX interfaces you expect to use at once */
-/* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */
-/* MAX_PPP_INTERFACES determines max. number of PPP interfaces */
-#define MAX_INTERFACES 1
-#define MAX_PPP_INTERFACES 1
-
-/* Define if you want slirp's socket in /tmp */
-/* XXXXXX Do this in ./configure */
-#undef USE_TMPSOCKET
-
-/* Define if you want slirp to use cfsetXspeed() on the terminal */
-#undef DO_CFSETSPEED
-
-/* Define this if you want slirp to write to the tty as fast as it can */
-/* This should only be set if you are using load-balancing, slirp does a */
-/* pretty good job on single modems already, and seting this will make */
-/* interactive sessions less responsive */
-/* XXXXX Talk about having fast modem as unit 0 */
-#undef FULL_BOLT
-
-/*
- * Define if you want slirp to use less CPU
- * You will notice a small lag in interactive sessions, but it's not that bad
- * Things like Netscape/ftp/etc. are completely unaffected
- * This is mainly for sysadmins who have many slirp users
- */
-#undef USE_LOWCPU
-
-/* Define this if your compiler doesn't like prototypes */
-#ifndef __STDC__
-#define NO_PROTOTYPES
-#endif
-
-/*********************************************************/
-/*
- * Autoconf defined configuration options
- * You shouldn't need to touch any of these
- */
-
-/* Ignore this */
-#undef DUMMY_PPP
-
-/* Define if you have unistd.h */
-#define HAVE_UNISTD_H
-
-/* Define if you have stdlib.h */
-#define HAVE_STDLIB_H
-
-/* Define if you have sys/ioctl.h */
-#undef HAVE_SYS_IOCTL_H
-#ifndef _WIN32
-#define HAVE_SYS_IOCTL_H
-#endif
-
-/* Define if you have sys/filio.h */
-#undef HAVE_SYS_FILIO_H
-#ifdef __APPLE__
-#define HAVE_SYS_FILIO_H
-#endif
-
-/* Define if you have strerror */
-#define HAVE_STRERROR
-
-/* Define if you have strdup() */
-#define HAVE_STRDUP
-
-/* Define according to how time.h should be included */
-#define TIME_WITH_SYS_TIME 0
-#undef HAVE_SYS_TIME_H
-
-/* Define if you have sys/bitypes.h */
-#undef HAVE_SYS_BITYPES_H
-
-/* Define if the machine is big endian */
-//#undef WORDS_BIGENDIAN
-
-/* Define if your sprintf returns char * instead of int */
-#undef BAD_SPRINTF
-
-/* Define if you have readv */
-#undef HAVE_READV
-
-/* Define if iovec needs to be declared */
-#undef DECLARE_IOVEC
-#ifdef _WIN32
-#define DECLARE_IOVEC
-#endif
-
-/* Define if a declaration of sprintf/fprintf is needed */
-#undef DECLARE_SPRINTF
-
-/* Define if you have a POSIX.1 sys/wait.h */
-#undef HAVE_SYS_WAIT_H
-
-/* Define if you have sys/select.h */
-#undef HAVE_SYS_SELECT_H
-#ifndef _WIN32
-#define HAVE_SYS_SELECT_H
-#endif
-
-/* Define if you have strings.h */
-#define HAVE_STRING_H
-
-/* Define if you have arpa/inet.h */
-#undef HAVE_ARPA_INET_H
-#ifndef _WIN32
-#define HAVE_ARPA_INET_H
-#endif
-
-/* Define if you have sys/signal.h */
-#undef HAVE_SYS_SIGNAL_H
-
-/* Define if you have sys/stropts.h */
-#undef HAVE_SYS_STROPTS_H
-
-/* Define to whatever your compiler thinks inline should be */
-#define inline inline
-
-/* Define to whatever your compiler thinks const should be */
-#define const const
-
-/* Define if your compiler doesn't like prototypes */
-#undef NO_PROTOTYPES
-
-/* Define if you don't have u_int32_t etc. typedef'd */
-#undef NEED_TYPEDEFS
-#ifdef __sun__
-#define NEED_TYPEDEFS
-#endif
-
-/* Define to sizeof(char) */
-#define SIZEOF_CHAR 1
-
-/* Define to sizeof(short) */
-#define SIZEOF_SHORT 2
-
-/* Define to sizeof(int) */
-#define SIZEOF_INT 4
-
-/* Define to sizeof(char *) */
-#define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
-
-/* Define if you have random() */
-#undef HAVE_RANDOM
-
-/* Define if you have srandom() */
-#undef HAVE_SRANDOM
-
-/* Define if you have inet_aton */
-#undef HAVE_INET_ATON
-#ifndef _WIN32
-#define HAVE_INET_ATON
-#endif
-
-/* Define if you have setenv */
-#undef HAVE_SETENV
-
-/* Define if you have index() */
-#undef HAVE_INDEX
-
-/* Define if you have bcmp() */
-#undef HAVE_BCMP
-
-/* Define if you have drand48 */
-#undef HAVE_DRAND48
-
-/* Define if you have memmove */
-#define HAVE_MEMMOVE
-
-/* Define if you have gethostid */
-#undef HAVE_GETHOSTID
-
-/* Define if you DON'T have unix-domain sockets */
-#undef NO_UNIX_SOCKETS
-#ifdef _WIN32
-#define NO_UNIX_SOCKETS
-#endif
-
-/* Define if gettimeofday only takes one argument */
-#undef GETTIMEOFDAY_ONE_ARG
-
-/* Define if you have revoke() */
-#undef HAVE_REVOKE
-
-/* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */
-#undef HAVE_GRANTPT
-
-/* Define if you have fchmod */
-#undef HAVE_FCHMOD
-
-/* Define if you have <sys/type32.h> */
-#undef HAVE_SYS_TYPES32_H
diff --git a/slirp/socket.c b/slirp/socket.c
deleted file mode 100644
index bdae392..0000000
--- a/slirp/socket.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define WANT_SYS_IOCTL_H
-#include <slirp.h>
-#include "ip_icmp.h"
-#include "main.h"
-#ifdef __sun__
-#include <sys/filio.h>
-#endif
-#define SLIRP_COMPILATION
-#include "sockets.h"
-#include "proxy_common.h"
-
-void
-so_init()
-{
- /* Nothing yet */
-}
-
-
-struct socket *
-solookup(head, laddr, lport, faddr, fport)
- struct socket *head;
- struct in_addr laddr;
- u_int lport;
- struct in_addr faddr;
- u_int fport;
-{
- struct socket *so;
-
- for (so = head->so_next; so != head; so = so->so_next) {
- if (so->so_lport == lport &&
- so->so_laddr.s_addr == laddr.s_addr &&
- so->so_faddr.s_addr == faddr.s_addr &&
- so->so_fport == fport)
- break;
- }
-
- if (so == head)
- return (struct socket *)NULL;
- return so;
-
-}
-
-/*
- * Create a new socket, initialise the fields
- * It is the responsibility of the caller to
- * insque() it into the correct linked-list
- */
-struct socket *
-socreate()
-{
- struct socket *so;
-
- so = (struct socket *)malloc(sizeof(struct socket));
- if(so) {
- memset(so, 0, sizeof(struct socket));
- so->so_state = SS_NOFDREF;
- so->s = -1;
- }
- return(so);
-}
-
-/*
- * remque and free a socket, clobber cache
- */
-void
-sofree(so)
- struct socket *so;
-{
- if (so->so_state & SS_PROXIFIED)
- proxy_manager_del(so);
-
- if (so->extra) {
- sofree(so->extra);
- so->extra=NULL;
- }
- if (so == tcp_last_so)
- tcp_last_so = &tcb;
- else if (so == udp_last_so)
- udp_last_so = &udb;
-
- mbuf_free(so->so_m);
-
- if(so->so_next && so->so_prev)
- remque(so); /* crashes if so is not in a queue */
-
- free(so);
-}
-
-/*
- * Read from so's socket into sb_snd, updating all relevant sbuf fields
- * NOTE: This will only be called if it is select()ed for reading, so
- * a read() of 0 (or less) means it's disconnected
- */
-int
-soread(so)
- struct socket *so;
-{
- int n, nn, lss, total;
- SBuf sb = &so->so_snd;
- int len = sb->sb_datalen - sb->sb_cc;
- struct iovec iov[2];
- int mss = so->so_tcpcb->t_maxseg;
-
- DEBUG_CALL("soread");
- DEBUG_ARG("so = %lx", (long )so);
-
- /*
- * No need to check if there's enough room to read.
- * soread wouldn't have been called if there weren't
- */
-
- len = sb->sb_datalen - sb->sb_cc;
-
- iov[0].iov_base = sb->sb_wptr;
- if (sb->sb_wptr < sb->sb_rptr) {
- iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
- /* Should never succeed, but... */
- if (iov[0].iov_len > len)
- iov[0].iov_len = len;
- if (iov[0].iov_len > mss)
- iov[0].iov_len -= iov[0].iov_len%mss;
- n = 1;
- } else {
- iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
- /* Should never succeed, but... */
- if (iov[0].iov_len > len) iov[0].iov_len = len;
- len -= iov[0].iov_len;
- if (len) {
- iov[1].iov_base = sb->sb_data;
- iov[1].iov_len = sb->sb_rptr - sb->sb_data;
- if(iov[1].iov_len > len)
- iov[1].iov_len = len;
- total = iov[0].iov_len + iov[1].iov_len;
- if (total > mss) {
- lss = total%mss;
- if (iov[1].iov_len > lss) {
- iov[1].iov_len -= lss;
- n = 2;
- } else {
- lss -= iov[1].iov_len;
- iov[0].iov_len -= lss;
- n = 1;
- }
- } else
- n = 2;
- } else {
- if (iov[0].iov_len > mss)
- iov[0].iov_len -= iov[0].iov_len%mss;
- n = 1;
- }
- }
-
-#ifdef HAVE_READV
- nn = readv(so->s, (struct iovec *)iov, n);
- DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#else
- nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
-#endif
- if (nn <= 0) {
- if (nn < 0 && (errno == EINTR || errno == EAGAIN))
- return 0;
- else {
- DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
- sofcantrcvmore(so);
- tcp_sockclosed(sototcpcb(so));
- return -1;
- }
- }
-
-#ifndef HAVE_READV
- /*
- * If there was no error, try and read the second time round
- * We read again if n = 2 (ie, there's another part of the buffer)
- * and we read as much as we could in the first read
- * We don't test for <= 0 this time, because there legitimately
- * might not be any more data (since the socket is non-blocking),
- * a close will be detected on next iteration.
- * A return of -1 wont (shouldn't) happen, since it didn't happen above
- */
- if (n == 2 && nn == iov[0].iov_len) {
- int ret;
- ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
- if (ret > 0)
- nn += ret;
- }
-
- DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#endif
-
- /* Update fields */
- sb->sb_cc += nn;
- sb->sb_wptr += nn;
- if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
- sb->sb_wptr -= sb->sb_datalen;
- return nn;
-}
-
-/*
- * Get urgent data
- *
- * When the socket is created, we set it SO_OOBINLINE,
- * so when OOB data arrives, we soread() it and everything
- * in the send buffer is sent as urgent data
- */
-void
-sorecvoob(so)
- struct socket *so;
-{
- struct tcpcb *tp = sototcpcb(so);
-
- DEBUG_CALL("sorecvoob");
- DEBUG_ARG("so = %lx", (long)so);
-
- /*
- * We take a guess at how much urgent data has arrived.
- * In most situations, when urgent data arrives, the next
- * read() should get all the urgent data. This guess will
- * be wrong however if more data arrives just after the
- * urgent data, or the read() doesn't return all the
- * urgent data.
- */
- soread(so);
- tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
- tp->t_force = 1;
- tcp_output(tp);
- tp->t_force = 0;
-}
-
-/*
- * Send urgent data
- * There's a lot duplicated code here, but...
- */
-int
-sosendoob(so)
- struct socket *so;
-{
- SBuf sb = &so->so_rcv;
- char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
- int n, len;
-
- DEBUG_CALL("sosendoob");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
-
- if (so->so_urgc > 2048)
- so->so_urgc = 2048; /* XXXX */
-
- if (sb->sb_rptr < sb->sb_wptr) {
- /* We can send it directly */
- n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
- so->so_urgc -= n;
-
- DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
- } else {
- /*
- * Since there's no sendv or sendtov like writev,
- * we must copy all data to a linear buffer then
- * send it all
- */
- len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
- if (len > so->so_urgc) len = so->so_urgc;
- memcpy(buff, sb->sb_rptr, len);
- so->so_urgc -= len;
- if (so->so_urgc) {
- n = sb->sb_wptr - sb->sb_data;
- if (n > so->so_urgc) n = so->so_urgc;
- memcpy((buff + len), sb->sb_data, n);
- so->so_urgc -= n;
- len += n;
- }
- n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
-#ifdef DEBUG
- if (n != len)
- DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
-#endif
- DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
- }
-
- sb->sb_cc -= n;
- sb->sb_rptr += n;
- if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
- sb->sb_rptr -= sb->sb_datalen;
-
- return n;
-}
-
-/*
- * Write data from so_rcv to so's socket,
- * updating all sbuf field as necessary
- */
-int
-sowrite(so)
- struct socket *so;
-{
- int n,nn;
- SBuf sb = &so->so_rcv;
- int len = sb->sb_cc;
- struct iovec iov[2];
-
- DEBUG_CALL("sowrite");
- DEBUG_ARG("so = %lx", (long)so);
-
- if (so->so_urgc) {
- sosendoob(so);
- if (sb->sb_cc == 0)
- return 0;
- }
-
- /*
- * No need to check if there's something to write,
- * sowrite wouldn't have been called otherwise
- */
-
- len = sb->sb_cc;
-
- iov[0].iov_base = sb->sb_rptr;
- if (sb->sb_rptr < sb->sb_wptr) {
- iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
- /* Should never succeed, but... */
- if (iov[0].iov_len > len) iov[0].iov_len = len;
- n = 1;
- } else {
- iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
- if (iov[0].iov_len > len) iov[0].iov_len = len;
- len -= iov[0].iov_len;
- if (len) {
- iov[1].iov_base = sb->sb_data;
- iov[1].iov_len = sb->sb_wptr - sb->sb_data;
- if (iov[1].iov_len > len) iov[1].iov_len = len;
- n = 2;
- } else
- n = 1;
- }
- /* Check if there's urgent data to send, and if so, send it */
-
-#ifdef HAVE_READV
- nn = writev(so->s, (const struct iovec *)iov, n);
-
- DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
-#else
- nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
-#endif
- /* This should never happen, but people tell me it does *shrug* */
- if (nn < 0 && (errno == EAGAIN || errno == EINTR))
- return 0;
-
- if (nn <= 0) {
- DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
- so->so_state, errno));
- sofcantsendmore(so);
- tcp_sockclosed(sototcpcb(so));
- return -1;
- }
-
-#ifndef HAVE_READV
- if (n == 2 && nn == iov[0].iov_len) {
- int ret;
- ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
- if (ret > 0)
- nn += ret;
- }
- DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
-#endif
-
- /* Update sbuf */
- sb->sb_cc -= nn;
- sb->sb_rptr += nn;
- if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
- sb->sb_rptr -= sb->sb_datalen;
-
- /*
- * If in DRAIN mode, and there's no more data, set
- * it CANTSENDMORE
- */
- if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
- sofcantsendmore(so);
-
- return nn;
-}
-
-/*
- * recvfrom() a UDP socket
- */
-void
-sorecvfrom(so)
- struct socket *so;
-{
- struct sockaddr_in addr;
- int addrlen = sizeof(struct sockaddr_in);
-
- DEBUG_CALL("sorecvfrom");
- DEBUG_ARG("so = %lx", (long)so);
-
- if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
- char buff[256];
- int len;
-
- len = recvfrom(so->s, buff, 256, 0,
- (struct sockaddr *)&addr, &addrlen);
- /* XXX Check if reply is "correct"? */
-
- if(len == -1 || len == 0) {
- u_char code=ICMP_UNREACH_PORT;
-
- if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
- else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
-
- DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
- errno,strerror(errno)));
- icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
- } else {
- icmp_reflect(so->so_m);
- so->so_m = 0; /* Don't mbuf_free() it again! */
- }
- /* No need for this socket anymore, udp_detach it */
- udp_detach(so);
- } else { /* A "normal" UDP packet */
- MBuf m;
- int len, n;
-
- if (!(m = mbuf_alloc())) return;
- m->m_data += if_maxlinkhdr;
-
- /*
- * XXX Shouldn't FIONREAD packets destined for port 53,
- * but I don't know the max packet size for DNS lookups
- */
- len = mbuf_freeroom(m);
- /* if (so->so_fport != htons(53)) { */
- ioctlsocket(so->s, FIONREAD, &n);
-
- if (n > len) {
- n = (m->m_data - m->m_dat) + m->m_len + n + 1;
- mbuf_ensure(m, n);
- len = mbuf_freeroom(m);
- }
- /* } */
-
- m->m_len = recvfrom(so->s, m->m_data, len, 0,
- (struct sockaddr *)&addr, &addrlen);
- DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
- m->m_len, errno,strerror(errno)));
- if(m->m_len<0) {
- u_char code=ICMP_UNREACH_PORT;
-
- if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
- else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
-
- DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
- icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
- mbuf_free(m);
- } else {
- /*
- * Hack: domain name lookup will be used the most for UDP,
- * and since they'll only be used once there's no need
- * for the 4 minute (or whatever) timeout... So we time them
- * out much quicker (10 seconds for now...)
- */
- if (so->so_expire) {
- if (so->so_fport == htons(53))
- so->so_expire = curtime + SO_EXPIREFAST;
- else
- so->so_expire = curtime + SO_EXPIRE;
- }
-
- /* if (m->m_len == len) {
- * mbuf_ensure(m, MINCSIZE);
- * m->m_len = 0;
- * }
- */
-
- /*
- * If this packet was destined for CTL_ADDR,
- * make it look like that's where it came from, done by udp_output
- */
- udp_output(so, m, &addr);
- } /* rx error */
- } /* if ping packet */
-}
-
-/*
- * sendto() a socket
- */
-int
-sosendto(so, m)
- struct socket *so;
- MBuf m;
-{
- int ret;
- struct sockaddr_in addr;
-
- DEBUG_CALL("sosendto");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
-
- addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
- /* It's an alias */
- int low = ntohl(so->so_faddr.s_addr) & 0xff;
-
- if ( CTL_IS_DNS(low) )
- addr.sin_addr = dns_addr[low - CTL_DNS];
- else
- addr.sin_addr = loopback_addr;
- } else
- addr.sin_addr = so->so_faddr;
- addr.sin_port = so->so_fport;
-
- DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
-
- /* Don't care what port we get */
- ret = sendto(so->s, m->m_data, m->m_len, 0,
- (struct sockaddr *)&addr, sizeof (struct sockaddr));
- if (ret < 0)
- return -1;
-
- /*
- * Kill the socket if there's no reply in 4 minutes,
- * but only if it's an expirable socket
- */
- if (so->so_expire)
- so->so_expire = curtime + SO_EXPIRE;
- so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
- return 0;
-}
-
-/*
- * XXX This should really be tcp_listen
- */
-struct socket *
-solisten(port, laddr, lport, flags)
- u_int port;
- u_int32_t laddr;
- u_int lport;
- int flags;
-{
- struct sockaddr_in addr;
- struct socket *so;
- int s, addrlen = sizeof(addr);
-
- DEBUG_CALL("solisten");
- DEBUG_ARG("port = %d", port);
- DEBUG_ARG("laddr = %x", laddr);
- DEBUG_ARG("lport = %d", lport);
- DEBUG_ARG("flags = %x", flags);
-
- if ((so = socreate()) == NULL) {
- /* free(so); Not sofree() ??? free(NULL) == NOP */
- return NULL;
- }
-
- /* Don't tcp_attach... we don't need so_snd nor so_rcv */
- if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
- free(so);
- return NULL;
- }
- insque(so,&tcb);
-
- /*
- * SS_FACCEPTONCE sockets must time out.
- */
- if (flags & SS_FACCEPTONCE)
- so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
-
- so->so_state = (SS_FACCEPTCONN|flags);
- so->so_lport = lport; /* Kept in network format */
- so->so_hport = port;
- so->so_laddr.s_addr = laddr; /* Ditto */
-
- memset( &addr, 0, sizeof(addr) );
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr.sin_port = port;
-
- if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) {
- sofree(so);
- return NULL;
- }
-
- socket_set_xreuseaddr(s);
-
- if ((socket_set_xreuseaddr(s) < 0) ||
- (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
- (listen(s,1) < 0)) {
- int tmperrno = errno; /* Don't clobber the real reason we failed */
-
- close(s);
- sofree(so);
- /* Restore the real errno */
-#ifdef _WIN32
- WSASetLastError(tmperrno);
-#else
- errno = tmperrno;
-#endif
- return NULL;
- }
- socket_set_oobinline(s);
-
- getsockname(s,(struct sockaddr *)&addr,&addrlen);
- so->so_fport = addr.sin_port;
- if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
- so->so_faddr = alias_addr;
- else
- so->so_faddr = addr.sin_addr;
-
- so->s = s;
- return so;
-}
-
-
-int
-sounlisten(u_int port)
-{
- struct socket *so;
-
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
- if (so->so_hport == htons(port)) {
- break;
- }
- }
-
- if (so == &tcb) {
- return -1;
- }
-
- sofcantrcvmore( so );
- sofcantsendmore( so );
- close( so->s );
- so->s = -1;
- sofree( so );
- return 0;
-}
-
-
-/*
- * Data is available in so_rcv
- * Just write() the data to the socket
- * XXX not yet...
- */
-void
-sorwakeup(so)
- struct socket *so;
-{
-/* sowrite(so); */
-/* FD_CLR(so->s,&writefds); */
-}
-
-/*
- * Data has been freed in so_snd
- * We have room for a read() if we want to
- * For now, don't read, it'll be done in the main loop
- */
-void
-sowwakeup(so)
- struct socket *so;
-{
- /* Nothing, yet */
-}
-
-/*
- * Various session state calls
- * XXX Should be #define's
- * The socket state stuff needs work, these often get call 2 or 3
- * times each when only 1 was needed
- */
-void
-soisfconnecting(so)
- register struct socket *so;
-{
- so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
- SS_FCANTSENDMORE|SS_FWDRAIN);
- so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
-}
-
-void
-soisfconnected(so)
- register struct socket *so;
-{
- so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
- so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
-}
-
-void
-sofcantrcvmore(so)
- struct socket *so;
-{
- if ((so->so_state & SS_NOFDREF) == 0) {
- shutdown(so->s,0);
- if(global_writefds) {
- FD_CLR(so->s,global_writefds);
- }
- }
- so->so_state &= ~(SS_ISFCONNECTING);
- if (so->so_state & SS_FCANTSENDMORE)
- so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */
- else
- so->so_state |= SS_FCANTRCVMORE;
-}
-
-void
-sofcantsendmore(so)
- struct socket *so;
-{
- if ((so->so_state & SS_NOFDREF) == 0) {
- shutdown(so->s,1); /* send FIN to fhost */
- if (global_readfds) {
- FD_CLR(so->s,global_readfds);
- }
- if (global_xfds) {
- FD_CLR(so->s,global_xfds);
- }
- }
- so->so_state &= ~(SS_ISFCONNECTING);
- if (so->so_state & SS_FCANTRCVMORE)
- so->so_state = SS_NOFDREF; /* as above */
- else
- so->so_state |= SS_FCANTSENDMORE;
-}
-
-void
-soisfdisconnected(so)
- struct socket *so;
-{
-/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */
-/* close(so->s); */
-/* so->so_state = SS_ISFDISCONNECTED; */
- /*
- * XXX Do nothing ... ?
- */
-}
-
-/*
- * Set write drain mode
- * Set CANTSENDMORE once all data has been write()n
- */
-void
-sofwdrain(so)
- struct socket *so;
-{
- if (so->so_rcv.sb_cc)
- so->so_state |= SS_FWDRAIN;
- else
- sofcantsendmore(so);
-}
-
diff --git a/slirp/socket.h b/slirp/socket.h
deleted file mode 100644
index 54cb21c..0000000
--- a/slirp/socket.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-/* MINE */
-
-#ifndef _SLIRP_SOCKET_H_
-#define _SLIRP_SOCKET_H_
-
-#define SO_EXPIRE 240000
-#define SO_EXPIREFAST 10000
-
-/*
- * Our socket structure
- */
-
-struct socket {
- struct socket *so_next,*so_prev; /* For a linked list of sockets */
-
- int s; /* The actual socket */
-
- /* XXX union these with not-yet-used sbuf params */
- MBuf so_m; /* Pointer to the original SYN packet,
- * for non-blocking connect()'s, and
- * PING reply's */
- struct tcpiphdr *so_ti; /* Pointer to the original ti within
- * so_mconn, for non-blocking connections */
- int so_urgc;
- struct in_addr so_faddr; /* foreign host table entry */
- struct in_addr so_laddr; /* local host table entry */
- u_int16_t so_fport; /* foreign port */
- u_int16_t so_lport; /* local port */
- u_int16_t so_hport;
-
- u_int8_t so_iptos; /* Type of service */
- u_int8_t so_emu; /* Is the socket emulated? */
-
- u_char so_type; /* Type of socket, UDP or TCP */
- int so_state; /* internal state flags SS_*, below */
-
- struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */
- u_int so_expire; /* When the socket will expire */
-
- int so_queued; /* Number of packets queued from this socket */
- int so_nqueued; /* Number of packets queued in a row
- * Used to determine when to "downgrade" a session
- * from fastq to batchq */
-
- SBufRec so_rcv; /* Receive buffer */
- SBufRec so_snd; /* Send buffer */
- void * extra; /* Extra pointer */
-};
-
-
-/*
- * Socket state bits. (peer means the host on the Internet,
- * local host means the host on the other end of the modem)
- */
-#define SS_NOFDREF 0x001 /* No fd reference */
-
-#define SS_ISFCONNECTING 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */
-#define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */
-#define SS_FCANTRCVMORE 0x008 /* Socket can't receive more from peer (for half-closes) */
-#define SS_FCANTSENDMORE 0x010 /* Socket can't send more to peer (for half-closes) */
-/* #define SS_ISFDISCONNECTED 0x020*/ /* Socket has disconnected from peer, in 2MSL state */
-#define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */
-
-#define SS_CTL 0x080
-#define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */
-#define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */
-#define SS_PROXIFIED 0x400 /* Socket is trying to connect through a proxy, only makes sense
- when SS_ISFCONNECTING is also set */
-extern struct socket tcb;
-
-
-#if defined(DECLARE_IOVEC) && !defined(HAVE_READV)
-struct iovec {
- char *iov_base;
- size_t iov_len;
-};
-#endif
-
-void so_init _P((void));
-struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int));
-struct socket * socreate _P((void));
-void sofree _P((struct socket *));
-int soread _P((struct socket *));
-void sorecvoob _P((struct socket *));
-int sosendoob _P((struct socket *));
-int sowrite _P((struct socket *));
-void sorecvfrom _P((struct socket *));
-int sosendto _P((struct socket *, MBuf ));
-struct socket * solisten _P((u_int, u_int32_t, u_int, int));
-int sounlisten _P((u_int port));
-void sorwakeup _P((struct socket *));
-void sowwakeup _P((struct socket *));
-void soisfconnecting _P((register struct socket *));
-void soisfconnected _P((register struct socket *));
-void sofcantrcvmore _P((struct socket *));
-void sofcantsendmore _P((struct socket *));
-void soisfdisconnected _P((struct socket *));
-void sofwdrain _P((struct socket *));
-
-#endif /* _SOCKET_H_ */
diff --git a/slirp/tcp.h b/slirp/tcp.h
deleted file mode 100644
index 769f364..0000000
--- a/slirp/tcp.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp.h 8.1 (Berkeley) 6/10/93
- * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp
- */
-
-#ifndef _TCP_H_
-#define _TCP_H_
-
-typedef u_int32_t tcp_seq;
-
-#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */
-#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */
-
-extern int tcp_rcvspace;
-extern int tcp_sndspace;
-extern struct socket *tcp_last_so;
-
-#define TCP_SNDSPACE 8192
-#define TCP_RCVSPACE 8192
-
-/*
- * TCP header.
- * Per RFC 793, September, 1981.
- */
-struct tcphdr {
- u_int16_t th_sport; /* source port */
- u_int16_t th_dport; /* destination port */
- tcp_seq th_seq; /* sequence number */
- tcp_seq th_ack; /* acknowledgement number */
-#ifdef WORDS_BIGENDIAN
- u_int th_off:4, /* data offset */
- th_x2:4; /* (unused) */
-#else
- u_int th_x2:4, /* (unused) */
- th_off:4; /* data offset */
-#endif
- u_int8_t th_flags;
-#define TH_FIN 0x01
-#define TH_SYN 0x02
-#define TH_RST 0x04
-#define TH_PUSH 0x08
-#define TH_ACK 0x10
-#define TH_URG 0x20
- u_int16_t th_win; /* window */
- u_int16_t th_sum; /* checksum */
- u_int16_t th_urp; /* urgent pointer */
-};
-
-#include "tcp_var.h"
-
-#define TCPOPT_EOL 0
-#define TCPOPT_NOP 1
-#define TCPOPT_MAXSEG 2
-#define TCPOLEN_MAXSEG 4
-#define TCPOPT_WINDOW 3
-#define TCPOLEN_WINDOW 3
-#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
-#define TCPOLEN_SACK_PERMITTED 2
-#define TCPOPT_SACK 5 /* Experimental */
-#define TCPOPT_TIMESTAMP 8
-#define TCPOLEN_TIMESTAMP 10
-#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
-
-#define TCPOPT_TSTAMP_HDR \
- (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
-
-/*
- * Default maximum segment size for TCP.
- * With an IP MSS of 576, this is 536,
- * but 512 is probably more convenient.
- * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
- *
- * We make this 1460 because we only care about Ethernet in the qemu context.
- */
-#define TCP_MSS 1460
-
-#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
-
-#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
-
-/*
- * User-settable options (used with setsockopt).
- */
-#undef TCP_NODELAY
-#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
-#undef TCP_MAXSEG
-/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */
-
-/*
- * TCP FSM state definitions.
- * Per RFC793, September, 1981.
- */
-
-#define TCP_NSTATES 11
-
-#define TCPS_CLOSED 0 /* closed */
-#define TCPS_LISTEN 1 /* listening for connection */
-#define TCPS_SYN_SENT 2 /* active, have sent syn */
-#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
-/* states < TCPS_ESTABLISHED are those where connections not established */
-#define TCPS_ESTABLISHED 4 /* established */
-#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
-/* states > TCPS_CLOSE_WAIT are those where user has closed */
-#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
-#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
-#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
-/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
-#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
-#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
-
-#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED)
-#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
-#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT)
-
-/*
- * TCP sequence numbers are 32 bit integers operated
- * on with modular arithmetic. These macros can be
- * used to compare such integers.
- */
-#define SEQ_LT(a,b) ((int)((a)-(b)) < 0)
-#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
-#define SEQ_GT(a,b) ((int)((a)-(b)) > 0)
-#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0)
-
-/*
- * Macros to initialize tcp sequence numbers for
- * send and receive from initial send and receive
- * sequence numbers.
- */
-#define tcp_rcvseqinit(tp) \
- (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1
-
-#define tcp_sendseqinit(tp) \
- (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss
-
-#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */
-
-extern tcp_seq tcp_iss; /* tcp initial send seq # */
-
-extern char *tcpstates[];
-
-#endif
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
deleted file mode 100644
index 4621ca2..0000000
--- a/slirp/tcp_input.c
+++ /dev/null
@@ -1,1707 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94
- * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#include "ip_icmp.h"
-
-struct socket tcb;
-
-int tcprexmtthresh = 3;
-struct socket *tcp_last_so = &tcb;
-
-tcp_seq tcp_iss; /* tcp initial send seq # */
-
-#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
-
-/* for modulo comparisons of timestamps */
-#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
-#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
-
-/*
- * Insert segment ti into reassembly queue of tcp with
- * control block tp. Return TH_FIN if reassembly now includes
- * a segment with FIN. The macro form does the common case inline
- * (segment is the next to be received on an established connection,
- * and the queue is empty), avoiding linkage into and removal
- * from the queue and repetition of various conversions.
- * Set DELACK for segments received in order, but ack immediately
- * when segments are out of order (so fast retransmit can work).
- */
-#ifdef TCP_ACK_HACK
-#define TCP_REASS(tp, ti, m, so, flags) {\
- if ((ti)->ti_seq == (tp)->rcv_nxt && \
- (tp)->seg_next == (tcpiphdrp_32)(tp) && \
- (tp)->t_state == TCPS_ESTABLISHED) {\
- if (ti->ti_flags & TH_PUSH) \
- tp->t_flags |= TF_ACKNOW; \
- else \
- tp->t_flags |= TF_DELACK; \
- (tp)->rcv_nxt += (ti)->ti_len; \
- flags = (ti)->ti_flags & TH_FIN; \
- tcpstat.tcps_rcvpack++;\
- tcpstat.tcps_rcvbyte += (ti)->ti_len;\
- if (so->so_emu) { \
- if (tcp_emu((so),(m))) sbuf_append((so), (m)); \
- } else \
- sbuf_append((so), (m)); \
-/* sorwakeup(so); */ \
- } else {\
- (flags) = tcp_reass((tp), (ti), (m)); \
- tp->t_flags |= TF_ACKNOW; \
- } \
-}
-#else
-#define TCP_REASS(tp, ti, m, so, flags) { \
- if ((ti)->ti_seq == (tp)->rcv_nxt && \
- (tp)->seg_next == (tcpiphdrp_32)(tp) && \
- (tp)->t_state == TCPS_ESTABLISHED) { \
- tp->t_flags |= TF_DELACK; \
- (tp)->rcv_nxt += (ti)->ti_len; \
- flags = (ti)->ti_flags & TH_FIN; \
- tcpstat.tcps_rcvpack++;\
- tcpstat.tcps_rcvbyte += (ti)->ti_len;\
- if (so->so_emu) { \
- if (tcp_emu((so),(m))) sbuf_append(so, (m)); \
- } else \
- sbuf_append((so), (m)); \
-/* sorwakeup(so); */ \
- } else { \
- (flags) = tcp_reass((tp), (ti), (m)); \
- tp->t_flags |= TF_ACKNOW; \
- } \
-}
-#endif
-
-int
-tcp_reass(tp, ti, m)
- register struct tcpcb *tp;
- register struct tcpiphdr *ti;
- MBuf m;
-{
- register struct tcpiphdr *q;
- struct socket *so = tp->t_socket;
- int flags;
-
- /*
- * Call with ti==0 after become established to
- * force pre-ESTABLISHED data up to user socket.
- */
- if (ti == 0)
- goto present;
-
- /*
- * Find a segment which begins after this one does.
- */
- for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp;
- q = (struct tcpiphdr *)q->ti_next)
- if (SEQ_GT(q->ti_seq, ti->ti_seq))
- break;
-
- /*
- * If there is a preceding segment, it may provide some of
- * our data already. If so, drop the data from the incoming
- * segment. If it provides all of our data, drop us.
- */
- if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
- register int i;
- q = (struct tcpiphdr *)q->ti_prev;
- /* conversion to int (in i) handles seq wraparound */
- i = q->ti_seq + q->ti_len - ti->ti_seq;
- if (i > 0) {
- if (i >= ti->ti_len) {
- tcpstat.tcps_rcvduppack++;
- tcpstat.tcps_rcvdupbyte += ti->ti_len;
- mbuf_free(m);
- /*
- * Try to present any queued data
- * at the left window edge to the user.
- * This is needed after the 3-WHS
- * completes.
- */
- goto present; /* ??? */
- }
- mbuf_trim(m, i);
- ti->ti_len -= i;
- ti->ti_seq += i;
- }
- q = (struct tcpiphdr *)(q->ti_next);
- }
- tcpstat.tcps_rcvoopack++;
- tcpstat.tcps_rcvoobyte += ti->ti_len;
- REASS_MBUF(ti) = (mbufp_32) m; /* XXX */
-
- /*
- * While we overlap succeeding segments trim them or,
- * if they are completely covered, dequeue them.
- */
- while (q != (struct tcpiphdr *)tp) {
- register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
- if (i <= 0)
- break;
- if (i < q->ti_len) {
- q->ti_seq += i;
- q->ti_len -= i;
- mbuf_trim((MBuf ) REASS_MBUF(q), i);
- break;
- }
- q = (struct tcpiphdr *)q->ti_next;
- m = (MBuf ) REASS_MBUF((struct tcpiphdr *)q->ti_prev);
- remque_32((void *)(q->ti_prev));
- mbuf_free(m);
- }
-
- /*
- * Stick new segment in its place.
- */
- insque_32(ti, (void *)(q->ti_prev));
-
-present:
- /*
- * Present data to user, advancing rcv_nxt through
- * completed sequence space.
- */
- if (!TCPS_HAVEESTABLISHED(tp->t_state))
- return (0);
- ti = (struct tcpiphdr *) tp->seg_next;
- if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
- return (0);
- if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
- return (0);
- do {
- tp->rcv_nxt += ti->ti_len;
- flags = ti->ti_flags & TH_FIN;
- remque_32(ti);
- m = (MBuf ) REASS_MBUF(ti); /* XXX */
- ti = (struct tcpiphdr *)ti->ti_next;
-/* if (so->so_state & SS_FCANTRCVMORE) */
- if (so->so_state & SS_FCANTSENDMORE)
- mbuf_free(m);
- else {
- if (so->so_emu) {
- if (tcp_emu(so,m)) sbuf_append(so, m);
- } else
- sbuf_append(so, m);
- }
- } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);
-/* sorwakeup(so); */
- return (flags);
-}
-
-/*
- * TCP input routine, follows pages 65-76 of the
- * protocol specification dated September, 1981 very closely.
- */
-void
-tcp_input(m, iphlen, inso)
- register MBuf m;
- int iphlen;
- struct socket *inso;
-{
- struct ip save_ip, *ip;
- register struct tcpiphdr *ti;
- caddr_t optp = NULL;
- int optlen = 0;
- int len, tlen, off;
- register struct tcpcb *tp = 0;
- register int tiflags;
- struct socket *so = 0;
- int todrop, acked, ourfinisacked, needoutput = 0;
-/* int dropsocket = 0; */
- int iss = 0;
- u_long tiwin;
- int ret;
-/* int ts_present = 0; */
-
- DEBUG_CALL("tcp_input");
- DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
- (long )m, iphlen, (long )inso ));
-
- /*
- * If called with m == 0, then we're continuing the connect
- */
- if (m == NULL) {
- so = inso;
-
- /* Re-set a few variables */
- tp = sototcpcb(so);
- m = so->so_m;
- so->so_m = 0;
- ti = so->so_ti;
- tiwin = ti->ti_win;
- tiflags = ti->ti_flags;
-
- goto cont_conn;
- }
-
-
- tcpstat.tcps_rcvtotal++;
- /*
- * Get IP and TCP header together in first mbuf.
- * Note: IP leaves IP header in first mbuf.
- */
- ti = MBUF_TO(m, struct tcpiphdr *);
- if (iphlen > sizeof(struct ip )) {
- ip_stripoptions(m, (MBuf )0);
- iphlen=sizeof(struct ip );
- }
- /* XXX Check if too short */
-
-
- /*
- * Save a copy of the IP header in case we want restore it
- * for sending an ICMP error message in response.
- */
- ip=MBUF_TO(m, struct ip *);
- save_ip = *ip;
- save_ip.ip_len+= iphlen;
-
- /*
- * Checksum extended TCP header and data.
- */
- tlen = ((struct ip *)ti)->ip_len;
- ti->ti_next = ti->ti_prev = 0;
- ti->ti_x1 = 0;
- ti->ti_len = htons((u_int16_t)tlen);
- len = sizeof(struct ip ) + tlen;
- /* keep checksum for ICMP reply
- * ti->ti_sum = cksum(m, len);
- * if (ti->ti_sum) { */
- if(cksum(m, len)) {
- tcpstat.tcps_rcvbadsum++;
- goto drop;
- }
-
- /*
- * Check that TCP offset makes sense,
- * pull out TCP options and adjust length. XXX
- */
- off = ti->ti_off << 2;
- if (off < sizeof (struct tcphdr) || off > tlen) {
- tcpstat.tcps_rcvbadoff++;
- goto drop;
- }
- tlen -= off;
- ti->ti_len = tlen;
- if (off > sizeof (struct tcphdr)) {
- optlen = off - sizeof (struct tcphdr);
- optp = MBUF_TO(m, caddr_t) + sizeof (struct tcpiphdr);
-
- /*
- * Do quick retrieval of timestamp options ("options
- * prediction?"). If timestamp is the only option and it's
- * formatted as recommended in RFC 1323 appendix A, we
- * quickly get the values now and not bother calling
- * tcp_dooptions(), etc.
- */
-/* if ((optlen == TCPOLEN_TSTAMP_APPA ||
- * (optlen > TCPOLEN_TSTAMP_APPA &&
- * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
- * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
- * (ti->ti_flags & TH_SYN) == 0) {
- * ts_present = 1;
- * ts_val = ntohl(*(u_int32_t *)(optp + 4));
- * ts_ecr = ntohl(*(u_int32_t *)(optp + 8));
- * optp = NULL; / * we've parsed the options * /
- * }
- */
- }
- tiflags = ti->ti_flags;
-
- /*
- * Convert TCP protocol specific fields to host format.
- */
- NTOHL(ti->ti_seq);
- NTOHL(ti->ti_ack);
- NTOHS(ti->ti_win);
- NTOHS(ti->ti_urp);
-
- /*
- * Drop TCP, IP headers and TCP options.
- */
- m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
-
- /*
- * Locate pcb for segment.
- */
-findso:
- so = tcp_last_so;
- if (so->so_fport != ti->ti_dport ||
- so->so_lport != ti->ti_sport ||
- so->so_laddr.s_addr != ti->ti_src.s_addr ||
- so->so_faddr.s_addr != ti->ti_dst.s_addr) {
- so = solookup(&tcb, ti->ti_src, ti->ti_sport,
- ti->ti_dst, ti->ti_dport);
- if (so)
- tcp_last_so = so;
- ++tcpstat.tcps_socachemiss;
- }
-
- /*
- * If the state is CLOSED (i.e., TCB does not exist) then
- * all data in the incoming segment is discarded.
- * If the TCB exists but is in CLOSED state, it is embryonic,
- * but should either do a listen or a connect soon.
- *
- * state == CLOSED means we've done socreate() but haven't
- * attached it to a protocol yet...
- *
- * XXX If a TCB does not exist, and the TH_SYN flag is
- * the only flag set, then create a session, mark it
- * as if it was LISTENING, and continue...
- */
- if (so == 0) {
- if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
- goto dropwithreset;
-
- if ((so = socreate()) == NULL)
- goto dropwithreset;
- if (tcp_attach(so) < 0) {
- free(so); /* Not sofree (if it failed, it's not insqued) */
- goto dropwithreset;
- }
-
- sbuf_reserve(&so->so_snd, tcp_sndspace);
- sbuf_reserve(&so->so_rcv, tcp_rcvspace);
-
- /* tcp_last_so = so; */ /* XXX ? */
- /* tp = sototcpcb(so); */
-
- so->so_laddr = ti->ti_src;
- so->so_lport = ti->ti_sport;
- so->so_faddr = ti->ti_dst;
- so->so_fport = ti->ti_dport;
-
- if ((so->so_iptos = tcp_tos(so)) == 0)
- so->so_iptos = ((struct ip *)ti)->ip_tos;
-
- tp = sototcpcb(so);
- tp->t_state = TCPS_LISTEN;
- }
-
- /*
- * If this is a still-connecting socket, this probably
- * a retransmit of the SYN. Whether it's a retransmit SYN
- * or something else, we nuke it.
- */
- if (so->so_state & SS_ISFCONNECTING)
- goto drop;
-
- tp = sototcpcb(so);
-
- /* XXX Should never fail */
- if (tp == 0)
- goto dropwithreset;
- if (tp->t_state == TCPS_CLOSED)
- goto drop;
-
- /* Unscale the window into a 32-bit value. */
-/* if ((tiflags & TH_SYN) == 0)
- * tiwin = ti->ti_win << tp->snd_scale;
- * else
- */
- tiwin = ti->ti_win;
-
- /*
- * Segment received on connection.
- * Reset idle time and keep-alive timer.
- */
- tp->t_idle = 0;
- if (so_options)
- tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
- else
- tp->t_timer[TCPT_KEEP] = tcp_keepidle;
-
- /*
- * Process options if not in LISTEN state,
- * else do it below (after getting remote address).
- */
- if (optp && tp->t_state != TCPS_LISTEN)
- tcp_dooptions(tp, (u_char *)optp, optlen, ti);
-/* , */
-/* &ts_present, &ts_val, &ts_ecr); */
-
- /*
- * Header prediction: check for the two common cases
- * of a uni-directional data xfer. If the packet has
- * no control flags, is in-sequence, the window didn't
- * change and we're not retransmitting, it's a
- * candidate. If the length is zero and the ack moved
- * forward, we're the sender side of the xfer. Just
- * free the data acked & wake any higher level process
- * that was blocked waiting for space. If the length
- * is non-zero and the ack didn't move, we're the
- * receiver side. If we're getting packets in-order
- * (the reassembly queue is empty), add the data to
- * the socket buffer and note that we need a delayed ack.
- *
- * XXX Some of these tests are not needed
- * eg: the tiwin == tp->snd_wnd prevents many more
- * predictions.. with no *real* advantage..
- */
- if (tp->t_state == TCPS_ESTABLISHED &&
- (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
-/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */
- ti->ti_seq == tp->rcv_nxt &&
- tiwin && tiwin == tp->snd_wnd &&
- tp->snd_nxt == tp->snd_max) {
- /*
- * If last ACK falls within this segment's sequence numbers,
- * record the timestamp.
- */
-/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) &&
- * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) {
- * tp->ts_recent_age = tcp_now;
- * tp->ts_recent = ts_val;
- * }
- */
- if (ti->ti_len == 0) {
- if (SEQ_GT(ti->ti_ack, tp->snd_una) &&
- SEQ_LEQ(ti->ti_ack, tp->snd_max) &&
- tp->snd_cwnd >= tp->snd_wnd) {
- /*
- * this is a pure ack for outstanding data.
- */
- ++tcpstat.tcps_predack;
-/* if (ts_present)
- * tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
- * else
- */ if (tp->t_rtt &&
- SEQ_GT(ti->ti_ack, tp->t_rtseq))
- tcp_xmit_timer(tp, tp->t_rtt);
- acked = ti->ti_ack - tp->snd_una;
- tcpstat.tcps_rcvackpack++;
- tcpstat.tcps_rcvackbyte += acked;
- sbuf_drop(&so->so_snd, acked);
- tp->snd_una = ti->ti_ack;
- mbuf_free(m);
-
- /*
- * If all outstanding data are acked, stop
- * retransmit timer, otherwise restart timer
- * using current (possibly backed-off) value.
- * If process is waiting for space,
- * wakeup/selwakeup/signal. If data
- * are ready to send, let tcp_output
- * decide between more output or persist.
- */
- if (tp->snd_una == tp->snd_max)
- tp->t_timer[TCPT_REXMT] = 0;
- else if (tp->t_timer[TCPT_PERSIST] == 0)
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
-
- /*
- * There's room in so_snd, sowwakup will read()
- * from the socket if we can
- */
-/* if (so->so_snd.sb_flags & SB_NOTIFY)
- * sowwakeup(so);
- */
- /*
- * This is called because sowwakeup might have
- * put data into so_snd. Since we don't so sowwakeup,
- * we don't need this.. XXX???
- */
- if (so->so_snd.sb_cc)
- (void) tcp_output(tp);
-
- return;
- }
- } else if (ti->ti_ack == tp->snd_una &&
- tp->seg_next == (tcpiphdrp_32)tp &&
- ti->ti_len <= sbuf_space(&so->so_rcv)) {
- /*
- * this is a pure, in-sequence data packet
- * with nothing on the reassembly queue and
- * we have enough buffer space to take it.
- */
- ++tcpstat.tcps_preddat;
- tp->rcv_nxt += ti->ti_len;
- tcpstat.tcps_rcvpack++;
- tcpstat.tcps_rcvbyte += ti->ti_len;
- /*
- * Add data to socket buffer.
- */
- if (so->so_emu) {
- if (tcp_emu(so,m)) sbuf_append(so, m);
- } else
- sbuf_append(so, m);
-
- /*
- * XXX This is called when data arrives. Later, check
- * if we can actually write() to the socket
- * XXX Need to check? It's be NON_BLOCKING
- */
-/* sorwakeup(so); */
-
- /*
- * If this is a short packet, then ACK now - with Nagel
- * congestion avoidance sender won't send more until
- * he gets an ACK.
- *
- * It is better to not delay acks at all to maximize
- * TCP throughput. See RFC 2581.
- */
- tp->t_flags |= TF_ACKNOW;
- tcp_output(tp);
- return;
- }
- } /* header prediction */
- /*
- * Calculate amount of space in receive window,
- * and then do TCP input processing.
- * Receive window is amount of space in rcv queue,
- * but not less than advertised window.
- */
- { int win;
- win = sbuf_space(&so->so_rcv);
- if (win < 0)
- win = 0;
- tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt));
- }
-
- switch (tp->t_state) {
-
- /*
- * If the state is LISTEN then ignore segment if it contains an RST.
- * If the segment contains an ACK then it is bad and send a RST.
- * If it does not contain a SYN then it is not interesting; drop it.
- * Don't bother responding if the destination was a broadcast.
- * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
- * tp->iss, and send a segment:
- * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
- * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
- * Fill in remote peer address fields if not previously specified.
- * Enter SYN_RECEIVED state, and process any other fields of this
- * segment in this state.
- */
- case TCPS_LISTEN: {
-
- if (tiflags & TH_RST)
- goto drop;
- if (tiflags & TH_ACK)
- goto dropwithreset;
- if ((tiflags & TH_SYN) == 0)
- goto drop;
-
- /*
- * This has way too many gotos...
- * But a bit of spaghetti code never hurt anybody :)
- */
-
- /*
- * If this is destined for the control address, then flag to
- * tcp_ctl once connected, otherwise connect
- */
- if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) {
- int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff;
- /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */
- }
-
- if (so->so_emu & EMU_NOCONNECT) {
- so->so_emu &= ~EMU_NOCONNECT;
- goto cont_input;
- }
-
- if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
- u_char code=ICMP_UNREACH_NET;
- DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n",
- errno,strerror(errno)));
- if(errno == ECONNREFUSED) {
- /* ACK the SYN, send RST to refuse the connection */
- tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0,
- TH_RST|TH_ACK);
- } else {
- if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
- HTONL(ti->ti_seq); /* restore tcp header */
- HTONL(ti->ti_ack);
- HTONS(ti->ti_win);
- HTONS(ti->ti_urp);
- m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- *ip=save_ip;
- icmp_error(m, ICMP_UNREACH,code, 0,strerror(errno));
- }
- tp = tcp_close(tp);
- mbuf_free(m);
- } else {
- /*
- * Haven't connected yet, save the current mbuf
- * and ti, and return
- * XXX Some OS's don't tell us whether the connect()
- * succeeded or not. So we must time it out.
- */
- so->so_m = m;
- so->so_ti = ti;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->t_state = TCPS_SYN_RECEIVED;
- }
- return;
-
- cont_conn:
- /* m==NULL
- * Check if the connect succeeded
- */
- if (so->so_state & SS_NOFDREF) {
- DEBUG_MISC((dfd, " tcp_input closing connecting socket %lx\n", (long)so));
- tp = tcp_close(tp);
- goto dropwithreset;
- }
- cont_input:
- tcp_template(tp);
-
- if (optp)
- tcp_dooptions(tp, (u_char *)optp, optlen, ti);
- /* , */
- /* &ts_present, &ts_val, &ts_ecr); */
-
- if (iss)
- tp->iss = iss;
- else
- tp->iss = tcp_iss;
- tcp_iss += TCP_ISSINCR/2;
- tp->irs = ti->ti_seq;
- tcp_sendseqinit(tp);
- tcp_rcvseqinit(tp);
- tp->t_flags |= TF_ACKNOW;
- tp->t_state = TCPS_SYN_RECEIVED;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tcpstat.tcps_accepts++;
- DEBUG_MISC((dfd, " tcp_input accept connected socket %lx\n", (long)so));
- goto trimthenstep6;
- } /* case TCPS_LISTEN */
-
- /*
- * If the state is SYN_SENT:
- * if seg contains an ACK, but not for our SYN, drop the input.
- * if seg contains a RST, then drop the connection.
- * if seg does not contain SYN, then drop it.
- * Otherwise this is an acceptable SYN segment
- * initialize tp->rcv_nxt and tp->irs
- * if seg contains ack then advance tp->snd_una
- * if SYN has been acked change to ESTABLISHED else SYN_RCVD state
- * arrange for segment to be acked (eventually)
- * continue processing rest of data/controls, beginning with URG
- */
- case TCPS_SYN_SENT:
- if ((tiflags & TH_ACK) &&
- (SEQ_LEQ(ti->ti_ack, tp->iss) ||
- SEQ_GT(ti->ti_ack, tp->snd_max)))
- goto dropwithreset;
-
- if (tiflags & TH_RST) {
- if (tiflags & TH_ACK)
- tp = tcp_drop(tp,0); /* XXX Check t_softerror! */
- goto drop;
- }
-
- if ((tiflags & TH_SYN) == 0)
- goto drop;
- if (tiflags & TH_ACK) {
- tp->snd_una = ti->ti_ack;
- if (SEQ_LT(tp->snd_nxt, tp->snd_una))
- tp->snd_nxt = tp->snd_una;
- }
-
- tp->t_timer[TCPT_REXMT] = 0;
- tp->irs = ti->ti_seq;
- tcp_rcvseqinit(tp);
- tp->t_flags |= TF_ACKNOW;
- if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
- tcpstat.tcps_connects++;
- soisfconnected(so);
- tp->t_state = TCPS_ESTABLISHED;
-
- /* Do window scaling on this connection? */
-/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
- * (TF_RCVD_SCALE|TF_REQ_SCALE)) {
- * tp->snd_scale = tp->requested_s_scale;
- * tp->rcv_scale = tp->request_r_scale;
- * }
- */
- (void) tcp_reass(tp, (struct tcpiphdr *)0,
- (MBuf )0);
- /*
- * if we didn't have to retransmit the SYN,
- * use its rtt as our initial srtt & rtt var.
- */
- if (tp->t_rtt)
- tcp_xmit_timer(tp, tp->t_rtt);
- } else
- tp->t_state = TCPS_SYN_RECEIVED;
-
-trimthenstep6:
- /*
- * Advance ti->ti_seq to correspond to first data byte.
- * If data, trim to stay within window,
- * dropping FIN if necessary.
- */
- ti->ti_seq++;
- if (ti->ti_len > tp->rcv_wnd) {
- todrop = ti->ti_len - tp->rcv_wnd;
- mbuf_trim(m, -todrop);
- ti->ti_len = tp->rcv_wnd;
- tiflags &= ~TH_FIN;
- tcpstat.tcps_rcvpackafterwin++;
- tcpstat.tcps_rcvbyteafterwin += todrop;
- }
- tp->snd_wl1 = ti->ti_seq - 1;
- tp->rcv_up = ti->ti_seq;
- goto step6;
- } /* switch tp->t_state */
- /*
- * States other than LISTEN or SYN_SENT.
- * First check timestamp, if present.
- * Then check that at least some bytes of segment are within
- * receive window. If segment begins before rcv_nxt,
- * drop leading data (and SYN); if nothing left, just ack.
- *
- * RFC 1323 PAWS: If we have a timestamp reply on this segment
- * and it's less than ts_recent, drop it.
- */
-/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent &&
- * TSTMP_LT(ts_val, tp->ts_recent)) {
- *
- */ /* Check to see if ts_recent is over 24 days old. */
-/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
- */ /*
- * * Invalidate ts_recent. If this segment updates
- * * ts_recent, the age will be reset later and ts_recent
- * * will get a valid value. If it does not, setting
- * * ts_recent to zero will at least satisfy the
- * * requirement that zero be placed in the timestamp
- * * echo reply when ts_recent isn't valid. The
- * * age isn't reset until we get a valid ts_recent
- * * because we don't want out-of-order segments to be
- * * dropped when ts_recent is old.
- * */
-/* tp->ts_recent = 0;
- * } else {
- * tcpstat.tcps_rcvduppack++;
- * tcpstat.tcps_rcvdupbyte += ti->ti_len;
- * tcpstat.tcps_pawsdrop++;
- * goto dropafterack;
- * }
- * }
- */
-
- todrop = tp->rcv_nxt - ti->ti_seq;
- if (todrop > 0) {
- if (tiflags & TH_SYN) {
- tiflags &= ~TH_SYN;
- ti->ti_seq++;
- if (ti->ti_urp > 1)
- ti->ti_urp--;
- else
- tiflags &= ~TH_URG;
- todrop--;
- }
- /*
- * Following if statement from Stevens, vol. 2, p. 960.
- */
- if (todrop > ti->ti_len
- || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) {
- /*
- * Any valid FIN must be to the left of the window.
- * At this point the FIN must be a duplicate or out
- * of sequence; drop it.
- */
- tiflags &= ~TH_FIN;
-
- /*
- * Send an ACK to resynchronize and drop any data.
- * But keep on processing for RST or ACK.
- */
- tp->t_flags |= TF_ACKNOW;
- todrop = ti->ti_len;
- tcpstat.tcps_rcvduppack++;
- tcpstat.tcps_rcvdupbyte += todrop;
- } else {
- tcpstat.tcps_rcvpartduppack++;
- tcpstat.tcps_rcvpartdupbyte += todrop;
- }
- mbuf_trim(m, todrop);
- ti->ti_seq += todrop;
- ti->ti_len -= todrop;
- if (ti->ti_urp > todrop)
- ti->ti_urp -= todrop;
- else {
- tiflags &= ~TH_URG;
- ti->ti_urp = 0;
- }
- }
- /*
- * If new data are received on a connection after the
- * user processes are gone, then RST the other end.
- */
- if ((so->so_state & SS_NOFDREF) &&
- tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
- tp = tcp_close(tp);
- tcpstat.tcps_rcvafterclose++;
- goto dropwithreset;
- }
-
- /*
- * If segment ends after window, drop trailing data
- * (and PUSH and FIN); if nothing left, just ACK.
- */
- todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
- if (todrop > 0) {
- tcpstat.tcps_rcvpackafterwin++;
- if (todrop >= ti->ti_len) {
- tcpstat.tcps_rcvbyteafterwin += ti->ti_len;
- /*
- * If a new connection request is received
- * while in TIME_WAIT, drop the old connection
- * and start over if the sequence numbers
- * are above the previous ones.
- */
- if (tiflags & TH_SYN &&
- tp->t_state == TCPS_TIME_WAIT &&
- SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
- iss = tp->rcv_nxt + TCP_ISSINCR;
- tp = tcp_close(tp);
- goto findso;
- }
- /*
- * If window is closed can only take segments at
- * window edge, and have to drop data and PUSH from
- * incoming segments. Continue processing, but
- * remember to ack. Otherwise, drop segment
- * and ack.
- */
- if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
- tp->t_flags |= TF_ACKNOW;
- tcpstat.tcps_rcvwinprobe++;
- } else
- goto dropafterack;
- } else
- tcpstat.tcps_rcvbyteafterwin += todrop;
- mbuf_trim(m, -todrop);
- ti->ti_len -= todrop;
- tiflags &= ~(TH_PUSH|TH_FIN);
- }
-
- /*
- * If last ACK falls within this segment's sequence numbers,
- * record its timestamp.
- */
-/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) &&
- * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len +
- * ((tiflags & (TH_SYN|TH_FIN)) != 0))) {
- * tp->ts_recent_age = tcp_now;
- * tp->ts_recent = ts_val;
- * }
- */
-
- /*
- * If the RST bit is set examine the state:
- * SYN_RECEIVED STATE:
- * If passive open, return to LISTEN state.
- * If active open, inform user that connection was refused.
- * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
- * Inform user that connection was reset, and close tcb.
- * CLOSING, LAST_ACK, TIME_WAIT STATES
- * Close the tcb.
- */
- if (tiflags&TH_RST) switch (tp->t_state) {
-
- case TCPS_SYN_RECEIVED:
-/* so->so_error = ECONNREFUSED; */
- goto close;
-
- case TCPS_ESTABLISHED:
- case TCPS_FIN_WAIT_1:
- case TCPS_FIN_WAIT_2:
- case TCPS_CLOSE_WAIT:
-/* so->so_error = ECONNRESET; */
- close:
- tp->t_state = TCPS_CLOSED;
- tcpstat.tcps_drops++;
- tp = tcp_close(tp);
- goto drop;
-
- case TCPS_CLOSING:
- case TCPS_LAST_ACK:
- case TCPS_TIME_WAIT:
- tp = tcp_close(tp);
- goto drop;
- }
-
- /*
- * If a SYN is in the window, then this is an
- * error and we send an RST and drop the connection.
- */
- if (tiflags & TH_SYN) {
- tp = tcp_drop(tp,0);
- goto dropwithreset;
- }
-
- /*
- * If the ACK bit is off we drop the segment and return.
- */
- if ((tiflags & TH_ACK) == 0) goto drop;
-
- /*
- * Ack processing.
- */
- switch (tp->t_state) {
- /*
- * In SYN_RECEIVED state if the ack ACKs our SYN then enter
- * ESTABLISHED state and continue processing, otherwise
- * send an RST. una<=ack<=max
- */
- case TCPS_SYN_RECEIVED:
-
- if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
- SEQ_GT(ti->ti_ack, tp->snd_max))
- goto dropwithreset;
- tcpstat.tcps_connects++;
- tp->t_state = TCPS_ESTABLISHED;
- /*
- * The sent SYN is ack'ed with our sequence number +1
- * The first data byte already in the buffer will get
- * lost if no correction is made. This is only needed for
- * SS_CTL since the buffer is empty otherwise.
- * tp->snd_una++; or:
- */
- tp->snd_una=ti->ti_ack;
- if (so->so_state & SS_CTL) {
- /* So tcp_ctl reports the right state */
- ret = tcp_ctl(so);
- if (ret == 1) {
- soisfconnected(so);
- so->so_state &= ~SS_CTL; /* success XXX */
- } else if (ret == 2) {
- so->so_state = SS_NOFDREF; /* CTL_CMD */
- } else {
- needoutput = 1;
- tp->t_state = TCPS_FIN_WAIT_1;
- }
- } else {
- soisfconnected(so);
- }
-
- /* Do window scaling? */
-/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
- * (TF_RCVD_SCALE|TF_REQ_SCALE)) {
- * tp->snd_scale = tp->requested_s_scale;
- * tp->rcv_scale = tp->request_r_scale;
- * }
- */
- (void) tcp_reass(tp, (struct tcpiphdr *)0, (MBuf )0);
- tp->snd_wl1 = ti->ti_seq - 1;
- /* Avoid ack processing; snd_una==ti_ack => dup ack */
- goto synrx_to_est;
- /* fall into ... */
-
- /*
- * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
- * ACKs. If the ack is in the range
- * tp->snd_una < ti->ti_ack <= tp->snd_max
- * then advance tp->snd_una to ti->ti_ack and drop
- * data from the retransmission queue. If this ACK reflects
- * more up to date window information we update our window information.
- */
- case TCPS_ESTABLISHED:
- case TCPS_FIN_WAIT_1:
- case TCPS_FIN_WAIT_2:
- case TCPS_CLOSE_WAIT:
- case TCPS_CLOSING:
- case TCPS_LAST_ACK:
- case TCPS_TIME_WAIT:
-
- if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
- if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
- tcpstat.tcps_rcvdupack++;
- DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n",
- (long )m, (long )so));
- /*
- * If we have outstanding data (other than
- * a window probe), this is a completely
- * duplicate ack (ie, window info didn't
- * change), the ack is the biggest we've
- * seen and we've seen exactly our rexmt
- * threshold of them, assume a packet
- * has been dropped and retransmit it.
- * Kludge snd_nxt & the congestion
- * window so we send only this one
- * packet.
- *
- * We know we're losing at the current
- * window size so do congestion avoidance
- * (set ssthresh to half the current window
- * and pull our congestion window back to
- * the new ssthresh).
- *
- * Dup acks mean that packets have left the
- * network (they're now cached at the receiver)
- * so bump cwnd by the amount in the receiver
- * to keep a constant cwnd packets in the
- * network.
- */
- if (tp->t_timer[TCPT_REXMT] == 0 ||
- ti->ti_ack != tp->snd_una)
- tp->t_dupacks = 0;
- else if (++tp->t_dupacks == tcprexmtthresh) {
- tcp_seq onxt = tp->snd_nxt;
- u_int win =
- min(tp->snd_wnd, tp->snd_cwnd) / 2 /
- tp->t_maxseg;
-
- if (win < 2)
- win = 2;
- tp->snd_ssthresh = win * tp->t_maxseg;
- tp->t_timer[TCPT_REXMT] = 0;
- tp->t_rtt = 0;
- tp->snd_nxt = ti->ti_ack;
- tp->snd_cwnd = tp->t_maxseg;
- (void) tcp_output(tp);
- tp->snd_cwnd = tp->snd_ssthresh +
- tp->t_maxseg * tp->t_dupacks;
- if (SEQ_GT(onxt, tp->snd_nxt))
- tp->snd_nxt = onxt;
- goto drop;
- } else if (tp->t_dupacks > tcprexmtthresh) {
- tp->snd_cwnd += tp->t_maxseg;
- (void) tcp_output(tp);
- goto drop;
- }
- } else
- tp->t_dupacks = 0;
- break;
- }
- synrx_to_est:
- /*
- * If the congestion window was inflated to account
- * for the other side's cached packets, retract it.
- */
- if (tp->t_dupacks > tcprexmtthresh &&
- tp->snd_cwnd > tp->snd_ssthresh)
- tp->snd_cwnd = tp->snd_ssthresh;
- tp->t_dupacks = 0;
- if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
- tcpstat.tcps_rcvacktoomuch++;
- goto dropafterack;
- }
- acked = ti->ti_ack - tp->snd_una;
- tcpstat.tcps_rcvackpack++;
- tcpstat.tcps_rcvackbyte += acked;
-
- /*
- * If we have a timestamp reply, update smoothed
- * round trip time. If no timestamp is present but
- * transmit timer is running and timed sequence
- * number was acked, update smoothed round trip time.
- * Since we now have an rtt measurement, cancel the
- * timer backoff (cf., Phil Karn's retransmit alg.).
- * Recompute the initial retransmit timer.
- */
-/* if (ts_present)
- * tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
- * else
- */
- if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
- tcp_xmit_timer(tp,tp->t_rtt);
-
- /*
- * If all outstanding data is acked, stop retransmit
- * timer and remember to restart (more output or persist).
- * If there is more data to be acked, restart retransmit
- * timer, using current (possibly backed-off) value.
- */
- if (ti->ti_ack == tp->snd_max) {
- tp->t_timer[TCPT_REXMT] = 0;
- needoutput = 1;
- } else if (tp->t_timer[TCPT_PERSIST] == 0)
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- /*
- * When new data is acked, open the congestion window.
- * If the window gives us less than ssthresh packets
- * in flight, open exponentially (maxseg per packet).
- * Otherwise open linearly: maxseg per window
- * (maxseg^2 / cwnd per packet).
- */
- {
- register u_int cw = tp->snd_cwnd;
- register u_int incr = tp->t_maxseg;
-
- if (cw > tp->snd_ssthresh)
- incr = incr * incr / cw;
- tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale);
- }
- if (acked > so->so_snd.sb_cc) {
- tp->snd_wnd -= so->so_snd.sb_cc;
- sbuf_drop(&so->so_snd, (int )so->so_snd.sb_cc);
- ourfinisacked = 1;
- } else {
- sbuf_drop(&so->so_snd, acked);
- tp->snd_wnd -= acked;
- ourfinisacked = 0;
- }
- /*
- * XXX sowwakup is called when data is acked and there's room for
- * for more data... it should read() the socket
- */
-/* if (so->so_snd.sb_flags & SB_NOTIFY)
- * sowwakeup(so);
- */
- tp->snd_una = ti->ti_ack;
- if (SEQ_LT(tp->snd_nxt, tp->snd_una))
- tp->snd_nxt = tp->snd_una;
-
- switch (tp->t_state) {
-
- /*
- * In FIN_WAIT_1 STATE in addition to the processing
- * for the ESTABLISHED state if our FIN is now acknowledged
- * then enter FIN_WAIT_2.
- */
- case TCPS_FIN_WAIT_1:
- if (ourfinisacked) {
- /*
- * If we can't receive any more
- * data, then closing user can proceed.
- * Starting the timer is contrary to the
- * specification, but if we don't get a FIN
- * we'll hang forever.
- */
- if (so->so_state & SS_FCANTRCVMORE) {
- soisfdisconnected(so);
- tp->t_timer[TCPT_2MSL] = tcp_maxidle;
- }
- tp->t_state = TCPS_FIN_WAIT_2;
- }
- break;
-
- /*
- * In CLOSING STATE in addition to the processing for
- * the ESTABLISHED state if the ACK acknowledges our FIN
- * then enter the TIME-WAIT state, otherwise ignore
- * the segment.
- */
- case TCPS_CLOSING:
- if (ourfinisacked) {
- tp->t_state = TCPS_TIME_WAIT;
- tcp_canceltimers(tp);
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- soisfdisconnected(so);
- }
- break;
-
- /*
- * In LAST_ACK, we may still be waiting for data to drain
- * and/or to be acked, as well as for the ack of our FIN.
- * If our FIN is now acknowledged, delete the TCB,
- * enter the closed state and return.
- */
- case TCPS_LAST_ACK:
- if (ourfinisacked) {
- tp = tcp_close(tp);
- goto drop;
- }
- break;
-
- /*
- * In TIME_WAIT state the only thing that should arrive
- * is a retransmission of the remote FIN. Acknowledge
- * it and restart the finack timer.
- */
- case TCPS_TIME_WAIT:
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- goto dropafterack;
- }
- } /* switch(tp->t_state) */
-
-step6:
- /*
- * Update window information.
- * Don't look at window if no ACK: TAC's send garbage on first SYN.
- */
- if ((tiflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
- (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
- (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) {
- /* keep track of pure window updates */
- if (ti->ti_len == 0 &&
- tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)
- tcpstat.tcps_rcvwinupd++;
- tp->snd_wnd = tiwin;
- tp->snd_wl1 = ti->ti_seq;
- tp->snd_wl2 = ti->ti_ack;
- if (tp->snd_wnd > tp->max_sndwnd)
- tp->max_sndwnd = tp->snd_wnd;
- needoutput = 1;
- }
-
- /*
- * Process segments with URG.
- */
- if ((tiflags & TH_URG) && ti->ti_urp &&
- TCPS_HAVERCVDFIN(tp->t_state) == 0) {
- /*
- * This is a kludge, but if we receive and accept
- * random urgent pointers, we'll crash in
- * soreceive. It's hard to imagine someone
- * actually wanting to send this much urgent data.
- */
- if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) {
- ti->ti_urp = 0;
- tiflags &= ~TH_URG;
- goto dodata;
- }
- /*
- * If this segment advances the known urgent pointer,
- * then mark the data stream. This should not happen
- * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
- * a FIN has been received from the remote side.
- * In these states we ignore the URG.
- *
- * According to RFC961 (Assigned Protocols),
- * the urgent pointer points to the last octet
- * of urgent data. We continue, however,
- * to consider it to indicate the first octet
- * of data past the urgent section as the original
- * spec states (in one of two places).
- */
- if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
- tp->rcv_up = ti->ti_seq + ti->ti_urp;
- so->so_urgc = so->so_rcv.sb_cc +
- (tp->rcv_up - tp->rcv_nxt); /* -1; */
- tp->rcv_up = ti->ti_seq + ti->ti_urp;
-
- }
- } else
- /*
- * If no out of band data is expected,
- * pull receive urgent pointer along
- * with the receive window.
- */
- if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
- tp->rcv_up = tp->rcv_nxt;
-dodata:
-
- /*
- * Process the segment text, merging it into the TCP sequencing queue,
- * and arranging for acknowledgment of receipt if necessary.
- * This process logically involves adjusting tp->rcv_wnd as data
- * is presented to the user (this happens in tcp_usrreq.c,
- * case PRU_RCVD). If a FIN has already been received on this
- * connection then we just ignore the text.
- */
- if ((ti->ti_len || (tiflags&TH_FIN)) &&
- TCPS_HAVERCVDFIN(tp->t_state) == 0) {
- TCP_REASS(tp, ti, m, so, tiflags);
- /*
- * Note the amount of data that peer has sent into
- * our window, in order to estimate the sender's
- * buffer size.
- */
- len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt);
- } else {
- mbuf_free(m);
- tiflags &= ~TH_FIN;
- }
-
- /*
- * If FIN is received ACK the FIN and let the user know
- * that the connection is closing.
- */
- if (tiflags & TH_FIN) {
- if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
- /*
- * If we receive a FIN we can't send more data,
- * set it SS_FDRAIN
- * Shutdown the socket if there is no rx data in the
- * buffer.
- * soread() is called on completion of shutdown() and
- * will got to TCPS_LAST_ACK, and use tcp_output()
- * to send the FIN.
- */
-/* sofcantrcvmore(so); */
- sofwdrain(so);
-
- tp->t_flags |= TF_ACKNOW;
- tp->rcv_nxt++;
- }
- switch (tp->t_state) {
-
- /*
- * In SYN_RECEIVED and ESTABLISHED STATES
- * enter the CLOSE_WAIT state.
- */
- case TCPS_SYN_RECEIVED:
- case TCPS_ESTABLISHED:
- if(so->so_emu == EMU_CTL) /* no shutdown on socket */
- tp->t_state = TCPS_LAST_ACK;
- else
- tp->t_state = TCPS_CLOSE_WAIT;
- break;
-
- /*
- * If still in FIN_WAIT_1 STATE FIN has not been acked so
- * enter the CLOSING state.
- */
- case TCPS_FIN_WAIT_1:
- tp->t_state = TCPS_CLOSING;
- break;
-
- /*
- * In FIN_WAIT_2 state enter the TIME_WAIT state,
- * starting the time-wait timer, turning off the other
- * standard timers.
- */
- case TCPS_FIN_WAIT_2:
- tp->t_state = TCPS_TIME_WAIT;
- tcp_canceltimers(tp);
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- soisfdisconnected(so);
- break;
-
- /*
- * In TIME_WAIT state restart the 2 MSL time_wait timer.
- */
- case TCPS_TIME_WAIT:
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- break;
- }
- }
-
- /*
- * If this is a small packet, then ACK now - with Nagel
- * congestion avoidance sender won't send more until
- * he gets an ACK.
- *
- * See above.
- */
-/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) {
- */
-/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg &&
- * (so->so_iptos & IPTOS_LOWDELAY) == 0) ||
- * ((so->so_iptos & IPTOS_LOWDELAY) &&
- * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) {
- */
- if (ti->ti_len && (unsigned)ti->ti_len <= 5 &&
- ((struct tcpiphdr_2 *)ti)->first_char == (char)27) {
- tp->t_flags |= TF_ACKNOW;
- }
-
- /*
- * Return any desired output.
- */
- if (needoutput || (tp->t_flags & TF_ACKNOW)) {
- (void) tcp_output(tp);
- }
- return;
-
-dropafterack:
- /*
- * Generate an ACK dropping incoming segment if it occupies
- * sequence space, where the ACK reflects our state.
- */
- if (tiflags & TH_RST)
- goto drop;
- mbuf_free(m);
- tp->t_flags |= TF_ACKNOW;
- (void) tcp_output(tp);
- return;
-
-dropwithreset:
- /* reuses m if m!=NULL, mbuf_free() unnecessary */
- if (tiflags & TH_ACK)
- tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
- else {
- if (tiflags & TH_SYN) ti->ti_len++;
- tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
- TH_RST|TH_ACK);
- }
-
- return;
-
-drop:
- /*
- * Drop space held by incoming segment and return.
- */
- mbuf_free(m);
-
- return;
-}
-
- /* , ts_present, ts_val, ts_ecr) */
-/* int *ts_present;
- * u_int32_t *ts_val, *ts_ecr;
- */
-void
-tcp_dooptions(tp, cp, cnt, ti)
- struct tcpcb *tp;
- u_char *cp;
- int cnt;
- struct tcpiphdr *ti;
-{
- u_int16_t mss;
- int opt, optlen;
-
- DEBUG_CALL("tcp_dooptions");
- DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt));
-
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[0];
- if (opt == TCPOPT_EOL)
- break;
- if (opt == TCPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[1];
- if (optlen <= 0)
- break;
- }
- switch (opt) {
-
- default:
- continue;
-
- case TCPOPT_MAXSEG:
- if (optlen != TCPOLEN_MAXSEG)
- continue;
- if (!(ti->ti_flags & TH_SYN))
- continue;
- memcpy((char *) &mss, (char *) cp + 2, sizeof(mss));
- NTOHS(mss);
- (void) tcp_mss(tp, mss); /* sets t_maxseg */
- break;
-
-/* case TCPOPT_WINDOW:
- * if (optlen != TCPOLEN_WINDOW)
- * continue;
- * if (!(ti->ti_flags & TH_SYN))
- * continue;
- * tp->t_flags |= TF_RCVD_SCALE;
- * tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT);
- * break;
- */
-/* case TCPOPT_TIMESTAMP:
- * if (optlen != TCPOLEN_TIMESTAMP)
- * continue;
- * *ts_present = 1;
- * memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val));
- * NTOHL(*ts_val);
- * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr));
- * NTOHL(*ts_ecr);
- *
- */ /*
- * * A timestamp received in a SYN makes
- * * it ok to send timestamp requests and replies.
- * */
-/* if (ti->ti_flags & TH_SYN) {
- * tp->t_flags |= TF_RCVD_TSTMP;
- * tp->ts_recent = *ts_val;
- * tp->ts_recent_age = tcp_now;
- * }
- */ break;
- }
- }
-}
-
-
-/*
- * Pull out of band byte out of a segment so
- * it doesn't appear in the user's data queue.
- * It is still reflected in the segment length for
- * sequencing purposes.
- */
-
-#ifdef notdef
-
-void
-tcp_pulloutofband(so, ti, m)
- struct socket *so;
- struct tcpiphdr *ti;
- register MBuf m;
-{
- int cnt = ti->ti_urp - 1;
-
- while (cnt >= 0) {
- if (m->m_len > cnt) {
- char *cp = MBUF_TO(m, caddr_t) + cnt;
- struct tcpcb *tp = sototcpcb(so);
-
- tp->t_iobc = *cp;
- tp->t_oobflags |= TCPOOB_HAVEDATA;
- memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1));
- m->m_len--;
- return;
- }
- cnt -= m->m_len;
- m = m->m_next; /* XXX WRONG! Fix it! */
- if (m == 0)
- break;
- }
- panic("tcp_pulloutofband");
-}
-
-#endif /* notdef */
-
-/*
- * Collect new round-trip time estimate
- * and update averages and current timeout.
- */
-
-void
-tcp_xmit_timer(tp, rtt)
- register struct tcpcb *tp;
- int rtt;
-{
- register short delta;
-
- DEBUG_CALL("tcp_xmit_timer");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("rtt = %d", rtt);
-
- tcpstat.tcps_rttupdated++;
- if (tp->t_srtt != 0) {
- /*
- * srtt is stored as fixed point with 3 bits after the
- * binary point (i.e., scaled by 8). The following magic
- * is equivalent to the smoothing algorithm in rfc793 with
- * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed
- * point). Adjust rtt to origin 0.
- */
- delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT);
- if ((tp->t_srtt += delta) <= 0)
- tp->t_srtt = 1;
- /*
- * We accumulate a smoothed rtt variance (actually, a
- * smoothed mean difference), then set the retransmit
- * timer to smoothed rtt + 4 times the smoothed variance.
- * rttvar is stored as fixed point with 2 bits after the
- * binary point (scaled by 4). The following is
- * equivalent to rfc793 smoothing with an alpha of .75
- * (rttvar = rttvar*3/4 + |delta| / 4). This replaces
- * rfc793's wired-in beta.
- */
- if (delta < 0)
- delta = -delta;
- delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT);
- if ((tp->t_rttvar += delta) <= 0)
- tp->t_rttvar = 1;
- } else {
- /*
- * No rtt measurement yet - use the unsmoothed rtt.
- * Set the variance to half the rtt (so our first
- * retransmit happens at 3*rtt).
- */
- tp->t_srtt = rtt << TCP_RTT_SHIFT;
- tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1);
- }
- tp->t_rtt = 0;
- tp->t_rxtshift = 0;
-
- /*
- * the retransmit should happen at rtt + 4 * rttvar.
- * Because of the way we do the smoothing, srtt and rttvar
- * will each average +1/2 tick of bias. When we compute
- * the retransmit timer, we want 1/2 tick of rounding and
- * 1 extra tick because of +-1/2 tick uncertainty in the
- * firing of the timer. The bias will give us exactly the
- * 1.5 tick we need. But, because the bias is
- * statistical, we have to test that we don't drop below
- * the minimum feasible timer (which is 2 ticks).
- */
- TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
- (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
-
- /*
- * We received an ack for a packet that wasn't retransmitted;
- * it is probably safe to discard any error indications we've
- * received recently. This isn't quite right, but close enough
- * for now (a route might have failed after we sent a segment,
- * and the return path might not be symmetrical).
- */
- tp->t_softerror = 0;
-}
-
-/*
- * Determine a reasonable value for maxseg size.
- * If the route is known, check route for mtu.
- * If none, use an mss that can be handled on the outgoing
- * interface without forcing IP to fragment; if bigger than
- * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES
- * to utilize large mbufs. If no route is found, route has no mtu,
- * or the destination isn't local, use a default, hopefully conservative
- * size (usually 512 or the default IP max size, but no more than the mtu
- * of the interface), as we can't discover anything about intervening
- * gateways or networks. We also initialize the congestion/slow start
- * window to be a single segment if the destination isn't local.
- * While looking at the routing entry, we also initialize other path-dependent
- * parameters from pre-set or cached values in the routing entry.
- */
-
-int
-tcp_mss(tp, offer)
- register struct tcpcb *tp;
- u_int offer;
-{
- struct socket *so = tp->t_socket;
- int mss;
-
- DEBUG_CALL("tcp_mss");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("offer = %d", offer);
-
- mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr);
- if (offer)
- mss = min(mss, offer);
- mss = max(mss, 32);
- if (mss < tp->t_maxseg || offer != 0)
- tp->t_maxseg = mss;
-
- tp->snd_cwnd = mss;
-
- sbuf_reserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0));
- sbuf_reserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0));
-
- DEBUG_MISC((dfd, " returning mss = %d\n", mss));
-
- return mss;
-}
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
deleted file mode 100644
index 95246aa..0000000
--- a/slirp/tcp_output.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93
- * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-/*
- * Since this is only used in "stats socket", we give meaning
- * names instead of the REAL names
- */
-char *tcpstates[] = {
-/* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */
- "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD",
- "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",
- "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",
-};
-
-u_char tcp_outflags[TCP_NSTATES] = {
- TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
- TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
- TH_FIN|TH_ACK, TH_ACK, TH_ACK,
-};
-
-
-#define MAX_TCPOPTLEN 32 /* max # bytes that go in options */
-
-/*
- * Tcp output routine: figure out what should be sent and send it.
- */
-int
-tcp_output(tp)
- register struct tcpcb *tp;
-{
- register struct socket *so = tp->t_socket;
- register long len, win;
- int off, flags, error;
- register MBuf m;
- register struct tcpiphdr *ti;
- u_char opt[MAX_TCPOPTLEN];
- unsigned optlen, hdrlen;
- int idle, sendalot;
-
- DEBUG_CALL("tcp_output");
- DEBUG_ARG("tp = %lx", (long )tp);
-
- /*
- * Determine length of data that should be transmitted,
- * and flags that will be used.
- * If there is some data or critical controls (SYN, RST)
- * to send, then transmit; otherwise, investigate further.
- */
- idle = (tp->snd_max == tp->snd_una);
- if (idle && tp->t_idle >= tp->t_rxtcur)
- /*
- * We have been idle for "a while" and no acks are
- * expected to clock out any data we send --
- * slow start to get ack "clock" running again.
- */
- tp->snd_cwnd = tp->t_maxseg;
-again:
- sendalot = 0;
- off = tp->snd_nxt - tp->snd_una;
- win = min(tp->snd_wnd, tp->snd_cwnd);
-
- flags = tcp_outflags[tp->t_state];
-
- DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags));
-
- /*
- * If in persist timeout with window of 0, send 1 byte.
- * Otherwise, if window is small but nonzero
- * and timer expired, we will send what we can
- * and go to transmit state.
- */
- if (tp->t_force) {
- if (win == 0) {
- /*
- * If we still have some data to send, then
- * clear the FIN bit. Usually this would
- * happen below when it realizes that we
- * aren't sending all the data. However,
- * if we have exactly 1 byte of unset data,
- * then it won't clear the FIN bit below,
- * and if we are in persist state, we wind
- * up sending the packet without recording
- * that we sent the FIN bit.
- *
- * We can't just blindly clear the FIN bit,
- * because if we don't have any more data
- * to send then the probe will be the FIN
- * itself.
- */
- if (off < so->so_snd.sb_cc)
- flags &= ~TH_FIN;
- win = 1;
- } else {
- tp->t_timer[TCPT_PERSIST] = 0;
- tp->t_rxtshift = 0;
- }
- }
-
- len = min(so->so_snd.sb_cc, win) - off;
-
- if (len < 0) {
- /*
- * If FIN has been sent but not acked,
- * but we haven't been called to retransmit,
- * len will be -1. Otherwise, window shrank
- * after we sent into it. If window shrank to 0,
- * cancel pending retransmit and pull snd_nxt
- * back to (closed) window. We will enter persist
- * state below. If the window didn't close completely,
- * just wait for an ACK.
- */
- len = 0;
- if (win == 0) {
- tp->t_timer[TCPT_REXMT] = 0;
- tp->snd_nxt = tp->snd_una;
- }
- }
-
- if (len > tp->t_maxseg) {
- len = tp->t_maxseg;
- sendalot = 1;
- }
- if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
- flags &= ~TH_FIN;
-
- win = sbuf_space(&so->so_rcv);
-
- /*
- * Sender silly window avoidance. If connection is idle
- * and can send all data, a maximum segment,
- * at least a maximum default-size segment do it,
- * or are forced, do it; otherwise don't bother.
- * If peer's buffer is tiny, then send
- * when window is at least half open.
- * If retransmitting (possibly after persist timer forced us
- * to send into a small window), then must resend.
- */
- if (len) {
- if (len == tp->t_maxseg)
- goto send;
- if ((1 || idle || tp->t_flags & TF_NODELAY) &&
- len + off >= so->so_snd.sb_cc)
- goto send;
- if (tp->t_force)
- goto send;
- if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
- goto send;
- if (SEQ_LT(tp->snd_nxt, tp->snd_max))
- goto send;
- }
-
- /*
- * Compare available window to amount of window
- * known to peer (as advertised window less
- * next expected input). If the difference is at least two
- * max size segments, or at least 50% of the maximum possible
- * window, then want to send a window update to peer.
- */
- if (win > 0) {
- /*
- * "adv" is the amount we can increase the window,
- * taking into account that we are limited by
- * TCP_MAXWIN << tp->rcv_scale.
- */
- long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) -
- (tp->rcv_adv - tp->rcv_nxt);
-
- if (adv >= (long) (2 * tp->t_maxseg))
- goto send;
- if (2 * adv >= (long) so->so_rcv.sb_datalen)
- goto send;
- }
-
- /*
- * Send if we owe peer an ACK.
- */
- if (tp->t_flags & TF_ACKNOW)
- goto send;
- if (flags & (TH_SYN|TH_RST))
- goto send;
- if (SEQ_GT(tp->snd_up, tp->snd_una))
- goto send;
- /*
- * If our state indicates that FIN should be sent
- * and we have not yet done so, or we're retransmitting the FIN,
- * then we need to send.
- */
- if (flags & TH_FIN &&
- ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
- goto send;
-
- /*
- * TCP window updates are not reliable, rather a polling protocol
- * using ``persist'' packets is used to insure receipt of window
- * updates. The three ``states'' for the output side are:
- * idle not doing retransmits or persists
- * persisting to move a small or zero window
- * (re)transmitting and thereby not persisting
- *
- * tp->t_timer[TCPT_PERSIST]
- * is set when we are in persist state.
- * tp->t_force
- * is set when we are called to send a persist packet.
- * tp->t_timer[TCPT_REXMT]
- * is set when we are retransmitting
- * The output side is idle when both timers are zero.
- *
- * If send window is too small, there is data to transmit, and no
- * retransmit or persist is pending, then go to persist state.
- * If nothing happens soon, send when timer expires:
- * if window is nonzero, transmit what we can,
- * otherwise force out a byte.
- */
- if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
- tp->t_timer[TCPT_PERSIST] == 0) {
- tp->t_rxtshift = 0;
- tcp_setpersist(tp);
- }
-
- /*
- * No reason to send a segment, just return.
- */
- tcpstat.tcps_didnuttin++;
-
- return (0);
-
-send:
- /*
- * Before ESTABLISHED, force sending of initial options
- * unless TCP set not to do any options.
- * NOTE: we assume that the IP/TCP header plus TCP options
- * always fit in a single mbuf, leaving room for a maximum
- * link header, i.e.
- * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN
- */
- optlen = 0;
- hdrlen = sizeof (struct tcpiphdr);
- if (flags & TH_SYN) {
- tp->snd_nxt = tp->iss;
- if ((tp->t_flags & TF_NOOPT) == 0) {
- u_int16_t mss;
-
- opt[0] = TCPOPT_MAXSEG;
- opt[1] = 4;
- mss = htons((u_int16_t) tcp_mss(tp, 0));
- memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss));
- optlen = 4;
-
-/* if ((tp->t_flags & TF_REQ_SCALE) &&
- * ((flags & TH_ACK) == 0 ||
- * (tp->t_flags & TF_RCVD_SCALE))) {
- * *((u_int32_t *) (opt + optlen)) = htonl(
- * TCPOPT_NOP << 24 |
- * TCPOPT_WINDOW << 16 |
- * TCPOLEN_WINDOW << 8 |
- * tp->request_r_scale);
- * optlen += 4;
- * }
- */
- }
- }
-
- /*
- * Send a timestamp and echo-reply if this is a SYN and our side
- * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
- * and our peer have sent timestamps in our SYN's.
- */
-/* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
- * (flags & TH_RST) == 0 &&
- * ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
- * (tp->t_flags & TF_RCVD_TSTMP))) {
- * u_int32_t *lp = (u_int32_t *)(opt + optlen);
- *
- * / * Form timestamp option as shown in appendix A of RFC 1323. * /
- * *lp++ = htonl(TCPOPT_TSTAMP_HDR);
- * *lp++ = htonl(tcp_now);
- * *lp = htonl(tp->ts_recent);
- * optlen += TCPOLEN_TSTAMP_APPA;
- * }
- */
- hdrlen += optlen;
-
- /*
- * Adjust data length if insertion of options will
- * bump the packet length beyond the t_maxseg length.
- */
- if (len > tp->t_maxseg - optlen) {
- len = tp->t_maxseg - optlen;
- sendalot = 1;
- }
-
- /*
- * Grab a header mbuf, attaching a copy of data to
- * be transmitted, and initialize the header from
- * the template for sends on this connection.
- */
- if (len) {
- if (tp->t_force && len == 1)
- tcpstat.tcps_sndprobe++;
- else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
- tcpstat.tcps_sndrexmitpack++;
- tcpstat.tcps_sndrexmitbyte += len;
- } else {
- tcpstat.tcps_sndpack++;
- tcpstat.tcps_sndbyte += len;
- }
-
- m = mbuf_alloc();
- if (m == NULL) {
-/* error = ENOBUFS; */
- error = 1;
- goto out;
- }
- m->m_data += if_maxlinkhdr;
- m->m_len = hdrlen;
-
- /*
- * This will always succeed, since we make sure our mbufs
- * are big enough to hold one MSS packet + header + ... etc.
- */
-/* if (len <= MHLEN - hdrlen - max_linkhdr) { */
-
- sbuf_copy(&so->so_snd, off, (int) len, MBUF_TO(m, caddr_t) + hdrlen);
- m->m_len += len;
-
-/* } else {
- * m->m_next = mbuf_copy(so->so_snd.sb_mb, off, (int) len);
- * if (m->m_next == 0)
- * len = 0;
- * }
- */
- /*
- * If we're sending everything we've got, set PUSH.
- * (This will keep happy those implementations which only
- * give data to the user when a buffer fills or
- * a PUSH comes in.)
- */
- if (off + len == so->so_snd.sb_cc)
- flags |= TH_PUSH;
- } else {
- if (tp->t_flags & TF_ACKNOW)
- tcpstat.tcps_sndacks++;
- else if (flags & (TH_SYN|TH_FIN|TH_RST))
- tcpstat.tcps_sndctrl++;
- else if (SEQ_GT(tp->snd_up, tp->snd_una))
- tcpstat.tcps_sndurg++;
- else
- tcpstat.tcps_sndwinup++;
-
- m = mbuf_alloc();
- if (m == NULL) {
-/* error = ENOBUFS; */
- error = 1;
- goto out;
- }
- m->m_data += if_maxlinkhdr;
- m->m_len = hdrlen;
- }
-
- ti = MBUF_TO(m, struct tcpiphdr *);
-
- memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr));
-
- /*
- * Fill in fields, remembering maximum advertised
- * window for use in delaying messages about window sizes.
- * If resending a FIN, be sure not to use a new sequence number.
- */
- if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
- tp->snd_nxt == tp->snd_max)
- tp->snd_nxt--;
- /*
- * If we are doing retransmissions, then snd_nxt will
- * not reflect the first unsent octet. For ACK only
- * packets, we do not want the sequence number of the
- * retransmitted packet, we want the sequence number
- * of the next unsent octet. So, if there is no data
- * (and no SYN or FIN), use snd_max instead of snd_nxt
- * when filling in ti_seq. But if we are in persist
- * state, snd_max might reflect one byte beyond the
- * right edge of the window, so use snd_nxt in that
- * case, since we know we aren't doing a retransmission.
- * (retransmit and persist are mutually exclusive...)
- */
- if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
- ti->ti_seq = htonl(tp->snd_nxt);
- else
- ti->ti_seq = htonl(tp->snd_max);
- ti->ti_ack = htonl(tp->rcv_nxt);
- if (optlen) {
- memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen);
- ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
- }
- ti->ti_flags = flags;
- /*
- * Calculate receive window. Don't shrink window,
- * but avoid silly window syndrome.
- */
- if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg)
- win = 0;
- if (win > (long)TCP_MAXWIN << tp->rcv_scale)
- win = (long)TCP_MAXWIN << tp->rcv_scale;
- if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
- win = (long)(tp->rcv_adv - tp->rcv_nxt);
- ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale));
-
- if (SEQ_GT(tp->snd_up, tp->snd_una)) {
- ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq)));
-#ifdef notdef
- if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
- ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt));
-#endif
- ti->ti_flags |= TH_URG;
- } else
- /*
- * If no urgent pointer to send, then we pull
- * the urgent pointer to the left edge of the send window
- * so that it doesn't drift into the send window on sequence
- * number wraparound.
- */
- tp->snd_up = tp->snd_una; /* drag it along */
-
- /*
- * Put TCP length in extended header, and then
- * checksum extended header and data.
- */
- if (len + optlen)
- ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) +
- optlen + len));
- ti->ti_sum = cksum(m, (int)(hdrlen + len));
-
- /*
- * In transmit state, time the transmission and arrange for
- * the retransmit. In persist state, just set snd_max.
- */
- if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
- tcp_seq startseq = tp->snd_nxt;
-
- /*
- * Advance snd_nxt over sequence space of this segment.
- */
- if (flags & (TH_SYN|TH_FIN)) {
- if (flags & TH_SYN)
- tp->snd_nxt++;
- if (flags & TH_FIN) {
- tp->snd_nxt++;
- tp->t_flags |= TF_SENTFIN;
- }
- }
- tp->snd_nxt += len;
- if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
- tp->snd_max = tp->snd_nxt;
- /*
- * Time this transmission if not a retransmission and
- * not currently timing anything.
- */
- if (tp->t_rtt == 0) {
- tp->t_rtt = 1;
- tp->t_rtseq = startseq;
- tcpstat.tcps_segstimed++;
- }
- }
-
- /*
- * Set retransmit timer if not currently set,
- * and not doing an ack or a keep-alive probe.
- * Initial value for retransmit timer is smoothed
- * round-trip time + 2 * round-trip time variance.
- * Initialize shift counter which is used for backoff
- * of retransmit time.
- */
- if (tp->t_timer[TCPT_REXMT] == 0 &&
- tp->snd_nxt != tp->snd_una) {
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- if (tp->t_timer[TCPT_PERSIST]) {
- tp->t_timer[TCPT_PERSIST] = 0;
- tp->t_rxtshift = 0;
- }
- }
- } else
- if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
- tp->snd_max = tp->snd_nxt + len;
-
- /*
- * Fill in IP length and desired time to live and
- * send to IP level. There should be a better way
- * to handle ttl and tos; we could keep them in
- * the template, but need a way to checksum without them.
- */
- m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
-
- {
-
- ((struct ip *)ti)->ip_len = m->m_len;
-
- ((struct ip *)ti)->ip_ttl = ip_defttl;
- ((struct ip *)ti)->ip_tos = so->so_iptos;
-
-/* #if BSD >= 43 */
- /* Don't do IP options... */
-/* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
- * so->so_options & SO_DONTROUTE, 0);
- */
- error = ip_output(so, m);
-
-/* #else
- * error = ip_output(m, (MBuf )0, &tp->t_inpcb->inp_route,
- * so->so_options & SO_DONTROUTE);
- * #endif
- */
- }
- if (error) {
-out:
-/* if (error == ENOBUFS) {
- * tcp_quench(tp->t_inpcb, 0);
- * return (0);
- * }
- */
-/* if ((error == EHOSTUNREACH || error == ENETDOWN)
- * && TCPS_HAVERCVDSYN(tp->t_state)) {
- * tp->t_softerror = error;
- * return (0);
- * }
- */
- return (error);
- }
- tcpstat.tcps_sndtotal++;
-
- /*
- * Data sent (as far as we can tell).
- * If this advertises a larger window than any other segment,
- * then remember the size of the advertised window.
- * Any pending ACK has now been sent.
- */
- if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
- tp->rcv_adv = tp->rcv_nxt + win;
- tp->last_ack_sent = tp->rcv_nxt;
- tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
- if (sendalot)
- goto again;
-
- return (0);
-}
-
-void
-tcp_setpersist(tp)
- register struct tcpcb *tp;
-{
- int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
-
-/* if (tp->t_timer[TCPT_REXMT])
- * panic("tcp_output REXMT");
- */
- /*
- * Start/restart persistence timer.
- */
- TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
- t * tcp_backoff[tp->t_rxtshift],
- TCPTV_PERSMIN, TCPTV_PERSMAX);
- if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
- tp->t_rxtshift++;
-}
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
deleted file mode 100644
index 59aae0a..0000000
--- a/slirp/tcp_subr.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93
- * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define WANT_SYS_IOCTL_H
-#include <slirp.h>
-#define SLIRP_COMPILATION
-#include "sockets.h"
-#include "proxy_common.h"
-
-/* patchable/settable parameters for tcp */
-int tcp_mssdflt = TCP_MSS;
-int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
-int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */
-int tcp_rcvspace; /* You may want to change this */
-int tcp_sndspace; /* Keep small if you have an error prone link */
-
-/*
- * Tcp initialization
- */
-void
-tcp_init()
-{
- tcp_iss = 1; /* wrong */
- tcb.so_next = tcb.so_prev = &tcb;
-
- /* tcp_rcvspace = our Window we advertise to the remote */
- tcp_rcvspace = TCP_RCVSPACE;
- tcp_sndspace = TCP_SNDSPACE;
-
- /* Make sure tcp_sndspace is at least 2*MSS */
- if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)))
- tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr));
-}
-
-/*
- * Create template to be used to send tcp packets on a connection.
- * Call after host entry created, fills
- * in a skeletal tcp/ip header, minimizing the amount of work
- * necessary when the connection is used.
- */
-/* struct tcpiphdr * */
-void
-tcp_template(tp)
- struct tcpcb *tp;
-{
- struct socket *so = tp->t_socket;
- register struct tcpiphdr *n = &tp->t_template;
-
- n->ti_next = n->ti_prev = 0;
- n->ti_x1 = 0;
- n->ti_pr = IPPROTO_TCP;
- n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
- n->ti_src = so->so_faddr;
- n->ti_dst = so->so_laddr;
- n->ti_sport = so->so_fport;
- n->ti_dport = so->so_lport;
-
- n->ti_seq = 0;
- n->ti_ack = 0;
- n->ti_x2 = 0;
- n->ti_off = 5;
- n->ti_flags = 0;
- n->ti_win = 0;
- n->ti_sum = 0;
- n->ti_urp = 0;
-}
-
-/*
- * Send a single message to the TCP at address specified by
- * the given TCP/IP header. If m == 0, then we make a copy
- * of the tcpiphdr at ti and send directly to the addressed host.
- * This is used to force keep alive messages out using the TCP
- * template for a connection tp->t_template. If flags are given
- * then we send a message back to the TCP which originated the
- * segment ti, and discard the mbuf containing it and any other
- * attached mbufs.
- *
- * In any case the ack and sequence number of the transmitted
- * segment are as specified by the parameters.
- */
-void
-tcp_respond(tp, ti, m, ack, seq, flags)
- struct tcpcb *tp;
- register struct tcpiphdr *ti;
- register MBuf m;
- tcp_seq ack, seq;
- int flags;
-{
- register int tlen;
- int win = 0;
-
- DEBUG_CALL("tcp_respond");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("ti = %lx", (long)ti);
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("ack = %u", ack);
- DEBUG_ARG("seq = %u", seq);
- DEBUG_ARG("flags = %x", flags);
-
- if (tp)
- win = sbuf_space(&tp->t_socket->so_rcv);
- if (m == 0) {
- if ((m = mbuf_alloc()) == NULL)
- return;
-#ifdef TCP_COMPAT_42
- tlen = 1;
-#else
- tlen = 0;
-#endif
- m->m_data += if_maxlinkhdr;
- *MBUF_TO(m, struct tcpiphdr *) = *ti;
- ti = MBUF_TO(m, struct tcpiphdr *);
- flags = TH_ACK;
- } else {
- /*
- * ti points into m so the next line is just making
- * the mbuf point to ti
- */
- m->m_data = (caddr_t)ti;
-
- m->m_len = sizeof (struct tcpiphdr);
- tlen = 0;
-#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
- xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t);
- xchg(ti->ti_dport, ti->ti_sport, u_int16_t);
-#undef xchg
- }
- ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
- tlen += sizeof (struct tcpiphdr);
- m->m_len = tlen;
-
- ti->ti_next = ti->ti_prev = 0;
- ti->ti_x1 = 0;
- ti->ti_seq = htonl(seq);
- ti->ti_ack = htonl(ack);
- ti->ti_x2 = 0;
- ti->ti_off = sizeof (struct tcphdr) >> 2;
- ti->ti_flags = flags;
- if (tp)
- ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale));
- else
- ti->ti_win = htons((u_int16_t)win);
- ti->ti_urp = 0;
- ti->ti_sum = 0;
- ti->ti_sum = cksum(m, tlen);
- ((struct ip *)ti)->ip_len = tlen;
-
- if(flags & TH_RST)
- ((struct ip *)ti)->ip_ttl = MAXTTL;
- else
- ((struct ip *)ti)->ip_ttl = ip_defttl;
-
- (void) ip_output((struct socket *)0, m);
-}
-
-/*
- * Create a new TCP control block, making an
- * empty reassembly queue and hooking it to the argument
- * protocol control block.
- */
-struct tcpcb *
-tcp_newtcpcb(so)
- struct socket *so;
-{
- register struct tcpcb *tp;
-
- tp = (struct tcpcb *)malloc(sizeof(*tp));
- if (tp == NULL)
- return ((struct tcpcb *)0);
-
- memset((char *) tp, 0, sizeof(struct tcpcb));
- tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
- tp->t_maxseg = tcp_mssdflt;
-
- tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
- tp->t_socket = so;
-
- /*
- * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
- * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives
- * reasonable initial retransmit time.
- */
- tp->t_srtt = TCPTV_SRTTBASE;
- tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
- tp->t_rttmin = TCPTV_MIN;
-
- TCPT_RANGESET(tp->t_rxtcur,
- ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1,
- TCPTV_MIN, TCPTV_REXMTMAX);
-
- tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
- tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
- tp->t_state = TCPS_CLOSED;
-
- so->so_tcpcb = tp;
-
- return (tp);
-}
-
-/*
- * Drop a TCP connection, reporting
- * the specified error. If connection is synchronized,
- * then send a RST to peer.
- */
-struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
-{
-/* tcp_drop(tp, errno)
- register struct tcpcb *tp;
- int errno;
-{
-*/
-
- DEBUG_CALL("tcp_drop");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("errno = %d", errno);
-
- if (TCPS_HAVERCVDSYN(tp->t_state)) {
- tp->t_state = TCPS_CLOSED;
- (void) tcp_output(tp);
- tcpstat.tcps_drops++;
- } else
- tcpstat.tcps_conndrops++;
-/* if (errno == ETIMEDOUT && tp->t_softerror)
- * errno = tp->t_softerror;
- */
-/* so->so_error = errno; */
- return (tcp_close(tp));
-}
-
-/*
- * Close a TCP control block:
- * discard all space held by the tcp
- * discard internet protocol block
- * wake up any sleepers
- */
-struct tcpcb *
-tcp_close(tp)
- register struct tcpcb *tp;
-{
- register struct tcpiphdr *t;
- struct socket *so = tp->t_socket;
- register MBuf m;
-
- DEBUG_CALL("tcp_close");
- DEBUG_ARG("tp = %lx", (long )tp);
-
- /* free the reassembly queue, if any */
- t = (struct tcpiphdr *) tp->seg_next;
- while (t != (struct tcpiphdr *)tp) {
- t = (struct tcpiphdr *)t->ti_next;
- m = (MBuf ) REASS_MBUF((struct tcpiphdr *)t->ti_prev);
- remque_32((struct tcpiphdr *) t->ti_prev);
- mbuf_free(m);
- }
- /* It's static */
-/* if (tp->t_template)
- * (void) mbuf_free(MBUF_FROM(tp->t_template));
- */
-/* free(tp, M_PCB); */
- free(tp);
- so->so_tcpcb = 0;
- soisfdisconnected(so);
- /* clobber input socket cache if we're closing the cached connection */
- if (so == tcp_last_so)
- tcp_last_so = &tcb;
- closesocket(so->s);
- sbuf_free(&so->so_rcv);
- sbuf_free(&so->so_snd);
- sofree(so);
- tcpstat.tcps_closed++;
- return ((struct tcpcb *)0);
-}
-
-void
-tcp_drain()
-{
- /* XXX */
-}
-
-/*
- * When a source quench is received, close congestion window
- * to one segment. We will gradually open it again as we proceed.
- */
-
-#ifdef notdef
-
-void
-tcp_quench(i, errno)
-
- int errno;
-{
- struct tcpcb *tp = intotcpcb(inp);
-
- if (tp)
- tp->snd_cwnd = tp->t_maxseg;
-}
-
-#endif /* notdef */
-
-/*
- * TCP protocol interface to socket abstraction.
- */
-
-/*
- * User issued close, and wish to trail through shutdown states:
- * if never received SYN, just forget it. If got a SYN from peer,
- * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
- * If already got a FIN from peer, then almost done; go to LAST_ACK
- * state. In all other cases, have already sent FIN to peer (e.g.
- * after PRU_SHUTDOWN), and just have to play tedious game waiting
- * for peer to send FIN or not respond to keep-alives, etc.
- * We can let the user exit from the close as soon as the FIN is acked.
- */
-void
-tcp_sockclosed(tp)
- struct tcpcb *tp;
-{
-
- DEBUG_CALL("tcp_sockclosed");
- DEBUG_ARG("tp = %lx", (long)tp);
-
- switch (tp->t_state) {
-
- case TCPS_CLOSED:
- case TCPS_LISTEN:
- case TCPS_SYN_SENT:
- tp->t_state = TCPS_CLOSED;
- tp = tcp_close(tp);
- break;
-
- case TCPS_SYN_RECEIVED:
- case TCPS_ESTABLISHED:
- tp->t_state = TCPS_FIN_WAIT_1;
- break;
-
- case TCPS_CLOSE_WAIT:
- tp->t_state = TCPS_LAST_ACK;
- break;
- }
-/* soisfdisconnecting(tp->t_socket); */
- if (tp && tp->t_state >= TCPS_FIN_WAIT_2)
- soisfdisconnected(tp->t_socket);
- if (tp)
- tcp_output(tp);
-}
-
-static void
-tcp_proxy_event( struct socket* so,
- int s,
- ProxyEvent event )
-{
- so->so_state &= ~SS_PROXIFIED;
-
- if (event == PROXY_EVENT_CONNECTED) {
- so->s = s;
- so->so_state &= ~(SS_ISFCONNECTING);
- }
- else {
- so->so_state = SS_NOFDREF;
- }
-
- /* continue the connect */
- tcp_input(NULL, sizeof(struct ip), so);
-}
-
-/*
- * Connect to a host on the Internet
- * Called by tcp_input
- * Only do a connect, the tcp fields will be set in tcp_input
- * return 0 if there's a result of the connect,
- * else return -1 means we're still connecting
- * The return value is almost always -1 since the socket is
- * nonblocking. Connect returns after the SYN is sent, and does
- * not wait for ACK+SYN.
- */
-int tcp_fconnect(so)
- struct socket *so;
-{
- int ret=0;
- int try_proxy = 1;
- struct sockaddr_in addr;
-
- DEBUG_CALL("tcp_fconnect");
- DEBUG_ARG("so = %lx", (long )so);
-
- addr.sin_family = AF_INET;
- addr.sin_addr = so->so_faddr;
- addr.sin_port = so->so_fport;
-
- if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
- /* It's an alias */
- int last_byte = ntohl(so->so_faddr.s_addr) & 0xff;
-
- if (CTL_IS_DNS(last_byte))
- addr.sin_addr = dns_addr[last_byte - CTL_DNS];
- else
- addr.sin_addr = loopback_addr;
- try_proxy = 0;
- }
-
- DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, "
- "addr.sin_addr.s_addr=%.16s proxy=%d\n",
- ntohs(addr.sin_port), inet_ntoa(addr.sin_addr),
- try_proxy));
-
- if (try_proxy) {
- if (!proxy_manager_add(&addr, SOCK_STREAM, (ProxyEventFunc) tcp_proxy_event, so)) {
- soisfconnecting(so);
- so->s = -1;
- so->so_state |= SS_PROXIFIED;
- return 0;
- }
- }
-
- if ((ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0)
- {
- int s = so->s;
-
- socket_set_nonblock(s);
- socket_set_xreuseaddr(s);
- socket_set_oobinline(s);
-
- /* We don't care what port we get */
- ret = connect(s,(struct sockaddr *)&addr,sizeof (addr));
-
- /*
- * If it's not in progress, it failed, so we just return 0,
- * without clearing SS_NOFDREF
- */
- soisfconnecting(so);
- }
-
- return(ret);
-}
-
-/*
- * Accept the socket and connect to the local-host
- *
- * We have a problem. The correct thing to do would be
- * to first connect to the local-host, and only if the
- * connection is accepted, then do an accept() here.
- * But, a) we need to know who's trying to connect
- * to the socket to be able to SYN the local-host, and
- * b) we are already connected to the foreign host by
- * the time it gets to accept(), so... We simply accept
- * here and SYN the local-host.
- */
-void
-tcp_connect(inso)
- struct socket *inso;
-{
- struct socket *so;
- struct sockaddr_in addr;
- int addrlen = sizeof(struct sockaddr_in);
- struct tcpcb *tp;
- int s;
-
- DEBUG_CALL("tcp_connect");
- DEBUG_ARG("inso = %lx", (long)inso);
-
- /*
- * If it's an SS_ACCEPTONCE socket, no need to socreate()
- * another socket, just use the accept() socket.
- */
- if (inso->so_state & SS_FACCEPTONCE) {
- /* FACCEPTONCE already have a tcpcb */
- so = inso;
- } else {
- if ((so = socreate()) == NULL) {
- /* If it failed, get rid of the pending connection */
- closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen));
- return;
- }
- if (tcp_attach(so) < 0) {
- free(so); /* NOT sofree */
- return;
- }
- so->so_laddr = inso->so_laddr;
- so->so_lport = inso->so_lport;
- }
-
- (void) tcp_mss(sototcpcb(so), 0);
-
- if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) {
- tcp_close(sototcpcb(so)); /* This will sofree() as well */
- return;
- }
- socket_set_nonblock(s);
- socket_set_xreuseaddr(s);
- socket_set_oobinline(s);
- socket_set_lowlatency(s);
-
- so->so_fport = addr.sin_port;
- so->so_faddr = addr.sin_addr;
- /* Translate connections from localhost to the real hostname */
- if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
- so->so_faddr = alias_addr;
-
- /* Close the accept() socket, set right state */
- if (inso->so_state & SS_FACCEPTONCE) {
- socket_close(so->s); /* If we only accept once, close the accept() socket */
- so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */
- /* if it's not FACCEPTONCE, it's already NOFDREF */
- }
- so->s = s;
-
- so->so_iptos = tcp_tos(so);
- tp = sototcpcb(so);
-
- tcp_template(tp);
-
- /* Compute window scaling to request. */
-/* while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
- * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
- * tp->request_r_scale++;
- */
-
-/* soisconnecting(so); */ /* NOFDREF used instead */
- tcpstat.tcps_connattempt++;
-
- tp->t_state = TCPS_SYN_SENT;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->iss = tcp_iss;
- tcp_iss += TCP_ISSINCR/2;
- tcp_sendseqinit(tp);
- tcp_output(tp);
-}
-
-/*
- * Attach a TCPCB to a socket.
- */
-int
-tcp_attach(so)
- struct socket *so;
-{
- if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
- return -1;
-
- insque(so, &tcb);
-
- return 0;
-}
-
-/*
- * Set the socket's type of service field
- */
-struct tos_t tcptos[] = {
- {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */
- {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */
- {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */
- {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */
- {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */
- {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */
- {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */
- {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */
- {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */
- {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */
- {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */
- {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */
- {0, 0, 0, 0}
-};
-
-
-/*
- * Return TOS according to the above table
- */
-u_int8_t
-tcp_tos(so)
- struct socket *so;
-{
- int i = 0;
- struct emu_t *emup;
-
- while(tcptos[i].tos) {
- if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) ||
- (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) {
- so->so_emu = tcptos[i].emu;
- return tcptos[i].tos;
- }
- i++;
- }
-
- return 0;
-}
-
-int do_echo = -1;
-
-/*
- * Emulate programs that try and connect to us
- * This includes ftp (the data connection is
- * initiated by the server) and IRC (DCC CHAT and
- * DCC SEND) for now
- *
- * NOTE: It's possible to crash SLiRP by sending it
- * unstandard strings to emulate... if this is a problem,
- * more checks are needed here
- *
- * XXX Assumes the whole command came in one packet
- *
- * XXX Some ftp clients will have their TOS set to
- * LOWDELAY and so Nagel will kick in. Because of this,
- * we'll get the first letter, followed by the rest, so
- * we simply scan for ORT instead of PORT...
- * DCC doesn't have this problem because there's other stuff
- * in the packet before the DCC command.
- *
- * Return 1 if the mbuf m is still valid and should be
- * sbuf_append()ed
- *
- * NOTE: if you return 0 you MUST mbuf_free() the mbuf!
- */
-int
-tcp_emu(so, m)
- struct socket *so;
- MBuf m;
-{
- u_int n1, n2, n3, n4, n5, n6;
- char buff[256];
- u_int32_t laddr;
- u_int lport;
- char *bptr;
-
- DEBUG_CALL("tcp_emu");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
-
- switch(so->so_emu) {
- int x, i;
-
- case EMU_IDENT:
- /*
- * Identification protocol as per rfc-1413
- */
-
- {
- struct socket *tmpso;
- struct sockaddr_in addr;
- int addrlen = sizeof(struct sockaddr_in);
- SBuf so_rcv = &so->so_rcv;
-
- memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
- so_rcv->sb_wptr += m->m_len;
- so_rcv->sb_rptr += m->m_len;
- m->m_data[m->m_len] = 0; /* NULL terminate */
- if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) {
- if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) {
- HTONS(n1);
- HTONS(n2);
- /* n2 is the one on our host */
- for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
- if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr &&
- tmpso->so_lport == n2 &&
- tmpso->so_faddr.s_addr == so->so_faddr.s_addr &&
- tmpso->so_fport == n1) {
- if (getsockname(tmpso->s,
- (struct sockaddr *)&addr, &addrlen) == 0)
- n2 = ntohs(addr.sin_port);
- break;
- }
- }
- }
- so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2);
- so_rcv->sb_rptr = so_rcv->sb_data;
- so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
- }
- mbuf_free(m);
- return 0;
- }
-
- case EMU_FTP: /* ftp */
- *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */
- if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
- /*
- * Need to emulate the PORT command
- */
- x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
- &n1, &n2, &n3, &n4, &n5, &n6, buff);
- if (x < 6)
- return 1;
-
- laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
- lport = htons((n5 << 8) | (n6));
-
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- n6 = ntohs(so->so_fport);
-
- n5 = (n6 >> 8) & 0xff;
- n6 &= 0xff;
-
- laddr = ntohl(so->so_faddr.s_addr);
-
- n1 = ((laddr >> 24) & 0xff);
- n2 = ((laddr >> 16) & 0xff);
- n3 = ((laddr >> 8) & 0xff);
- n4 = (laddr & 0xff);
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
- n1, n2, n3, n4, n5, n6, x==7?buff:"");
- return 1;
- } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
- /*
- * Need to emulate the PASV response
- */
- x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]",
- &n1, &n2, &n3, &n4, &n5, &n6, buff);
- if (x < 6)
- return 1;
-
- laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
- lport = htons((n5 << 8) | (n6));
-
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- n6 = ntohs(so->so_fport);
-
- n5 = (n6 >> 8) & 0xff;
- n6 &= 0xff;
-
- laddr = ntohl(so->so_faddr.s_addr);
-
- n1 = ((laddr >> 24) & 0xff);
- n2 = ((laddr >> 16) & 0xff);
- n3 = ((laddr >> 8) & 0xff);
- n4 = (laddr & 0xff);
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
- n1, n2, n3, n4, n5, n6, x==7?buff:"");
-
- return 1;
- }
-
- return 1;
-
- case EMU_KSH:
- /*
- * The kshell (Kerberos rsh) and shell services both pass
- * a local port port number to carry signals to the server
- * and stderr to the client. It is passed at the beginning
- * of the connection as a NUL-terminated decimal ASCII string.
- */
- so->so_emu = 0;
- for (lport = 0, i = 0; i < m->m_len-1; ++i) {
- if (m->m_data[i] < '0' || m->m_data[i] > '9')
- return 1; /* invalid number */
- lport *= 10;
- lport += m->m_data[i] - '0';
- }
- if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
- (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
- m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;
- return 1;
-
- case EMU_IRC:
- /*
- * Need to emulate DCC CHAT, DCC SEND and DCC MOVE
- */
- *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */
- if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)
- return 1;
-
- /* The %256s is for the broken mIRC */
- if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
- if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
- return 1;
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",
- (unsigned long)ntohl(so->so_faddr.s_addr),
- ntohs(so->so_fport), 1);
- } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
- if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
- return 1;
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
- buff, (unsigned long)ntohl(so->so_faddr.s_addr),
- ntohs(so->so_fport), n1, 1);
- } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
- if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
- return 1;
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",
- buff, (unsigned long)ntohl(so->so_faddr.s_addr),
- ntohs(so->so_fport), n1, 1);
- }
- return 1;
-
- case EMU_REALAUDIO:
- /*
- * RealAudio emulation - JP. We must try to parse the incoming
- * data and try to find the two characters that contain the
- * port number. Then we redirect an udp port and replace the
- * number with the real port we got.
- *
- * The 1.0 beta versions of the player are not supported
- * any more.
- *
- * A typical packet for player version 1.0 (release version):
- *
- * 0000:50 4E 41 00 05
- * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....�..g�l�c..P
- * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH
- * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v
- * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB
- *
- * Now the port number 0x1BD7 is found at offset 0x04 of the
- * Now the port number 0x1BD7 is found at offset 0x04 of the
- * second packet. This time we received five bytes first and
- * then the rest. You never know how many bytes you get.
- *
- * A typical packet for player version 2.0 (beta):
- *
- * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........�.
- * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux�c..Win2.0.0
- * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/
- * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas
- * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B
- *
- * Port number 0x1BC1 is found at offset 0x0d.
- *
- * This is just a horrible switch statement. Variable ra tells
- * us where we're going.
- */
-
- bptr = m->m_data;
- while (bptr < m->m_data + m->m_len) {
- u_short p;
- static int ra = 0;
- char ra_tbl[4];
-
- ra_tbl[0] = 0x50;
- ra_tbl[1] = 0x4e;
- ra_tbl[2] = 0x41;
- ra_tbl[3] = 0;
-
- switch (ra) {
- case 0:
- case 2:
- case 3:
- if (*bptr++ != ra_tbl[ra]) {
- ra = 0;
- continue;
- }
- break;
-
- case 1:
- /*
- * We may get 0x50 several times, ignore them
- */
- if (*bptr == 0x50) {
- ra = 1;
- bptr++;
- continue;
- } else if (*bptr++ != ra_tbl[ra]) {
- ra = 0;
- continue;
- }
- break;
-
- case 4:
- /*
- * skip version number
- */
- bptr++;
- break;
-
- case 5:
- /*
- * The difference between versions 1.0 and
- * 2.0 is here. For future versions of
- * the player this may need to be modified.
- */
- if (*(bptr + 1) == 0x02)
- bptr += 8;
- else
- bptr += 4;
- break;
-
- case 6:
- /* This is the field containing the port
- * number that RA-player is listening to.
- */
- lport = (((u_char*)bptr)[0] << 8)
- + ((u_char *)bptr)[1];
- if (lport < 6970)
- lport += 256; /* don't know why */
- if (lport < 6970 || lport > 7170)
- return 1; /* failed */
-
- /* try to get udp port between 6970 - 7170 */
- for (p = 6970; p < 7071; p++) {
- if (udp_listen( htons(p),
- so->so_laddr.s_addr,
- htons(lport),
- SS_FACCEPTONCE)) {
- break;
- }
- }
- if (p == 7071)
- p = 0;
- *(u_char *)bptr++ = (p >> 8) & 0xff;
- *(u_char *)bptr++ = p & 0xff;
- ra = 0;
- return 1; /* port redirected, we're done */
- break;
-
- default:
- ra = 0;
- }
- ra++;
- }
- return 1;
-
- default:
- /* Ooops, not emulated, won't call tcp_emu again */
- so->so_emu = 0;
- return 1;
- }
-}
-
-/*
- * Do misc. config of SLiRP while its running.
- * Return 0 if this connections is to be closed, 1 otherwise,
- * return 2 if this is a command-line connection
- */
-int
-tcp_ctl(so)
- struct socket *so;
-{
- SBuf sb = &so->so_snd;
- int command;
- struct ex_list *ex_ptr;
- int do_pty;
- // struct socket *tmpso;
-
- DEBUG_CALL("tcp_ctl");
- DEBUG_ARG("so = %lx", (long )so);
-
-#if 0
- /*
- * Check if they're authorised
- */
- if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) {
- sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n");
- sb->sb_wptr += sb->sb_cc;
- return 0;
- }
-#endif
- command = (ntohl(so->so_faddr.s_addr) & 0xff);
-
- switch(command) {
- default:
- /*
- * Nothing bound..
- */
- /* tcp_fconnect(so); */
-
- case CTL_ALIAS:
- sb->sb_cc = sprintf(sb->sb_wptr,
- "Error: No application configured.\r\n");
- sb->sb_wptr += sb->sb_cc;
- return(0);
- }
-}
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
deleted file mode 100644
index ad03098..0000000
--- a/slirp/tcp_timer.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93
- * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp
- */
-
-#include <slirp.h>
-
-int tcp_keepidle = TCPTV_KEEP_IDLE;
-int tcp_keepintvl = TCPTV_KEEPINTVL;
-int tcp_maxidle;
-int so_options = DO_KEEPALIVE;
-
-struct tcpstat tcpstat; /* tcp statistics */
-u_int32_t tcp_now; /* for RFC 1323 timestamps */
-
-/*
- * Fast timeout routine for processing delayed acks
- */
-void
-tcp_fasttimo()
-{
- register struct socket *so;
- register struct tcpcb *tp;
-
- DEBUG_CALL("tcp_fasttimo");
-
- so = tcb.so_next;
- if (so)
- for (; so != &tcb; so = so->so_next)
- if ((tp = (struct tcpcb *)so->so_tcpcb) &&
- (tp->t_flags & TF_DELACK)) {
- tp->t_flags &= ~TF_DELACK;
- tp->t_flags |= TF_ACKNOW;
- tcpstat.tcps_delack++;
- (void) tcp_output(tp);
- }
-}
-
-/*
- * Tcp protocol timeout routine called every 500 ms.
- * Updates the timers in all active tcb's and
- * causes finite state machine actions if timers expire.
- */
-void
-tcp_slowtimo()
-{
- register struct socket *ip, *ipnxt;
- register struct tcpcb *tp;
- register int i;
-
- DEBUG_CALL("tcp_slowtimo");
-
- tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
- /*
- * Search through tcb's and update active timers.
- */
- ip = tcb.so_next;
- if (ip == 0)
- return;
- for (; ip != &tcb; ip = ipnxt) {
- ipnxt = ip->so_next;
- tp = sototcpcb(ip);
- if (tp == 0)
- continue;
- for (i = 0; i < TCPT_NTIMERS; i++) {
- if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
- tcp_timers(tp,i);
- if (ipnxt->so_prev != ip)
- goto tpgone;
- }
- }
- tp->t_idle++;
- if (tp->t_rtt)
- tp->t_rtt++;
-tpgone:
- ;
- }
- tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
-#ifdef TCP_COMPAT_42
- if ((int)tcp_iss < 0)
- tcp_iss = 0; /* XXX */
-#endif
- tcp_now++; /* for timestamps */
-}
-
-/*
- * Cancel all timers for TCP tp.
- */
-void
-tcp_canceltimers(tp)
- struct tcpcb *tp;
-{
- register int i;
-
- for (i = 0; i < TCPT_NTIMERS; i++)
- tp->t_timer[i] = 0;
-}
-
-int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
- { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
-
-/*
- * TCP timer processing.
- */
-struct tcpcb *
-tcp_timers(tp, timer)
- register struct tcpcb *tp;
- int timer;
-{
- register int rexmt;
-
- DEBUG_CALL("tcp_timers");
-
- switch (timer) {
-
- /*
- * 2 MSL timeout in shutdown went off. If we're closed but
- * still waiting for peer to close and connection has been idle
- * too long, or if 2MSL time is up from TIME_WAIT, delete connection
- * control block. Otherwise, check again in a bit.
- */
- case TCPT_2MSL:
- if (tp->t_state != TCPS_TIME_WAIT &&
- tp->t_idle <= tcp_maxidle)
- tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
- else
- tp = tcp_close(tp);
- break;
-
- /*
- * Retransmission timer went off. Message has not
- * been acked within retransmit interval. Back off
- * to a longer retransmit interval and retransmit one segment.
- */
- case TCPT_REXMT:
-
- /*
- * XXXXX If a packet has timed out, then remove all the queued
- * packets for that session.
- */
-
- if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
- /*
- * This is a hack to suit our terminal server here at the uni of canberra
- * since they have trouble with zeroes... It usually lets them through
- * unharmed, but under some conditions, it'll eat the zeros. If we
- * keep retransmitting it, it'll keep eating the zeroes, so we keep
- * retransmitting, and eventually the connection dies...
- * (this only happens on incoming data)
- *
- * So, if we were gonna drop the connection from too many retransmits,
- * don't... instead halve the t_maxseg, which might break up the NULLs and
- * let them through
- *
- * *sigh*
- */
-
- tp->t_maxseg >>= 1;
- if (tp->t_maxseg < 32) {
- /*
- * We tried our best, now the connection must die!
- */
- tp->t_rxtshift = TCP_MAXRXTSHIFT;
- tcpstat.tcps_timeoutdrop++;
- tp = tcp_drop(tp, tp->t_softerror);
- /* tp->t_softerror : ETIMEDOUT); */ /* XXX */
- return (tp); /* XXX */
- }
-
- /*
- * Set rxtshift to 6, which is still at the maximum
- * backoff time
- */
- tp->t_rxtshift = 6;
- }
- tcpstat.tcps_rexmttimeo++;
- rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
- TCPT_RANGESET(tp->t_rxtcur, rexmt,
- (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- /*
- * If losing, let the lower level know and try for
- * a better route. Also, if we backed off this far,
- * our srtt estimate is probably bogus. Clobber it
- * so we'll take the next rtt measurement as our srtt;
- * move the current srtt into rttvar to keep the current
- * retransmit times until then.
- */
- if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
-/* in_losing(tp->t_inpcb); */
- tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
- tp->t_srtt = 0;
- }
- tp->snd_nxt = tp->snd_una;
- /*
- * If timing a segment in this window, stop the timer.
- */
- tp->t_rtt = 0;
- /*
- * Close the congestion window down to one segment
- * (we'll open it by one segment for each ack we get).
- * Since we probably have a window's worth of unacked
- * data accumulated, this "slow start" keeps us from
- * dumping all that data as back-to-back packets (which
- * might overwhelm an intermediate gateway).
- *
- * There are two phases to the opening: Initially we
- * open by one mss on each ack. This makes the window
- * size increase exponentially with time. If the
- * window is larger than the path can handle, this
- * exponential growth results in dropped packet(s)
- * almost immediately. To get more time between
- * drops but still "push" the network to take advantage
- * of improving conditions, we switch from exponential
- * to linear window opening at some threshold size.
- * For a threshold, we use half the current window
- * size, truncated to a multiple of the mss.
- *
- * (the minimum cwnd that will give us exponential
- * growth is 2 mss. We don't allow the threshold
- * to go below this.)
- */
- {
- u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
- if (win < 2)
- win = 2;
- tp->snd_cwnd = tp->t_maxseg;
- tp->snd_ssthresh = win * tp->t_maxseg;
- tp->t_dupacks = 0;
- }
- (void) tcp_output(tp);
- break;
-
- /*
- * Persistence timer into zero window.
- * Force a byte to be output, if possible.
- */
- case TCPT_PERSIST:
- tcpstat.tcps_persisttimeo++;
- tcp_setpersist(tp);
- tp->t_force = 1;
- (void) tcp_output(tp);
- tp->t_force = 0;
- break;
-
- /*
- * Keep-alive timer went off; send something
- * or drop connection if idle for too long.
- */
- case TCPT_KEEP:
- tcpstat.tcps_keeptimeo++;
- if (tp->t_state < TCPS_ESTABLISHED)
- goto dropit;
-
-/* if (tp->t_socket->so_options & SO_KEEPALIVE && */
- if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) {
- if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
- goto dropit;
- /*
- * Send a packet designed to force a response
- * if the peer is up and reachable:
- * either an ACK if the connection is still alive,
- * or an RST if the peer has closed the connection
- * due to timeout or reboot.
- * Using sequence number tp->snd_una-1
- * causes the transmitted zero-length segment
- * to lie outside the receive window;
- * by the protocol spec, this requires the
- * correspondent TCP to respond.
- */
- tcpstat.tcps_keepprobe++;
-#ifdef TCP_COMPAT_42
- /*
- * The keepalive packet must have nonzero length
- * to get a 4.2 host to respond.
- */
- tcp_respond(tp, &tp->t_template, (MBuf )NULL,
- tp->rcv_nxt - 1, tp->snd_una - 1, 0);
-#else
- tcp_respond(tp, &tp->t_template, (MBuf )NULL,
- tp->rcv_nxt, tp->snd_una - 1, 0);
-#endif
- tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
- } else
- tp->t_timer[TCPT_KEEP] = tcp_keepidle;
- break;
-
- dropit:
- tcpstat.tcps_keepdrops++;
- tp = tcp_drop(tp, 0); /* ETIMEDOUT); */
- break;
- }
-
- return (tp);
-}
diff --git a/slirp/tcp_timer.h b/slirp/tcp_timer.h
deleted file mode 100644
index 59933bc..0000000
--- a/slirp/tcp_timer.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93
- * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp
- */
-
-#ifndef _TCP_TIMER_H_
-#define _TCP_TIMER_H_
-
-/*
- * Definitions of the TCP timers. These timers are counted
- * down PR_SLOWHZ times a second.
- */
-#define TCPT_NTIMERS 4
-
-#define TCPT_REXMT 0 /* retransmit */
-#define TCPT_PERSIST 1 /* retransmit persistence */
-#define TCPT_KEEP 2 /* keep alive */
-#define TCPT_2MSL 3 /* 2*msl quiet time timer */
-
-/*
- * The TCPT_REXMT timer is used to force retransmissions.
- * The TCP has the TCPT_REXMT timer set whenever segments
- * have been sent for which ACKs are expected but not yet
- * received. If an ACK is received which advances tp->snd_una,
- * then the retransmit timer is cleared (if there are no more
- * outstanding segments) or reset to the base value (if there
- * are more ACKs expected). Whenever the retransmit timer goes off,
- * we retransmit one unacknowledged segment, and do a backoff
- * on the retransmit timer.
- *
- * The TCPT_PERSIST timer is used to keep window size information
- * flowing even if the window goes shut. If all previous transmissions
- * have been acknowledged (so that there are no retransmissions in progress),
- * and the window is too small to bother sending anything, then we start
- * the TCPT_PERSIST timer. When it expires, if the window is nonzero,
- * we go to transmit state. Otherwise, at intervals send a single byte
- * into the peer's window to force him to update our window information.
- * We do this at most as often as TCPT_PERSMIN time intervals,
- * but no more frequently than the current estimate of round-trip
- * packet time. The TCPT_PERSIST timer is cleared whenever we receive
- * a window update from the peer.
- *
- * The TCPT_KEEP timer is used to keep connections alive. If an
- * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time,
- * but not yet established, then we drop the connection. Once the connection
- * is established, if the connection is idle for TCPTV_KEEP_IDLE time
- * (and keepalives have been enabled on the socket), we begin to probe
- * the connection. We force the peer to send us a segment by sending:
- * <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
- * This segment is (deliberately) outside the window, and should elicit
- * an ack segment in response from the peer. If, despite the TCPT_KEEP
- * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE
- * amount of time probing, then we drop the connection.
- */
-
-/*
- * Time constants.
- */
-#define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */
-
-#define TCPTV_SRTTBASE 0 /* base roundtrip time;
- if 0, no idea yet */
-#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */
-
-#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */
-#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */
-
-#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */
-#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */
-#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */
-#define TCPTV_KEEPCNT 8 /* max probes before drop */
-
-#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */
-/* #define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) */ /* max allowable REXMT value */
-#define TCPTV_REXMTMAX ( 12*PR_SLOWHZ) /* max allowable REXMT value */
-
-#define TCP_LINGERTIME 120 /* linger at most 2 minutes */
-
-#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
-
-
-#ifdef TCPTIMERS
-char *tcptimers[] =
- { "REXMT", "PERSIST", "KEEP", "2MSL" };
-#endif
-
-/*
- * Force a time value to be in a certain range.
- */
-#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \
- (tv) = (value); \
- if ((tv) < (tvmin)) \
- (tv) = (tvmin); \
- else if ((tv) > (tvmax)) \
- (tv) = (tvmax); \
-}
-
-extern int tcp_keepidle; /* time before keepalive probes begin */
-extern int tcp_keepintvl; /* time between keepalive probes */
-extern int tcp_maxidle; /* time to drop after starting probes */
-extern int tcp_ttl; /* time to live for TCP segs */
-extern int tcp_backoff[];
-
-struct tcpcb;
-
-void tcp_fasttimo _P((void));
-void tcp_slowtimo _P((void));
-void tcp_canceltimers _P((struct tcpcb *));
-struct tcpcb * tcp_timers _P((register struct tcpcb *, int));
-
-#endif
diff --git a/slirp/tcp_var.h b/slirp/tcp_var.h
deleted file mode 100644
index b30a15d..0000000
--- a/slirp/tcp_var.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94
- * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp
- */
-
-#ifndef _TCP_VAR_H_
-#define _TCP_VAR_H_
-
-#include "mbuf.h"
-#include "tcpip.h"
-#include "tcp_timer.h"
-
-#if SIZEOF_CHAR_P == 4
- typedef struct tcpiphdr *tcpiphdrp_32;
-#else
- typedef u_int32_t tcpiphdrp_32;
-#endif
-
-/*
- * Tcp control block, one per tcp; fields:
- */
-struct tcpcb {
- tcpiphdrp_32 seg_next; /* sequencing queue */
- tcpiphdrp_32 seg_prev;
- short t_state; /* state of this connection */
- short t_timer[TCPT_NTIMERS]; /* tcp timers */
- short t_rxtshift; /* log(2) of rexmt exp. backoff */
- short t_rxtcur; /* current retransmit value */
- short t_dupacks; /* consecutive dup acks recd */
- u_short t_maxseg; /* maximum segment size */
- char t_force; /* 1 if forcing out a byte */
- u_short t_flags;
-#define TF_ACKNOW 0x0001 /* ack peer immediately */
-#define TF_DELACK 0x0002 /* ack, but try to delay it */
-#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */
-#define TF_NOOPT 0x0008 /* don't use tcp options */
-#define TF_SENTFIN 0x0010 /* have sent FIN */
-#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */
-#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */
-#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */
-#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */
-#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */
-
- /* Make it static for now */
-/* struct tcpiphdr *t_template; / * skeletal packet for transmit */
- struct tcpiphdr t_template;
-
- struct socket *t_socket; /* back pointer to socket */
-/*
- * The following fields are used as in the protocol specification.
- * See RFC783, Dec. 1981, page 21.
- */
-/* send sequence variables */
- tcp_seq snd_una; /* send unacknowledged */
- tcp_seq snd_nxt; /* send next */
- tcp_seq snd_up; /* send urgent pointer */
- tcp_seq snd_wl1; /* window update seg seq number */
- tcp_seq snd_wl2; /* window update seg ack number */
- tcp_seq iss; /* initial send sequence number */
- u_int32_t snd_wnd; /* send window */
-/* receive sequence variables */
- u_int32_t rcv_wnd; /* receive window */
- tcp_seq rcv_nxt; /* receive next */
- tcp_seq rcv_up; /* receive urgent pointer */
- tcp_seq irs; /* initial receive sequence number */
-/*
- * Additional variables for this implementation.
- */
-/* receive variables */
- tcp_seq rcv_adv; /* advertised window */
-/* retransmit variables */
- tcp_seq snd_max; /* highest sequence number sent;
- * used to recognize retransmits
- */
-/* congestion control (for slow start, source quench, retransmit after loss) */
- u_int32_t snd_cwnd; /* congestion-controlled window */
- u_int32_t snd_ssthresh; /* snd_cwnd size threshold for
- * for slow start exponential to
- * linear switch
- */
-/*
- * transmit timing stuff. See below for scale of srtt and rttvar.
- * "Variance" is actually smoothed difference.
- */
- short t_idle; /* inactivity time */
- short t_rtt; /* round trip time */
- tcp_seq t_rtseq; /* sequence number being timed */
- short t_srtt; /* smoothed round-trip time */
- short t_rttvar; /* variance in round-trip time */
- u_short t_rttmin; /* minimum rtt allowed */
- u_int32_t max_sndwnd; /* largest window peer has offered */
-
-/* out-of-band data */
- char t_oobflags; /* have some */
- char t_iobc; /* input character */
-#define TCPOOB_HAVEDATA 0x01
-#define TCPOOB_HADDATA 0x02
- short t_softerror; /* possible error not yet reported */
-
-/* RFC 1323 variables */
- u_char snd_scale; /* window scaling for send window */
- u_char rcv_scale; /* window scaling for recv window */
- u_char request_r_scale; /* pending window scaling */
- u_char requested_s_scale;
- u_int32_t ts_recent; /* timestamp echo data */
- u_int32_t ts_recent_age; /* when last updated */
- tcp_seq last_ack_sent;
-
-};
-
-#define sototcpcb(so) ((so)->so_tcpcb)
-
-/*
- * The smoothed round-trip time and estimated variance
- * are stored as fixed point numbers scaled by the values below.
- * For convenience, these scales are also used in smoothing the average
- * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
- * With these scales, srtt has 3 bits to the right of the binary point,
- * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the
- * binary point, and is smoothed with an ALPHA of 0.75.
- */
-#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */
-#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */
-#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */
-#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */
-
-/*
- * The initial retransmission should happen at rtt + 4 * rttvar.
- * Because of the way we do the smoothing, srtt and rttvar
- * will each average +1/2 tick of bias. When we compute
- * the retransmit timer, we want 1/2 tick of rounding and
- * 1 extra tick because of +-1/2 tick uncertainty in the
- * firing of the timer. The bias will give us exactly the
- * 1.5 tick we need. But, because the bias is
- * statistical, we have to test that we don't drop below
- * the minimum feasible timer (which is 2 ticks).
- * This macro assumes that the value of TCP_RTTVAR_SCALE
- * is the same as the multiplier for rttvar.
- */
-#define TCP_REXMTVAL(tp) \
- (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
-
-/* XXX
- * We want to avoid doing m_pullup on incoming packets but that
- * means avoiding MBUF_FROM on the tcp reassembly code. That in turn means
- * keeping an mbuf pointer in the reassembly queue (since we might
- * have a cluster). As a quick hack, the source & destination
- * port numbers (which are no longer needed once we've located the
- * tcpcb) are overlayed with an mbuf pointer.
- */
-#if SIZEOF_CHAR_P == 4
-typedef MBuf mbufp_32;
-#else
-typedef u_int32_t mbufp_32;
-#endif
-#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
-
-/*
- * TCP statistics.
- * Many of these should be kept per connection,
- * but that's inconvenient at the moment.
- */
-struct tcpstat {
- u_long tcps_connattempt; /* connections initiated */
- u_long tcps_accepts; /* connections accepted */
- u_long tcps_connects; /* connections established */
- u_long tcps_drops; /* connections dropped */
- u_long tcps_conndrops; /* embryonic connections dropped */
- u_long tcps_closed; /* conn. closed (includes drops) */
- u_long tcps_segstimed; /* segs where we tried to get rtt */
- u_long tcps_rttupdated; /* times we succeeded */
- u_long tcps_delack; /* delayed acks sent */
- u_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */
- u_long tcps_rexmttimeo; /* retransmit timeouts */
- u_long tcps_persisttimeo; /* persist timeouts */
- u_long tcps_keeptimeo; /* keepalive timeouts */
- u_long tcps_keepprobe; /* keepalive probes sent */
- u_long tcps_keepdrops; /* connections dropped in keepalive */
-
- u_long tcps_sndtotal; /* total packets sent */
- u_long tcps_sndpack; /* data packets sent */
- u_long tcps_sndbyte; /* data bytes sent */
- u_long tcps_sndrexmitpack; /* data packets retransmitted */
- u_long tcps_sndrexmitbyte; /* data bytes retransmitted */
- u_long tcps_sndacks; /* ack-only packets sent */
- u_long tcps_sndprobe; /* window probes sent */
- u_long tcps_sndurg; /* packets sent with URG only */
- u_long tcps_sndwinup; /* window update-only packets sent */
- u_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */
-
- u_long tcps_rcvtotal; /* total packets received */
- u_long tcps_rcvpack; /* packets received in sequence */
- u_long tcps_rcvbyte; /* bytes received in sequence */
- u_long tcps_rcvbadsum; /* packets received with ccksum errs */
- u_long tcps_rcvbadoff; /* packets received with bad offset */
-/* u_long tcps_rcvshort; */ /* packets received too short */
- u_long tcps_rcvduppack; /* duplicate-only packets received */
- u_long tcps_rcvdupbyte; /* duplicate-only bytes received */
- u_long tcps_rcvpartduppack; /* packets with some duplicate data */
- u_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */
- u_long tcps_rcvoopack; /* out-of-order packets received */
- u_long tcps_rcvoobyte; /* out-of-order bytes received */
- u_long tcps_rcvpackafterwin; /* packets with data after window */
- u_long tcps_rcvbyteafterwin; /* bytes rcvd after window */
- u_long tcps_rcvafterclose; /* packets rcvd after "close" */
- u_long tcps_rcvwinprobe; /* rcvd window probe packets */
- u_long tcps_rcvdupack; /* rcvd duplicate acks */
- u_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */
- u_long tcps_rcvackpack; /* rcvd ack packets */
- u_long tcps_rcvackbyte; /* bytes acked by rcvd acks */
- u_long tcps_rcvwinupd; /* rcvd window update packets */
-/* u_long tcps_pawsdrop; */ /* segments dropped due to PAWS */
- u_long tcps_predack; /* times hdr predict ok for acks */
- u_long tcps_preddat; /* times hdr predict ok for data pkts */
- u_long tcps_socachemiss; /* tcp_last_so misses */
- u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */
-};
-
-extern struct tcpstat tcpstat; /* tcp statistics */
-extern u_int32_t tcp_now; /* for RFC 1323 timestamps */
-
-#endif
diff --git a/slirp/tcpip.h b/slirp/tcpip.h
deleted file mode 100644
index 82708b0..0000000
--- a/slirp/tcpip.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcpip.h 8.1 (Berkeley) 6/10/93
- * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp
- */
-
-#ifndef _TCPIP_H_
-#define _TCPIP_H_
-
-/*
- * Tcp+ip header, after ip options removed.
- */
-struct tcpiphdr {
- struct ipovly ti_i; /* overlaid ip structure */
- struct tcphdr ti_t; /* tcp header */
-};
-#define ti_next ti_i.ih_next
-#define ti_prev ti_i.ih_prev
-#define ti_x1 ti_i.ih_x1
-#define ti_pr ti_i.ih_pr
-#define ti_len ti_i.ih_len
-#define ti_src ti_i.ih_src
-#define ti_dst ti_i.ih_dst
-#define ti_sport ti_t.th_sport
-#define ti_dport ti_t.th_dport
-#define ti_seq ti_t.th_seq
-#define ti_ack ti_t.th_ack
-#define ti_x2 ti_t.th_x2
-#define ti_off ti_t.th_off
-#define ti_flags ti_t.th_flags
-#define ti_win ti_t.th_win
-#define ti_sum ti_t.th_sum
-#define ti_urp ti_t.th_urp
-
-/*
- * Just a clean way to get to the first byte
- * of the packet
- */
-struct tcpiphdr_2 {
- struct tcpiphdr dummy;
- char first_char;
-};
-
-#endif
diff --git a/slirp/tftp.c b/slirp/tftp.c
deleted file mode 100644
index 8af404a..0000000
--- a/slirp/tftp.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * tftp.c - a simple, read-only tftp server for qemu
- *
- * Copyright (c) 2004 Magnus Damm <damm@opensource.se>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <slirp.h>
-
-struct tftp_session {
- int in_use;
- unsigned char filename[TFTP_FILENAME_MAX];
-
- struct in_addr client_ip;
- u_int16_t client_port;
-
- int timestamp;
-};
-
-struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
-
-const char *tftp_prefix;
-
-static void tftp_session_update(struct tftp_session *spt)
-{
- spt->timestamp = curtime;
- spt->in_use = 1;
-}
-
-static void tftp_session_terminate(struct tftp_session *spt)
-{
- spt->in_use = 0;
-}
-
-static int tftp_session_allocate(struct tftp_t *tp)
-{
- struct tftp_session *spt;
- int k;
-
- for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
- spt = &tftp_sessions[k];
-
- if (!spt->in_use)
- goto found;
-
- /* sessions time out after 5 inactive seconds */
- if ((int)(curtime - spt->timestamp) > 5000)
- goto found;
- }
-
- return -1;
-
- found:
- memset(spt, 0, sizeof(*spt));
- memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip));
- spt->client_port = tp->udp.uh_sport;
-
- tftp_session_update(spt);
-
- return k;
-}
-
-static int tftp_session_find(struct tftp_t *tp)
-{
- struct tftp_session *spt;
- int k;
-
- for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
- spt = &tftp_sessions[k];
-
- if (spt->in_use) {
- if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) {
- if (spt->client_port == tp->udp.uh_sport) {
- return k;
- }
- }
- }
- }
-
- return -1;
-}
-
-static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr,
- u_int8_t *buf, int len)
-{
- int fd;
- int bytes_read = 0;
- char buffer[1024];
- int n;
-
- n = snprintf(buffer, sizeof(buffer), "%s/%s",
- tftp_prefix, spt->filename);
- if (n >= sizeof(buffer))
- return -1;
-
- fd = open(buffer, O_RDONLY | O_BINARY);
-
- if (fd < 0) {
- return -1;
- }
-
- if (len) {
- lseek(fd, block_nr * 512, SEEK_SET);
-
- bytes_read = read(fd, buf, len);
- }
-
- close(fd);
-
- return bytes_read;
-}
-
-static int tftp_send_oack(struct tftp_session *spt,
- const char *key, uint32_t value,
- struct tftp_t *recv_tp)
-{
- struct sockaddr_in saddr, daddr;
- MBuf m;
- struct tftp_t *tp;
- int n = 0;
-
- m = mbuf_alloc();
-
- if (!m)
- return -1;
-
- memset(m->m_data, 0, m->m_size);
-
- m->m_data += if_maxlinkhdr;
- tp = (void *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
-
- tp->tp_op = htons(TFTP_OACK);
- n += sprintf((char*)tp->x.tp_buf + n, "%s", key) + 1;
- n += sprintf((char*)tp->x.tp_buf + n, "%u", value) + 1;
-
- saddr.sin_addr = recv_tp->ip.ip_dst;
- saddr.sin_port = recv_tp->udp.uh_dport;
-
- daddr.sin_addr = spt->client_ip;
- daddr.sin_port = spt->client_port;
-
- m->m_len = sizeof(struct tftp_t) - 514 + n -
- sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-
- return 0;
-}
-
-
-
-static int tftp_send_error(struct tftp_session *spt,
- u_int16_t errorcode, const char *msg,
- struct tftp_t *recv_tp)
-{
- struct sockaddr_in saddr, daddr;
- MBuf m;
- struct tftp_t *tp;
- int nobytes;
-
- m = mbuf_alloc();
-
- if (!m) {
- return -1;
- }
-
- memset(m->m_data, 0, m->m_size);
-
- m->m_data += if_maxlinkhdr;
- tp = (void *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
-
- tp->tp_op = htons(TFTP_ERROR);
- tp->x.tp_error.tp_error_code = htons(errorcode);
- strcpy((char*)tp->x.tp_error.tp_msg, msg);
-
- saddr.sin_addr = recv_tp->ip.ip_dst;
- saddr.sin_port = recv_tp->udp.uh_dport;
-
- daddr.sin_addr = spt->client_ip;
- daddr.sin_port = spt->client_port;
-
- nobytes = 2;
-
- m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
- sizeof(struct ip) - sizeof(struct udphdr);
-
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-
- tftp_session_terminate(spt);
-
- return 0;
-}
-
-static int tftp_send_data(struct tftp_session *spt,
- u_int16_t block_nr,
- struct tftp_t *recv_tp)
-{
- struct sockaddr_in saddr, daddr;
- MBuf m;
- struct tftp_t *tp;
- int nobytes;
-
- if (block_nr < 1) {
- return -1;
- }
-
- m = mbuf_alloc();
-
- if (!m) {
- return -1;
- }
-
- memset(m->m_data, 0, m->m_size);
-
- m->m_data += if_maxlinkhdr;
- tp = (void *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
-
- tp->tp_op = htons(TFTP_DATA);
- tp->x.tp_data.tp_block_nr = htons(block_nr);
-
- saddr.sin_addr = recv_tp->ip.ip_dst;
- saddr.sin_port = recv_tp->udp.uh_dport;
-
- daddr.sin_addr = spt->client_ip;
- daddr.sin_port = spt->client_port;
-
- nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);
-
- if (nobytes < 0) {
- mbuf_free(m);
-
- /* send "file not found" error back */
-
- tftp_send_error(spt, 1, "File not found", tp);
-
- return -1;
- }
-
- m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
- sizeof(struct ip) - sizeof(struct udphdr);
-
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-
- if (nobytes == 512) {
- tftp_session_update(spt);
- }
- else {
- tftp_session_terminate(spt);
- }
-
- return 0;
-}
-
-static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
-{
- struct tftp_session *spt;
- int s, k, n;
- u_int8_t *src, *dst;
-
- s = tftp_session_allocate(tp);
-
- if (s < 0) {
- return;
- }
-
- spt = &tftp_sessions[s];
-
- src = tp->x.tp_buf;
- dst = spt->filename;
- n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
-
- /* get name */
-
- for (k = 0; k < n; k++) {
- if (k < TFTP_FILENAME_MAX) {
- dst[k] = src[k];
- }
- else {
- return;
- }
-
- if (src[k] == '\0') {
- break;
- }
- }
-
- if (k >= n) {
- return;
- }
-
- k++;
-
- /* check mode */
- if ((n - k) < 6) {
- return;
- }
-
- if (memcmp(&src[k], "octet\0", 6) != 0) {
- tftp_send_error(spt, 4, "Unsupported transfer mode", tp);
- return;
- }
-
- k += 6; /* skipping octet */
-
- /* do sanity checks on the filename */
-
- if ((spt->filename[0] != '/')
- || (spt->filename[strlen((const char*)spt->filename) - 1] == '/')
- || strstr((const char*)spt->filename, "/../")) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- /* only allow exported prefixes */
-
- if (!tftp_prefix) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- /* check if the file exists */
-
- if (tftp_read_data(spt, 0, spt->filename, 0) < 0) {
- tftp_send_error(spt, 1, "File not found", tp);
- return;
- }
-
- if (src[n - 1] != 0) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- while (k < n) {
- const char *key, *value;
-
- key = (const char*)src + k;
- k += strlen(key) + 1;
-
- if (k >= n) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- value = (const char*)src + k;
- k += strlen(value) + 1;
-
- if (strcmp(key, "tsize") == 0) {
- int tsize = atoi(value);
- struct stat stat_p;
-
- if (tsize == 0 && tftp_prefix) {
- char buffer[1024];
- int len;
-
- len = snprintf(buffer, sizeof(buffer), "%s/%s",
- tftp_prefix, spt->filename);
-
- if (stat(buffer, &stat_p) == 0)
- tsize = stat_p.st_size;
- else {
- tftp_send_error(spt, 1, "File not found", tp);
- return;
- }
- }
-
- tftp_send_oack(spt, "tsize", tsize, tp);
- }
- }
-
- tftp_send_data(spt, 1, tp);
-}
-
-static void tftp_handle_ack(struct tftp_t *tp, int pktlen)
-{
- int s;
-
- s = tftp_session_find(tp);
-
- if (s < 0) {
- return;
- }
-
- if (tftp_send_data(&tftp_sessions[s],
- ntohs(tp->x.tp_data.tp_block_nr) + 1,
- tp) < 0) {
- return;
- }
-}
-
-void tftp_input(MBuf m)
-{
- struct tftp_t *tp = (struct tftp_t *)m->m_data;
-
- switch(ntohs(tp->tp_op)) {
- case TFTP_RRQ:
- tftp_handle_rrq(tp, m->m_len);
- break;
-
- case TFTP_ACK:
- tftp_handle_ack(tp, m->m_len);
- break;
- }
-}
diff --git a/slirp/tftp.h b/slirp/tftp.h
deleted file mode 100644
index 06018a7..0000000
--- a/slirp/tftp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* tftp defines */
-
-#define TFTP_SESSIONS_MAX 3
-
-#define TFTP_SERVER 69
-
-#define TFTP_RRQ 1
-#define TFTP_WRQ 2
-#define TFTP_DATA 3
-#define TFTP_ACK 4
-#define TFTP_ERROR 5
-#define TFTP_OACK 6
-
-#define TFTP_FILENAME_MAX 512
-
-struct tftp_t {
- struct ip ip;
- struct udphdr udp;
- u_int16_t tp_op;
- union {
- struct {
- u_int16_t tp_block_nr;
- u_int8_t tp_buf[512];
- } tp_data;
- struct {
- u_int16_t tp_error_code;
- u_int8_t tp_msg[512];
- } tp_error;
- u_int8_t tp_buf[512 + 2];
- } x;
-};
-
-void tftp_input(MBuf m);
diff --git a/slirp/udp.c b/slirp/udp.c
deleted file mode 100644
index d96251d..0000000
--- a/slirp/udp.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94
- * udp_usrreq.c,v 1.4 1994/10/02 17:48:45 phk Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#include "ip_icmp.h"
-
-struct udpstat udpstat;
-
-struct socket udb;
-
-/*
- * UDP protocol implementation.
- * Per RFC 768, August, 1980.
- */
-#ifndef COMPAT_42
-int udpcksum = 1;
-#else
-int udpcksum = 0; /* XXX */
-#endif
-
-struct socket *udp_last_so = &udb;
-
-void
-udp_init()
-{
- udb.so_next = udb.so_prev = &udb;
-}
-/* m->m_data points at ip packet header
- * m->m_len length ip packet
- * ip->ip_len length data (IPDU)
- */
-void
-udp_input(m, iphlen)
- register MBuf m;
- int iphlen;
-{
- register struct ip *ip;
- register struct udphdr *uh;
-/* MBuf opts = 0;*/
- int len;
- struct ip save_ip;
- struct socket *so;
-
- DEBUG_CALL("udp_input");
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("iphlen = %d", iphlen);
-
- udpstat.udps_ipackets++;
-
- /*
- * Strip IP options, if any; should skip this,
- * make available to user, and use on returned packets,
- * but we don't yet have a way to check the checksum
- * with options still present.
- */
- if(iphlen > sizeof(struct ip)) {
- ip_stripoptions(m, (MBuf )0);
- iphlen = sizeof(struct ip);
- }
-
- /*
- * Get IP and UDP header together in first mbuf.
- */
- ip = MBUF_TO(m, struct ip *);
- uh = (struct udphdr *)((caddr_t)ip + iphlen);
-
- /*
- * Make mbuf data length reflect UDP length.
- * If not enough data to reflect UDP length, drop.
- */
- len = ntohs((u_int16_t)uh->uh_ulen);
-
- if (ip->ip_len != len) {
- if (len > ip->ip_len) {
- udpstat.udps_badlen++;
- goto bad;
- }
- mbuf_trim(m, len - ip->ip_len);
- ip->ip_len = len;
- }
-
- /*
- * Save a copy of the IP header in case we want restore it
- * for sending an ICMP error message in response.
- */
- save_ip = *ip;
- save_ip.ip_len+= iphlen; /* tcp_input subtracts this */
-
- /*
- * Checksum extended UDP header and data.
- */
- if (udpcksum && uh->uh_sum) {
- ((struct ipovly *)ip)->ih_next = 0;
- ((struct ipovly *)ip)->ih_prev = 0;
- ((struct ipovly *)ip)->ih_x1 = 0;
- ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
- /* keep uh_sum for ICMP reply
- * uh->uh_sum = cksum(m, len + sizeof (struct ip));
- * if (uh->uh_sum) {
- */
- if(cksum(m, len + sizeof(struct ip))) {
- udpstat.udps_badsum++;
- goto bad;
- }
- }
-
- /*
- * handle DHCP/BOOTP
- */
- if (ntohs(uh->uh_dport) == BOOTP_SERVER) {
- bootp_input(m);
- goto bad;
- }
-
- /*
- * handle TFTP
- */
- if (ntohs(uh->uh_dport) == TFTP_SERVER) {
- tftp_input(m);
- goto bad;
- }
-
- /*
- * Locate pcb for datagram.
- */
- so = udp_last_so;
- if (so->so_lport != uh->uh_sport ||
- so->so_laddr.s_addr != ip->ip_src.s_addr) {
- struct socket *tmp;
-
- for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) {
- if (tmp->so_lport == uh->uh_sport &&
- tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
- tmp->so_faddr.s_addr = ip->ip_dst.s_addr;
- tmp->so_fport = uh->uh_dport;
- so = tmp;
- break;
- }
- }
- if (tmp == &udb) {
- so = NULL;
- } else {
- udpstat.udpps_pcbcachemiss++;
- udp_last_so = so;
- }
- }
-
- if (so == NULL) {
- /*
- * If there's no socket for this packet,
- * create one
- */
- if ((so = socreate()) == NULL) goto bad;
- if(udp_attach(so) == -1) {
- DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
- errno,strerror(errno)));
- sofree(so);
- goto bad;
- }
-
- /*
- * Setup fields
- */
- /* udp_last_so = so; */
- so->so_laddr = ip->ip_src;
- so->so_lport = uh->uh_sport;
-
- if ((so->so_iptos = udp_tos(so)) == 0)
- so->so_iptos = ip->ip_tos;
-
- /*
- * XXXXX Here, check if it's in udpexec_list,
- * and if it is, do the fork_exec() etc.
- */
- }
-
- so->so_faddr = ip->ip_dst; /* XXX */
- so->so_fport = uh->uh_dport; /* XXX */
-
- iphlen += sizeof(struct udphdr);
- m->m_len -= iphlen;
- m->m_data += iphlen;
-
- /*
- * Now we sendto() the packet.
- */
- if (so->so_emu)
- udp_emu(so, m);
-
- if(sosendto(so,m) == -1) {
- m->m_len += iphlen;
- m->m_data -= iphlen;
- *ip=save_ip;
- DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
- }
-
- mbuf_free(so->so_m); /* used for ICMP if error on sorecvfrom */
-
- /* restore the orig mbuf packet */
- m->m_len += iphlen;
- m->m_data -= iphlen;
- *ip=save_ip;
- so->so_m=m; /* ICMP backup */
-
- return;
-bad:
- mbuf_free(m);
- /* if (opts) mbuf_free(opts); */
- return;
-}
-
-int udp_output2(struct socket *so, MBuf m,
- struct sockaddr_in *saddr, struct sockaddr_in *daddr,
- int iptos)
-{
- register struct udpiphdr *ui;
- int error = 0;
-
- DEBUG_CALL("udp_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr);
- DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr);
-
- /*
- * Adjust for header
- */
- m->m_data -= sizeof(struct udpiphdr);
- m->m_len += sizeof(struct udpiphdr);
-
- /*
- * Fill in mbuf with extended UDP header
- * and addresses and length put into network format.
- */
- ui = MBUF_TO(m, struct udpiphdr *);
- ui->ui_next = ui->ui_prev = 0;
- ui->ui_x1 = 0;
- ui->ui_pr = IPPROTO_UDP;
- ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
- /* XXXXX Check for from-one-location sockets, or from-any-location sockets */
- ui->ui_src = saddr->sin_addr;
- ui->ui_dst = daddr->sin_addr;
- ui->ui_sport = saddr->sin_port;
- ui->ui_dport = daddr->sin_port;
- ui->ui_ulen = ui->ui_len;
-
- /*
- * Stuff checksum and output datagram.
- */
- ui->ui_sum = 0;
- if (udpcksum) {
- if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0)
- ui->ui_sum = 0xffff;
- }
- ((struct ip *)ui)->ip_len = m->m_len;
-
- ((struct ip *)ui)->ip_ttl = ip_defttl;
- ((struct ip *)ui)->ip_tos = iptos;
-
- udpstat.udps_opackets++;
-
- error = ip_output(so, m);
-
- return (error);
-}
-
-int udp_output(struct socket *so, MBuf m,
- struct sockaddr_in *addr)
-
-{
- struct sockaddr_in saddr, daddr;
-
- saddr = *addr;
- if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
- saddr.sin_addr.s_addr = so->so_faddr.s_addr;
- if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff))
- saddr.sin_addr.s_addr = alias_addr.s_addr;
- }
- daddr.sin_addr = so->so_laddr;
- daddr.sin_port = so->so_lport;
-
- return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
-}
-
-int
-udp_attach(so)
- struct socket *so;
-{
- struct sockaddr_in addr;
-
- if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
- /*
- * Here, we bind() the socket. Although not really needed
- * (sendto() on an unbound socket will bind it), it's done
- * here so that emulation of ytalk etc. don't have to do it
- */
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr.s_addr = INADDR_ANY;
- if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) {
- int lasterrno=errno;
- closesocket(so->s);
- so->s=-1;
-#ifdef _WIN32
- WSASetLastError(lasterrno);
-#else
- errno=lasterrno;
-#endif
- } else {
- /* success, insert in queue */
- so->so_expire = curtime + SO_EXPIRE;
- insque(so,&udb);
- }
- }
- return(so->s);
-}
-
-void
-udp_detach(so)
- struct socket *so;
-{
- closesocket(so->s);
- /* if (so->so_m) mbuf_free(so->so_m); done by sofree */
-
- sofree(so);
-}
-
-struct tos_t udptos[] = {
- {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */
- {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */
- {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */
- {0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME}, /* Cu-Seeme */
- {0, 0, 0, 0}
-};
-
-u_int8_t
-udp_tos(so)
- struct socket *so;
-{
- int i = 0;
-
- while(udptos[i].tos) {
- if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) ||
- (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) {
- so->so_emu = udptos[i].emu;
- return udptos[i].tos;
- }
- i++;
- }
-
- return 0;
-}
-
-#ifdef EMULATE_TALK
-#include "talkd.h"
-#endif
-
-/*
- * Here, talk/ytalk/ntalk requests must be emulated
- */
-void
-udp_emu(so, m)
- struct socket *so;
- MBuf m;
-{
- struct sockaddr_in addr;
- int addrlen = sizeof(addr);
-#ifdef EMULATE_TALK
- CTL_MSG_OLD *omsg;
- CTL_MSG *nmsg;
- char buff[sizeof(CTL_MSG)];
- u_char type;
-
-struct talk_request {
- struct talk_request *next;
- struct socket *udp_so;
- struct socket *tcp_so;
-} *req;
-
- static struct talk_request *req_tbl = 0;
-
-#endif
-
-struct cu_header {
- uint16_t d_family; // destination family
- uint16_t d_port; // destination port
- uint32_t d_addr; // destination address
- uint16_t s_family; // source family
- uint16_t s_port; // source port
- uint32_t so_addr; // source address
- uint32_t seqn; // sequence number
- uint16_t message; // message
- uint16_t data_type; // data type
- uint16_t pkt_len; // packet length
-} *cu_head;
-
- switch(so->so_emu) {
-
-#ifdef EMULATE_TALK
- case EMU_TALK:
- case EMU_NTALK:
- /*
- * Talk emulation. We always change the ctl_addr to get
- * some answers from the daemon. When an ANNOUNCE comes,
- * we send LEAVE_INVITE to the local daemons. Also when a
- * DELETE comes, we send copies to the local daemons.
- */
- if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)
- return;
-
-#define IS_OLD (so->so_emu == EMU_TALK)
-
-#define COPY_MSG(dest, src) { dest->type = src->type; \
- dest->id_num = src->id_num; \
- dest->pid = src->pid; \
- dest->addr = src->addr; \
- dest->ctl_addr = src->ctl_addr; \
- memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \
- memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \
- memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); }
-
-#define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field)
-/* old_sockaddr to sockaddr_in */
-
-
- if (IS_OLD) { /* old talk */
- omsg = MBUF_TO(m, CTL_MSG_OLD*);
- nmsg = (CTL_MSG *) buff;
- type = omsg->type;
- OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port;
- OTOSIN(omsg, ctl_addr)->sin_addr = our_addr;
- strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD);
- } else { /* new talk */
- omsg = (CTL_MSG_OLD *) buff;
- nmsg = MBUF_TO(m, CTL_MSG *);
- type = nmsg->type;
- OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port;
- OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr;
- strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD);
- }
-
- if (type == LOOK_UP)
- return; /* for LOOK_UP this is enough */
-
- if (IS_OLD) { /* make a copy of the message */
- COPY_MSG(nmsg, omsg);
- nmsg->vers = 1;
- nmsg->answer = 0;
- } else
- COPY_MSG(omsg, nmsg);
-
- /*
- * If if is an ANNOUNCE message, we go through the
- * request table to see if a tcp port has already
- * been redirected for this socket. If not, we solisten()
- * a new socket and add this entry to the table.
- * The port number of the tcp socket and our IP
- * are put to the addr field of the message structures.
- * Then a LEAVE_INVITE is sent to both local daemon
- * ports, 517 and 518. This is why we have two copies
- * of the message, one in old talk and one in new talk
- * format.
- */
-
- if (type == ANNOUNCE) {
- int s;
- u_short temp_port;
-
- for(req = req_tbl; req; req = req->next)
- if (so == req->udp_so)
- break; /* found it */
-
- if (!req) { /* no entry for so, create new */
- req = (struct talk_request *)
- malloc(sizeof(struct talk_request));
- req->udp_so = so;
- req->tcp_so = solisten(0,
- OTOSIN(omsg, addr)->sin_addr.s_addr,
- OTOSIN(omsg, addr)->sin_port,
- SS_FACCEPTONCE);
- req->next = req_tbl;
- req_tbl = req;
- }
-
- /* replace port number in addr field */
- addrlen = sizeof(addr);
- getsockname(req->tcp_so->s,
- (struct sockaddr *) &addr,
- &addrlen);
- OTOSIN(omsg, addr)->sin_port = addr.sin_port;
- OTOSIN(omsg, addr)->sin_addr = our_addr;
- OTOSIN(nmsg, addr)->sin_port = addr.sin_port;
- OTOSIN(nmsg, addr)->sin_addr = our_addr;
-
- /* send LEAVE_INVITEs */
- temp_port = OTOSIN(omsg, ctl_addr)->sin_port;
- OTOSIN(omsg, ctl_addr)->sin_port = 0;
- OTOSIN(nmsg, ctl_addr)->sin_port = 0;
- omsg->type = nmsg->type = LEAVE_INVITE;
-
- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
- addr.sin_addr = our_addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(517);
- sendto(s, (char *)omsg, sizeof(*omsg), 0,
- (struct sockaddr *)&addr, sizeof(addr));
- addr.sin_port = htons(518);
- sendto(s, (char *)nmsg, sizeof(*nmsg), 0,
- (struct sockaddr *) &addr, sizeof(addr));
- closesocket(s) ;
-
- omsg->type = nmsg->type = ANNOUNCE;
- OTOSIN(omsg, ctl_addr)->sin_port = temp_port;
- OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;
- }
-
- /*
- * If it is a DELETE message, we send a copy to the
- * local daemons. Then we delete the entry corresponding
- * to our socket from the request table.
- */
-
- if (type == DELETE) {
- struct talk_request *temp_req, *req_next;
- int s;
- u_short temp_port;
-
- temp_port = OTOSIN(omsg, ctl_addr)->sin_port;
- OTOSIN(omsg, ctl_addr)->sin_port = 0;
- OTOSIN(nmsg, ctl_addr)->sin_port = 0;
-
- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
- addr.sin_addr = our_addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(517);
- sendto(s, (char *)omsg, sizeof(*omsg), 0,
- (struct sockaddr *)&addr, sizeof(addr));
- addr.sin_port = htons(518);
- sendto(s, (char *)nmsg, sizeof(*nmsg), 0,
- (struct sockaddr *)&addr, sizeof(addr));
- closesocket(s);
-
- OTOSIN(omsg, ctl_addr)->sin_port = temp_port;
- OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;
-
- /* delete table entry */
- if (so == req_tbl->udp_so) {
- temp_req = req_tbl;
- req_tbl = req_tbl->next;
- free(temp_req);
- } else {
- temp_req = req_tbl;
- for(req = req_tbl->next; req; req = req_next) {
- req_next = req->next;
- if (so == req->udp_so) {
- temp_req->next = req_next;
- free(req);
- break;
- } else {
- temp_req = req;
- }
- }
- }
- }
-
- return;
-#endif
-
- case EMU_CUSEEME:
-
- /*
- * Cu-SeeMe emulation.
- * Hopefully the packet is more that 16 bytes long. We don't
- * do any other tests, just replace the address and port
- * fields.
- */
- if (m->m_len >= sizeof (*cu_head)) {
- if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)
- return;
- cu_head = MBUF_TO(m, struct cu_header *);
- cu_head->s_port = addr.sin_port;
- cu_head->so_addr = our_addr.s_addr;
- }
-
- return;
- }
-}
-
-struct socket *
-udp_listen(port, laddr, lport, flags)
- u_int port;
- u_int32_t laddr;
- u_int lport;
- int flags;
-{
- struct sockaddr_in addr;
- struct socket *so;
- int addrlen = sizeof(struct sockaddr_in);
-
- if ((so = socreate()) == NULL) {
- free(so);
- return NULL;
- }
- so->s = socket(AF_INET,SOCK_DGRAM,0);
- so->so_expire = curtime + SO_EXPIRE;
- so->so_hport = port;
- insque(so,&udb);
-
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = port;
-
- if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) {
- udp_detach(so);
- return NULL;
- }
- socket_set_xreuseaddr(so->s);
-
- getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
- so->so_fport = addr.sin_port;
- if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
- so->so_faddr = alias_addr;
- else
- so->so_faddr = addr.sin_addr;
-
- so->so_lport = lport;
- so->so_laddr.s_addr = laddr;
- if (flags != SS_FACCEPTONCE)
- so->so_expire = 0;
-
- so->so_state = SS_ISFCONNECTED;
-
- return so;
-}
-
-int udp_unlisten (u_int port)
-{
- struct socket *so;
-
- for (so = udb.so_next; so != &udb; so = so->so_next) {
- if (so->so_hport == htons(port)) {
- break;
- }
- }
-
- if (so == &udb)
- return -1;
-
- sofcantrcvmore( so );
- sofcantsendmore( so );
- close( so->s );
- so->s = -1;
- sofree( so );
- return 0;
-}
-
-
diff --git a/slirp/udp.h b/slirp/udp.h
deleted file mode 100644
index f59925d..0000000
--- a/slirp/udp.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)udp.h 8.1 (Berkeley) 6/10/93
- * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp
- */
-
-#ifndef _UDP_H_
-#define _UDP_H_
-
-#define UDP_TTL 0x60
-#define UDP_UDPDATALEN 16192
-
-extern struct socket *udp_last_so;
-
-/*
- * Udp protocol header.
- * Per RFC 768, September, 1981.
- */
-struct udphdr {
- u_int16_t uh_sport; /* source port */
- u_int16_t uh_dport; /* destination port */
- int16_t uh_ulen; /* udp length */
- u_int16_t uh_sum; /* udp checksum */
-};
-
-/*
- * UDP kernel structures and variables.
- */
-struct udpiphdr {
- struct ipovly ui_i; /* overlaid ip structure */
- struct udphdr ui_u; /* udp header */
-};
-#define ui_next ui_i.ih_next
-#define ui_prev ui_i.ih_prev
-#define ui_x1 ui_i.ih_x1
-#define ui_pr ui_i.ih_pr
-#define ui_len ui_i.ih_len
-#define ui_src ui_i.ih_src
-#define ui_dst ui_i.ih_dst
-#define ui_sport ui_u.uh_sport
-#define ui_dport ui_u.uh_dport
-#define ui_ulen ui_u.uh_ulen
-#define ui_sum ui_u.uh_sum
-
-struct udpstat {
- /* input statistics: */
- u_long udps_ipackets; /* total input packets */
- u_long udps_hdrops; /* packet shorter than header */
- u_long udps_badsum; /* checksum error */
- u_long udps_badlen; /* data length larger than packet */
- u_long udps_noport; /* no socket on port */
- u_long udps_noportbcast; /* of above, arrived as broadcast */
- u_long udps_fullsock; /* not delivered, input socket full */
- u_long udpps_pcbcachemiss; /* input packets missing pcb cache */
- /* output statistics: */
- u_long udps_opackets; /* total output packets */
-};
-
-/*
- * Names for UDP sysctl objects
- */
-#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
-#define UDPCTL_MAXID 2
-
-extern struct udpstat udpstat;
-extern struct socket udb;
-struct mbuf;
-
-void udp_init _P((void));
-void udp_input _P((register MBuf , int));
-int udp_output _P((struct socket *, MBuf , struct sockaddr_in *));
-int udp_attach _P((struct socket *));
-void udp_detach _P((struct socket *));
-u_int8_t udp_tos _P((struct socket *));
-void udp_emu _P((struct socket *, MBuf ));
-struct socket * udp_listen _P((u_int, u_int32_t, u_int, int));
-int udp_unlisten _P((u_int));
-int udp_output2(struct socket *so, MBuf m,
- struct sockaddr_in *saddr, struct sockaddr_in *daddr,
- int iptos);
-#endif