SLIRP 0.9.1

This commit is contained in:
jvernet 2017-10-03 22:34:56 +02:00
parent 000ec0f135
commit 4682bb80a1
39 changed files with 2299 additions and 2006 deletions

View File

@ -25,6 +25,9 @@ The copyright terms and conditions:
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

View File

@ -38,8 +38,17 @@ typedef struct {
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;
@ -100,6 +109,7 @@ static void dhcp_decode(const uint8_t *buf, int size,
if (p >= p_end)
break;
len = *p++;
dprintf("dhcp: tag=0x%02x len=%d\n", tag, len);
switch(tag) {
case RFC2132_MSG_TYPE:
@ -126,6 +136,7 @@ static void bootp_reply(struct bootp_t *bp)
/* 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 */
@ -138,7 +149,7 @@ static void bootp_reply(struct bootp_t *bp)
if ((m = m_get()) == NULL)
return;
m->m_data += if_maxlinkhdr;
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));
@ -146,8 +157,10 @@ static void bootp_reply(struct bootp_t *bp)
if (dhcp_msg_type == DHCPDISCOVER) {
new_addr:
bc = get_new_addr(&daddr.sin_addr);
if (!bc)
if (!bc) {
dprintf("no address left\n");
return;
}
memcpy(bc->macaddr, client_ethaddr, 6);
} else {
bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
@ -158,6 +171,11 @@ static void bootp_reply(struct bootp_t *bp)
}
}
if (bootp_filename)
snprintf(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);

View File

@ -90,10 +90,6 @@
#define BOOTP_VENDOR_LEN 64
#define DHCP_OPT_LEN 312
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
struct bootp_t {
struct ip ip;
struct udphdr udp;
@ -112,10 +108,6 @@ struct bootp_t {
uint8_t bp_sname[64];
uint8_t bp_file[128];
uint8_t bp_vend[DHCP_OPT_LEN];
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
void bootp_input(struct mbuf *m);

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*

View File

@ -16,8 +16,11 @@ 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 */
#ifndef CONFIG_QEMU
extern struct termios slirp_tty_settings;
extern int slirp_tty_restore;
@ -68,7 +71,9 @@ dump_packet(dat, n)
}
}
#endif
#endif
#ifdef LOG_ENABLED
#if 0
/*
* Statistic routines
@ -78,7 +83,7 @@ dump_packet(dat, n)
* the link as well.
*/
void
static void
ttystats(ttyp)
struct ttys *ttyp;
{
@ -87,9 +92,9 @@ ttystats(ttyp)
lprint(" \r\n");
if (if_comp & IF_COMPRESS)
if (IF_COMP & IF_COMPRESS)
strcpy(buff, "on");
else if (if_comp & IF_NOCOMPRESS)
else if (IF_COMP & IF_NOCOMPRESS)
strcpy(buff, "off");
else
strcpy(buff, "off (for now)");
@ -117,8 +122,8 @@ ttystats(ttyp)
lprint(" %6d bad input packets\r\n", is->in_mbad);
}
void
allttystats()
static void
allttystats(void)
{
struct ttys *ttyp;
@ -127,8 +132,8 @@ allttystats()
}
#endif
void
ipstats()
static void
ipstats(void)
{
lprint(" \r\n");
@ -151,9 +156,9 @@ ipstats()
lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered);
}
#if 0
void
vjstats()
#ifndef CONFIG_QEMU
static void
vjstats(void)
{
lprint(" \r\n");
@ -170,8 +175,8 @@ vjstats()
}
#endif
void
tcpstats()
static void
tcpstats(void)
{
lprint(" \r\n");
@ -238,8 +243,8 @@ tcpstats()
}
void
udpstats()
static void
udpstats(void)
{
lprint(" \r\n");
@ -252,8 +257,8 @@ udpstats()
lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets);
}
void
icmpstats()
static void
icmpstats(void)
{
lprint(" \r\n");
lprint("ICMP stats:\r\n");
@ -265,8 +270,8 @@ icmpstats()
lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
}
void
mbufstats()
static void
mbufstats(void)
{
struct mbuf *m;
int i;
@ -289,10 +294,9 @@ mbufstats()
lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
}
void
sockstats()
static void
sockstats(void)
{
char addr[INET_ADDRSTRLEN];
char buff[256];
int n;
struct socket *so;
@ -310,11 +314,9 @@ sockstats()
buff[17] = 0;
lprint("%s %3d %15s %5d ",
buff, so->s,
inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)),
ntohs(so->so_lport));
inet_ntoa(so->so_laddr), ntohs(so->so_lport));
lprint("%15s %5d %5d %5d\r\n",
inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)),
ntohs(so->so_fport),
inet_ntoa(so->so_faddr), ntohs(so->so_fport),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
@ -326,16 +328,15 @@ sockstats()
buff[17] = 0;
lprint("%s %3d %15s %5d ",
buff, so->s,
inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)),
ntohs(so->so_lport));
inet_ntoa(so->so_laddr), ntohs(so->so_lport));
lprint("%15s %5d %5d %5d\r\n",
inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)),
ntohs(so->so_fport),
inet_ntoa(so->so_faddr), ntohs(so->so_fport),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
}
}
#endif
#if 0
#ifndef CONFIG_QEMU
void
slirp_exit(exit_status)
int exit_status;
@ -377,3 +378,18 @@ slirp_exit(exit_status)
exit(exit_status);
}
#endif
void
slirp_stats(void)
{
#ifdef LOG_ENABLED
ipstats();
tcpstats();
udpstats();
icmpstats();
mbufstats();
sockstats();
#else
lprint("SLIRP statistics code not compiled.\n");
#endif
}

View File

@ -36,15 +36,5 @@ extern int slirp_debug;
#endif
void debug_init(char *, int);
//void ttystats(struct ttys *);
void allttystats(void);
void ipstats(void);
void vjstats(void);
void tcpstats(void);
void udpstats(void);
void icmpstats(void);
void mbufstats(void);
void sockstats(void);
void slirp_exit(int);
void debug_init _P((char *, int));

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -60,6 +64,8 @@ struct icmpstat {
{ "stats", CTLTYPE_STRUCT }, \
}
#ifdef LOG_ENABLED
extern struct icmpstat icmpstat;
#endif
#endif

View File

@ -7,12 +7,7 @@
#include <slirp.h>
size_t 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 */
@ -41,23 +36,6 @@ ifs_remque(ifm)
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);
@ -116,8 +94,7 @@ if_input(ttyp)
DEBUG_MISC((dfd, " read %d bytes\n", if_n));
if (if_n <= 0) {
int error = WSAGetLastError();
if (if_n == 0 || (error != WSAEINTR && error != EAGAIN)) {
if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) {
if (ttyp->up)
link_up--;
tty_detached(ttyp, 0);
@ -314,7 +291,7 @@ if_start(void)
}
/* Encapsulate the packet for sending */
if_encap((uint8_t*)ifm->m_data, ifm->m_len);
if_encap(ifm->m_data, ifm->m_len);
m_free(ifm);

View File

@ -13,15 +13,26 @@
#define IF_AUTOCOMP 0x04 /* Autodetect (default) */
#define IF_NOCIDCOMP 0x08 /* CID compression */
/* Needed for FreeBSD */
#undef if_mtu
extern size_t if_mtu;
extern size_t if_mru; /* MTU and MRU */
extern int if_comp; /* Flags for compression */
extern int if_maxlinkhdr;
#define IF_MTU 1500
#define IF_MRU 1500
#define IF_COMP IF_AUTOCOMP /* Flags for compression */
#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
#define IF_MAXLINKHDR 48
#else
#define IF_MAXLINKHDR 40
#endif
#else
/* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
#define IF_MAXLINKHDR (2 + 14 + 40)
#endif
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 */
@ -29,6 +40,7 @@ extern struct mbuf *next_m;
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
#ifdef LOG_ENABLED
/* Interface statistics */
struct slirp_ifstats {
u_int out_pkts; /* Output packets */
@ -46,5 +58,6 @@ struct slirp_ifstats {
u_int in_mbad; /* Bad incoming packets */
};
#endif
#endif

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -72,16 +76,12 @@ typedef u_int32_t n_long; /* long as received from the net */
/*
* Structure of an internet header, naked of options.
*/
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
struct ip {
#ifdef WORDS_BIGENDIAN
u_char ip_v:4, /* version */
u_int ip_v:4, /* version */
ip_hl:4; /* header length */
#else
u_char ip_hl:4, /* header length */
u_int ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
u_int8_t ip_tos; /* type of service */
@ -95,11 +95,7 @@ struct ip {
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
#define IP_MAXPACKET 65535 /* maximum packet size */
@ -143,19 +139,15 @@ struct ip {
/*
* Time stamp option structure.
*/
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
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_char ipt_oflw:4, /* overflow counter */
u_int ipt_oflw:4, /* overflow counter */
ipt_flg:4; /* flags, see below */
#else
u_char ipt_flg:4, /* flags, see below */
u_int ipt_flg:4, /* flags, see below */
ipt_oflw:4; /* overflow counter */
#endif
union ipt_timestamp {
@ -165,11 +157,7 @@ struct ip_timestamp {
n_long ipt_time;
} ipt_ta[1];
} ipt_timestamp;
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
/* flag bits for ipt_flg */
#define IPOPT_TS_TSONLY 0 /* timestamps only */
@ -216,10 +204,6 @@ typedef caddr32_t ipasfragp_32;
/*
* Overlay for ip header used by other protocols (tcp, udp).
*/
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
struct ipovly {
caddr32_t ih_next, ih_prev; /* for protocol sequence q's */
u_int8_t ih_x1; /* (unused) */
@ -227,11 +211,7 @@ struct ipovly {
u_int16_t ih_len; /* protocol length */
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
/*
* Ip reassembly queue structure. Each fragment
@ -257,10 +237,10 @@ struct ipq {
*/
struct ipasfrag {
#ifdef WORDS_BIGENDIAN
u_char ip_v:4,
u_int ip_v:4,
ip_hl:4;
#else
u_char ip_hl:4,
u_int ip_hl:4,
ip_v:4;
#endif
/* BUG : u_int changed to u_int8_t.
@ -292,6 +272,7 @@ struct ipoption {
int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
};
#ifdef LOG_ENABLED
/*
* Structure attached to inpcb.ip_moptions and
* passed to ip_output when IP multicast options are in use.
@ -326,8 +307,9 @@ struct ipstat {
};
extern struct ipstat ipstat;
#endif
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

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -33,14 +37,16 @@
#include "slirp.h"
#include "ip_icmp.h"
#ifdef LOG_ENABLED
struct icmpstat icmpstat;
#endif
/* 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";
/* Be nice and tell them it's just a pseudo-ping packet */
const char icmp_ping_msg[] = "This is a pseudo-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] = {
static const int icmp_flush[19] = {
/* ECHO REPLY (0) */ 0,
1,
1,
@ -77,16 +83,16 @@ icmp_input(m, hlen)
DEBUG_CALL("icmp_input");
DEBUG_ARG("m = %lx", (long )m);
DEBUG_ARG("m_len = %zu", m->m_len);
DEBUG_ARG("m_len = %d", m->m_len);
icmpstat.icps_received++;
STAT(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++;
STAT(icmpstat.icps_tooshort++);
freeit:
m_freem(m);
goto end_error;
@ -96,7 +102,7 @@ icmp_input(m, hlen)
m->m_data += hlen;
icp = mtod(m, struct icmp *);
if (cksum(m, icmplen)) {
icmpstat.icps_checksum++;
STAT(icmpstat.icps_checksum++);
goto freeit;
}
m->m_len += hlen;
@ -166,12 +172,12 @@ icmp_input(m, hlen)
case ICMP_TSTAMP:
case ICMP_MASKREQ:
case ICMP_REDIRECT:
icmpstat.icps_notsupp++;
STAT(icmpstat.icps_notsupp++);
m_freem(m);
break;
default:
icmpstat.icps_badtype++;
STAT(icmpstat.icps_badtype++);
m_freem(m);
} /* swith */
@ -201,12 +207,12 @@ end_error:
#define ICMP_MAXDATALEN (IP_MSS-28)
void
icmp_error(
struct mbuf *msrc,
u_char type,
u_char code,
int minsize,
char *message)
icmp_error(msrc, type, code, minsize, message)
struct mbuf *msrc;
u_char type;
u_char code;
int minsize;
char *message;
{
unsigned hlen, shlen, s_ip_len;
register struct ip *ip;
@ -215,7 +221,7 @@ icmp_error(
DEBUG_CALL("icmp_error");
DEBUG_ARG("msrc = %lx", (long )msrc);
DEBUG_ARG("msrc_len = %zu", msrc->m_len);
DEBUG_ARG("msrc_len = %d", msrc->m_len);
if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error;
@ -223,9 +229,9 @@ icmp_error(
if(!msrc) goto end_error;
ip = mtod(msrc, struct ip *);
#if DEBUG
{ char bufa[INET_ADDRSTRLEN], bufb[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ip->ip_src, bufa, sizeof(bufa));
inet_ntop(AF_INET, &ip->ip_dst, bufb, sizeof(bufb));
{ 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
@ -244,7 +250,7 @@ icmp_error(
/* make a copy */
if(!(m=m_get())) goto end_error; /* get mbuf */
{ u_int new_m_size;
{ int new_m_size;
new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN;
if(new_m_size>m->m_size) m_inc(m, new_m_size);
}
@ -299,7 +305,7 @@ icmp_error(
/* fill in ip */
ip->ip_hl = hlen >> 2;
ip->ip_len = (u_int16_t)m->m_len;
ip->ip_len = m->m_len;
ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */
@ -310,7 +316,7 @@ icmp_error(
(void ) ip_output((struct socket *)NULL, m);
icmpstat.icps_reflect++;
STAT(icmpstat.icps_reflect++);
end_error:
return;
@ -367,5 +373,5 @@ icmp_reflect(m)
(void ) ip_output((struct socket *)NULL, m);
icmpstat.icps_reflect++;
STAT(icmpstat.icps_reflect++);
}

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -43,10 +47,6 @@ typedef u_int32_t n_time;
/*
* Structure of an icmp header.
*/
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
@ -92,11 +92,7 @@ struct icmp {
#define icmp_ip icmp_dun.id_ip.idi_ip
#define icmp_mask icmp_dun.id_mask
#define icmp_data icmp_dun.id_data
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
/*
* Lower bounds on packet lengths for various types.
@ -161,8 +157,8 @@ struct icmp {
(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
void icmp_input(struct mbuf *, int);
void icmp_error(struct mbuf *, u_char, u_char, int, char *);
void icmp_reflect(struct mbuf *);
void icmp_input _P((struct mbuf *, int));
void icmp_error _P((struct mbuf *, u_char, u_char, int, char *));
void icmp_reflect _P((struct mbuf *));
#endif

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -41,10 +45,19 @@
#include <slirp.h>
#include "ip_icmp.h"
int ip_defttl;
#ifdef LOG_ENABLED
struct ipstat ipstat;
#endif
struct ipq ipq;
static struct ip *ip_reass(register struct ipasfrag *ip,
register struct ipq *fp);
static void ip_freef(struct ipq *fp);
static void ip_enq(register struct ipasfrag *p,
register struct ipasfrag *prev);
static void ip_deq(register struct ipasfrag *p);
/*
* IP initialization: fill in IP protocol switch table.
* All protocols not implemented in kernel go to raw IP protocol handler.
@ -56,7 +69,6 @@ ip_init()
ip_id = tt.tv_sec & 0xffff;
udp_init();
tcp_init();
ip_defttl = IPDEFTTL;
}
/*
@ -68,29 +80,29 @@ ip_input(m)
struct mbuf *m;
{
register struct ip *ip;
u_int hlen;
int hlen;
DEBUG_CALL("ip_input");
DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("m_len = %zu", m->m_len);
DEBUG_ARG("m_len = %d", m->m_len);
ipstat.ips_total++;
STAT(ipstat.ips_total++);
if (m->m_len < sizeof (struct ip)) {
ipstat.ips_toosmall++;
STAT(ipstat.ips_toosmall++);
return;
}
ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) {
ipstat.ips_badvers++;
STAT(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 */
STAT(ipstat.ips_badhlen++); /* or packet too short */
goto bad;
}
@ -99,7 +111,7 @@ ip_input(m)
* if (ip->ip_sum) {
*/
if(cksum(m,hlen)) {
ipstat.ips_badsum++;
STAT(ipstat.ips_badsum++);
goto bad;
}
@ -108,7 +120,7 @@ ip_input(m)
*/
NTOHS(ip->ip_len);
if (ip->ip_len < hlen) {
ipstat.ips_badlen++;
STAT(ipstat.ips_badlen++);
goto bad;
}
NTOHS(ip->ip_id);
@ -121,7 +133,7 @@ ip_input(m)
* Drop packet if shorter than we expect.
*/
if (m->m_len < ip->ip_len) {
ipstat.ips_tooshort++;
STAT(ipstat.ips_tooshort++);
goto bad;
}
/* Should drop packet if mbuf too long? hmmm... */
@ -188,11 +200,11 @@ ip_input(m)
* attempt reassembly; if it succeeds, proceed.
*/
if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
ipstat.ips_fragments++;
STAT(ipstat.ips_fragments++);
ip = ip_reass((struct ipasfrag *)ip, fp);
if (ip == 0)
return;
ipstat.ips_reassembled++;
STAT(ipstat.ips_reassembled++);
m = dtom(ip);
} else
if (fp)
@ -204,7 +216,7 @@ ip_input(m)
/*
* Switch out to protocol's input routine.
*/
ipstat.ips_delivered++;
STAT(ipstat.ips_delivered++);
switch (ip->ip_p) {
case IPPROTO_TCP:
tcp_input(m, hlen, (struct socket *)NULL);
@ -216,7 +228,7 @@ ip_input(m)
icmp_input(m, hlen);
break;
default:
ipstat.ips_noproto++;
STAT(ipstat.ips_noproto++);
m_free(m);
}
return;
@ -231,10 +243,8 @@ bad:
* 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;
static struct ip *
ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
{
register struct mbuf *m = dtom(ip);
register struct ipasfrag *q;
@ -381,7 +391,7 @@ insert:
return ((struct ip *)ip);
dropfrag:
ipstat.ips_fragdropped++;
STAT(ipstat.ips_fragdropped++);
m_freem(m);
return (0);
}
@ -390,9 +400,8 @@ dropfrag:
* Free a fragment reassembly header and all
* associated datagrams.
*/
void
ip_freef(fp)
struct ipq *fp;
static void
ip_freef(struct ipq *fp)
{
register struct ipasfrag *q, *p;
@ -410,9 +419,8 @@ ip_freef(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;
static void
ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev)
{
DEBUG_CALL("ip_enq");
DEBUG_ARG("prev = %lx", (long)prev);
@ -425,9 +433,8 @@ ip_enq(p, prev)
/*
* To ip_enq as remque is to insque.
*/
void
ip_deq(p)
register struct ipasfrag *p;
static void
ip_deq(register struct ipasfrag *p)
{
((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next;
((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev;
@ -453,7 +460,7 @@ ip_slowtimo()
--fp->ipq_ttl;
fp = (struct ipq *) fp->next;
if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
ipstat.ips_fragtimeout++;
STAT(ipstat.ips_fragtimeout++);
ip_freef((struct ipq *) fp->prev);
}
}
@ -660,7 +667,7 @@ bad:
/* Not yet */
icmp_error(m, type, code, 0, 0);
ipstat.ips_badoptions++;
STAT(ipstat.ips_badoptions++);
return (1);
}

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -42,6 +46,10 @@
u_int16_t ip_id;
/* Number of packets queued before we start sending
* (to prevent allocing too many mbufs) */
#define IF_THRESH 10
/*
* IP output. The packet in mbuf chain m contains a skeletal IP
* header (with len, off, ttl, proto, tos, src, dst).
@ -55,9 +63,8 @@ ip_output(so, m0)
{
register struct ip *ip;
register struct mbuf *m = m0;
register u_int hlen = sizeof(struct ip);
u_int len, off;
int error = 0;
register int hlen = sizeof(struct ip );
int len, off, error = 0;
DEBUG_CALL("ip_output");
DEBUG_ARG("so = %lx", (long)so);
@ -77,14 +84,14 @@ ip_output(so, m0)
ip->ip_off &= IP_DF;
ip->ip_id = htons(ip_id++);
ip->ip_hl = hlen >> 2;
ipstat.ips_localout++;
STAT(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) {
/* if (if_queued > IF_THRESH && towrite <= 0) {
* error = ENOBUFS;
* goto bad;
* }
@ -93,7 +100,7 @@ ip_output(so, m0)
/*
* If small enough for interface, can just send directly.
*/
if ((u_int16_t)ip->ip_len <= if_mtu) {
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;
@ -109,11 +116,11 @@ ip_output(so, m0)
*/
if (ip->ip_off & IP_DF) {
error = -1;
ipstat.ips_cantfrag++;
STAT(ipstat.ips_cantfrag++);
goto bad;
}
len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */
len = (IF_MTU - hlen) &~ 7; /* ip databytes per packet */
if (len < 8) {
error = -1;
goto bad;
@ -129,15 +136,15 @@ ip_output(so, m0)
*/
m0 = m;
mhlen = sizeof (struct ip);
for (off = hlen + len; off < ip->ip_len; off += len) {
for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
register struct ip *mhip;
m = m_get();
if (m == 0) {
error = -1;
ipstat.ips_odropped++;
STAT(ipstat.ips_odropped++);
goto sendorfree;
}
m->m_data += if_maxlinkhdr;
m->m_data += IF_MAXLINKHDR;
mhip = mtod(m, struct ip *);
*mhip = *ip;
@ -167,14 +174,14 @@ ip_output(so, m0)
mhip->ip_sum = cksum(m, mhlen);
*mnext = m;
mnext = &m->m_nextpkt;
ipstat.ips_ofragments++;
STAT(ipstat.ips_ofragments++);
}
/*
* Update first fragment by trimming what's been copied out
* and updating header, then send each fragment (in order).
*/
m = m0;
m_adj(m, hlen + firstlen - ip->ip_len);
m_adj(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;
@ -190,7 +197,7 @@ sendorfree:
}
if (error == 0)
ipstat.ips_fragmented++;
STAT(ipstat.ips_fragmented++);
}
done:

View File

@ -1,30 +1,22 @@
#ifndef _LIBSLIRP_H
#define _LIBSLIRP_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
int slirp_init(void);
void slirp_init(void);
int slirp_select_fill(int *pnfds,
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 *pkt, int pkt_len);
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 *pkt, int pkt_len);
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);
@ -34,6 +26,8 @@ int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
extern const char *tftp_prefix;
extern char slirp_hostname[33];
void slirp_stats(void);
#ifdef __cplusplus
}
#endif

View File

@ -42,7 +42,6 @@ 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];

View File

@ -15,32 +15,26 @@
* the flags
*/
#include <stdlib.h>
#include <slirp.h>
struct mbuf *mbutl;
char *mclrefcnt;
int mbuf_alloced = 0;
struct mbuf m_freelist, m_usedlist;
int mbuf_thresh = 30;
#define MBUF_THRESH 30
int mbuf_max = 0;
size_t msize;
void m_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;
#define MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
void
m_init()
{
m_freelist.m_next = m_freelist.m_prev = &m_freelist;
m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
}
/*
@ -51,7 +45,8 @@ void msize_init()
* free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
* which tells m_free to actually free() it
*/
struct mbuf *m_get()
struct mbuf *
m_get()
{
register struct mbuf *m;
int flags = 0;
@ -59,10 +54,10 @@ struct mbuf *m_get()
DEBUG_CALL("m_get");
if (m_freelist.m_next == &m_freelist) {
m = (struct mbuf *)malloc(msize);
m = (struct mbuf *)malloc(MSIZE);
if (m == NULL) goto end_error;
mbuf_alloced++;
if (mbuf_alloced > mbuf_thresh)
if (mbuf_alloced > MBUF_THRESH)
flags = M_DOFREE;
if (mbuf_alloced > mbuf_max)
mbuf_max = mbuf_alloced;
@ -76,7 +71,7 @@ struct mbuf *m_get()
m->m_flags = (flags | M_USEDLIST);
/* Initialise it */
m->m_size = msize - sizeof(struct m_hdr);
m->m_size = MSIZE - sizeof(struct m_hdr);
m->m_data = m->m_dat;
m->m_len = 0;
m->m_nextpkt = 0;
@ -86,7 +81,9 @@ end_error:
return m;
}
void m_free(struct mbuf *m)
void
m_free(m)
struct mbuf *m;
{
DEBUG_CALL("m_free");
@ -119,7 +116,9 @@ void m_free(struct mbuf *m)
* the other.. if result is too big for one mbuf, malloc()
* an M_EXT data segment
*/
void m_cat(register struct mbuf *m, register struct mbuf *n)
void
m_cat(m, n)
register struct mbuf *m, *n;
{
/*
* If there's no room, realloc
@ -135,7 +134,10 @@ void m_cat(register struct mbuf *m, register struct mbuf *n)
/* make m size bytes large */
void m_inc(struct mbuf *m, u_int size)
void
m_inc(m, size)
struct mbuf *m;
int size;
{
int datasize;
@ -169,7 +171,10 @@ void m_inc(struct mbuf *m, u_int size)
void m_adj(struct mbuf *m, int len)
void
m_adj(m, len)
struct mbuf *m;
int len;
{
if (m == NULL)
return;
@ -189,7 +194,9 @@ void m_adj(struct mbuf *m, int len)
* Copy len bytes from m, starting off bytes into n
*/
int
m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len)
m_copy(n, m, off, len)
struct mbuf *n, *m;
int off, len;
{
if (len > M_FREEROOM(n))
return -1;
@ -205,7 +212,9 @@ m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len)
* XXX This is a kludge, I should eliminate the need for it
* Fortunately, it's not used often
*/
struct mbuf *dtom(void *dat)
struct mbuf *
dtom(dat)
void *dat;
{
struct mbuf *m;

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -63,11 +67,11 @@ struct m_hdr {
struct mbuf *mh_prevpkt; /* Flags aren't used in the output queue */
int mh_flags; /* Misc flags */
size_t mh_size; /* Size of data */
int mh_size; /* Size of data */
struct socket *mh_so;
caddr_t mh_data; /* Location of data */
size_t mh_len; /* Amount of data in this mbuf */
int mh_len; /* Amount of data in this mbuf */
};
/*
@ -130,14 +134,13 @@ extern int mbuf_alloced;
extern struct mbuf m_freelist, m_usedlist;
extern int mbuf_max;
void m_init(void);
void msize_init(void);
struct mbuf * m_get(void);
void m_free(struct mbuf *);
void m_cat(register struct mbuf *, register struct mbuf *);
void m_inc(struct mbuf *, u_int);
void m_adj(struct mbuf *, int);
int m_copy(struct mbuf *, struct mbuf *, u_int, u_int);
struct mbuf * dtom(void *);
void m_init _P((void));
struct mbuf * m_get _P((void));
void m_free _P((struct mbuf *));
void m_cat _P((register struct mbuf *, register struct mbuf *));
void m_inc _P((struct mbuf *, int));
void m_adj _P((struct mbuf *, int));
int m_copy _P((struct mbuf *, struct mbuf *, int, int));
struct mbuf * dtom _P((void *));
#endif

View File

@ -6,18 +6,19 @@
*/
#define WANT_SYS_IOCTL_H
#include <stdlib.h>
#include <slirp.h>
u_int curtime, time_fasttimo, last_slowtimo, detach_time;
u_int detach_wait = 600000; /* 10 minutes */
u_int curtime, time_fasttimo, last_slowtimo;
#if 0
int x_port = -1;
int x_display = 0;
int x_screen = 0;
int show_x(char *buff, struct socket *inso)
int
show_x(buff, inso)
char *buff;
struct socket *inso;
{
if (x_port < 0) {
lprint("X Redir: X not being redirected.\r\n");
@ -37,7 +38,12 @@ int show_x(char *buff, struct socket *inso)
/*
* XXX Allow more than one X redirection?
*/
void redir_x(u_int32_t inaddr, int start_port, int display, int screen)
void
redir_x(inaddr, start_port, display, screen)
u_int32_t inaddr;
int start_port;
int display;
int screen;
{
int i;
@ -61,31 +67,32 @@ void redir_x(u_int32_t inaddr, int start_port, int display, int screen)
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *ia)
int
inet_aton(cp, ia)
const char *cp;
struct in_addr *ia;
{
return inet_pton(AF_INET, cp, &ia->s_addr);
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()
void
getouraddr()
{
char buff[256];
struct hostent *he = NULL;
if (gethostname(buff, sizeof(buff)) == 0)
{
struct addrinfo hints = { 0 };
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_INET;
struct addrinfo* ai;
if (getaddrinfo(buff, NULL, &hints, &ai) == 0)
{
our_addr = *(struct in_addr *)ai->ai_addr->sa_data;
freeaddrinfo(ai);
}
}
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;
}
@ -97,7 +104,10 @@ struct quehead_32 {
u_int32_t qh_rlink;
};
inline void insque_32(void *a, void *b)
inline void
insque_32(a, b)
void *a;
void *b;
{
register struct quehead_32 *element = (struct quehead_32 *) a;
register struct quehead_32 *head = (struct quehead_32 *) b;
@ -108,7 +118,9 @@ inline void insque_32(void *a, void *b)
= (u_int32_t)element;
}
inline void remque_32(void *a)
inline void
remque_32(a)
void *a;
{
register struct quehead_32 *element = (struct quehead_32 *) a;
((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
@ -123,7 +135,9 @@ struct quehead {
struct quehead *qh_rlink;
};
void insque(void *a, void *b)
inline void
insque(a, b)
void *a, *b;
{
register struct quehead *element = (struct quehead *) a;
register struct quehead *head = (struct quehead *) b;
@ -134,7 +148,9 @@ void insque(void *a, void *b)
= (struct quehead *)element;
}
void remque(void *a)
inline void
remque(a)
void *a;
{
register struct quehead *element = (struct quehead *) a;
((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
@ -146,7 +162,13 @@ void remque(void *a)
/* #endif */
int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port)
int
add_exec(ex_ptr, do_pty, exec, addr, port)
struct ex_list **ex_ptr;
int do_pty;
char *exec;
int addr;
int port;
{
struct ex_list *tmp_ptr;
@ -175,7 +197,9 @@ int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port
extern int sys_nerr;
extern char *sys_errlist[];
char *strerror(int error)
char *
strerror(error)
int error;
{
if (error < sys_nerr)
return sys_errlist[error];
@ -188,7 +212,8 @@ char *strerror(int error)
#ifdef _WIN32
int fork_exec(struct socket *so, char *ex, int do_pty)
int
fork_exec(struct socket *so, const char *ex, int do_pty)
{
/* not implemented */
return 0;
@ -196,7 +221,10 @@ int fork_exec(struct socket *so, char *ex, int do_pty)
#else
int slirp_openpty(int *amaster, int *aslave)
#ifndef CONFIG_QEMU
int
slirp_openpty(amaster, aslave)
int *amaster, *aslave;
{
register int master, slave;
@ -258,6 +286,7 @@ int slirp_openpty(int *amaster, int *aslave)
return (-1);
#endif
}
#endif
/*
* XXX This is ugly
@ -270,20 +299,21 @@ int slirp_openpty(int *amaster, int *aslave)
* do_pty = 1 Fork/exec using slirp.telnetd
* do_ptr = 2 Fork/exec using pty
*/
int fork_exec(struct socket *so, char *ex, int do_pty)
int
fork_exec(struct socket *so, const char *ex, int do_pty)
{
int s;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
int addrlen = sizeof(addr);
int opt;
int master;
int master = -1;
char *argv[256];
#if 0
char buff[256];
#endif
/* don't want to clobber the original */
char *bptr;
char *curarg;
const char *curarg;
int c, i, ret;
DEBUG_CALL("fork_exec");
@ -292,12 +322,15 @@ int fork_exec(struct socket *so, char *ex, int do_pty)
DEBUG_ARG("do_pty = %lx", (long)do_pty);
if (do_pty == 2) {
#if 0
if (slirp_openpty(&master, &s) == -1) {
lprint("Error: openpty failed: %s\n", strerror(errno));
return 0;
}
#else
return 0;
#endif
} else {
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr.s_addr = INADDR_ANY;
@ -356,7 +389,7 @@ int fork_exec(struct socket *so, char *ex, int do_pty)
dup2(s, 0);
dup2(s, 1);
dup2(s, 2);
for (s = 3; s <= 255; s++)
for (s = getdtablesize() - 1; s >= 3; s--)
close(s);
i = 0;
@ -426,7 +459,9 @@ int fork_exec(struct socket *so, char *ex, int do_pty)
#endif
#ifndef HAVE_STRDUP
char *strdup(const char *str)
char *
strdup(str)
const char *str;
{
char *bptr;
@ -438,7 +473,9 @@ char *strdup(const char *str)
#endif
#if 0
void snooze_hup(int num)
void
snooze_hup(num)
int num;
{
int s, ret;
#ifndef NO_UNIX_SOCKETS
@ -478,7 +515,8 @@ void snooze_hup(int num)
}
void snooze()
void
snooze()
{
sigset_t s;
int i;
@ -502,7 +540,9 @@ void snooze()
exit(255);
}
void relay(int s)
void
relay(s)
int s;
{
char buf[8192];
int n;
@ -562,14 +602,37 @@ void relay(int s)
}
#endif
int (*lprint_print)(void *, const char *, va_list);
char *lprint_ptr, *lprint_ptr2, **lprint_arg;
#ifdef CONFIG_QEMU
extern void term_vprintf(const char *fmt, va_list ap);
void lprint(const char *format, ...)
{
va_list args;
va_start(args, format);
term_vprintf(format, args);
va_end(args);
}
#else
int (*lprint_print) _P((void *, const char *, va_list));
char *lprint_ptr, *lprint_ptr2, **lprint_arg;
void
#ifdef __STDC__
lprint(const char *format, ...)
#else
lprint(va_alist) va_dcl
#endif
{
va_list args;
#ifdef __STDC__
va_start(args, format);
#else
char *format;
va_start(args);
format = va_arg(args, char *);
#endif
#if 0
/* If we're printing to an sbuf, make sure there's enough room */
/* XXX +100? */
@ -618,7 +681,9 @@ void lprint(const char *format, ...)
va_end(args);
}
void add_emu(char *buff)
void
add_emu(buff)
char *buff;
{
u_int lport, fport;
u_int8_t tos = 0, emu = 0;
@ -700,6 +765,7 @@ void add_emu(char *buff)
lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
}
#endif
#ifdef BAD_SPRINTF
@ -710,24 +776,42 @@ void add_emu(char *buff)
* Some BSD-derived systems have a sprintf which returns char *
*/
int vsprintf_len(char *string, const char *format, va_list args)
int
vsprintf_len(string, format, args)
char *string;
const char *format;
va_list args;
{
vsprintf(string, format, args);
return strlen(string);
}
int sprintf_len(char *string, const char *format, ...)
int
#ifdef __STDC__
sprintf_len(char *string, const char *format, ...)
#else
sprintf_len(va_alist) va_dcl
#endif
{
va_list args;
#ifdef __STDC__
va_start(args, format);
#else
char *string;
char *format;
va_start(args);
string = va_arg(args, char *);
format = va_arg(args, char *);
#endif
vsprintf(string, format, args);
va_end(args);
return strlen(string);
}
#endif
void u_sleep(int usec)
void
u_sleep(usec)
int usec;
{
struct timeval t;
fd_set fdset;
@ -744,10 +828,12 @@ void u_sleep(int usec)
* Set fd blocking and non-blocking
*/
void fd_nonblock(int fd)
void
fd_nonblock(fd)
int fd;
{
#if defined USE_FIONBIO && defined FIONBIO
ioctlsockopt_t opt = 1;
#ifdef FIONBIO
int opt = 1;
ioctlsocket(fd, FIONBIO, &opt);
#else
@ -759,10 +845,12 @@ void fd_nonblock(int fd)
#endif
}
void fd_block(int fd)
void
fd_block(fd)
int fd;
{
#if defined USE_FIONBIO && defined FIONBIO
ioctlsockopt_t opt = 0;
#ifdef FIONBIO
int opt = 0;
ioctlsocket(fd, FIONBIO, &opt);
#else
@ -779,8 +867,13 @@ void fd_block(int fd)
/*
* invoke RSH
*/
int rsh_exec(struct socket *so, struct socket *ns,
char *user, char *host, char *args)
int
rsh_exec(so,ns, user, host, args)
struct socket *so;
struct socket *ns;
char *user;
char *host;
char *args;
{
int fd[2];
int fd0[2];

View File

@ -12,22 +12,22 @@ struct ex_list {
int ex_pty; /* Do we want a pty? */
int ex_addr; /* The last byte of the address */
int ex_fport; /* Port to telnet to */
char *ex_exec; /* Command line of what to exec */
const char *ex_exec; /* Command line of what to exec */
struct ex_list *ex_next;
};
extern struct ex_list *exec_list;
extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait;
extern u_int curtime, time_fasttimo, last_slowtimo;
extern int (*lprint_print)(void *, const char *, va_list);
extern int (*lprint_print) _P((void *, const char *, va_list));
extern char *lprint_ptr, *lprint_ptr2, **lprint_arg;
extern struct sbuf *lprint_sb;
#ifndef HAVE_STRDUP
char *strdup(const char *);
char *strdup _P((const char *));
#endif
void do_wait(int);
void do_wait _P((int));
#define EMU_NONE 0x0
@ -63,25 +63,27 @@ struct emu_t {
struct emu_t *next;
};
#ifndef CONFIG_QEMU
extern struct emu_t *tcpemu;
#endif
extern int x_port, x_server, x_display;
int show_x(char *, struct socket *);
void redir_x(u_int32_t, int, int, int);
void getouraddr(void);
void slirp_insque(void *, void *);
void slirp_remque(void *);
int add_exec(struct ex_list **, int, char *, int, int);
int slirp_openpty(int *, int *);
int fork_exec(struct socket *, char *, int);
void snooze_hup(int);
void snooze(void);
void relay(int);
void add_emu(char *);
void u_sleep(int);
void fd_nonblock(int);
void fd_block(int);
int rsh_exec(struct socket *, struct socket *, char *, char *, char *);
int show_x _P((char *, struct socket *));
void redir_x _P((u_int32_t, int, int, int));
void getouraddr _P((void));
inline void slirp_insque _P((void *, void *));
inline void slirp_remque _P((void *));
int add_exec _P((struct ex_list **, int, char *, int, int));
int slirp_openpty _P((int *, int *));
int fork_exec(struct socket *so, const char *ex, int do_pty);
void snooze_hup _P((int));
void snooze _P((void));
void relay _P((int));
void add_emu _P((char *));
void u_sleep _P((int));
void fd_nonblock _P((int));
void fd_block _P((int));
int rsh_exec _P((struct socket *, struct socket *, char *, char *, char *));
#endif

View File

@ -5,9 +5,10 @@
* terms and conditions of the copyright.
*/
#include <stdlib.h>
#include <slirp.h>
static void sbappendsb(struct sbuf *sb, struct mbuf *m);
/* Done as a macro in socket.h */
/* int
* sbspace(struct sockbuff *sb)
@ -16,12 +17,17 @@
* }
*/
void sbfree(struct sbuf *sb)
void
sbfree(sb)
struct sbuf *sb;
{
free(sb->sb_data);
}
void sbdrop(struct sbuf *sb, u_int num)
void
sbdrop(sb, num)
struct sbuf *sb;
int num;
{
/*
* We can only drop how much we have
@ -36,7 +42,10 @@ void sbdrop(struct sbuf *sb, u_int num)
}
void sbreserve(struct sbuf *sb, size_t size)
void
sbreserve(sb, size)
struct sbuf *sb;
int size;
{
if (sb->sb_data) {
/* Already alloced, realloc if necessary */
@ -64,14 +73,17 @@ void sbreserve(struct sbuf *sb, size_t size)
* this prevents an unnecessary copy of the data
* (the socket is non-blocking, so we won't hang)
*/
void sbappend(struct socket *so, struct mbuf *m)
void
sbappend(so, m)
struct socket *so;
struct mbuf *m;
{
int ret = 0;
DEBUG_CALL("sbappend");
DEBUG_ARG("so = %lx", (long)so);
DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("m->m_len = %zu", m->m_len);
DEBUG_ARG("m->m_len = %d", m->m_len);
/* Shouldn't happen, but... e.g. foreign host closes connection */
if (m->m_len <= 0) {
@ -123,7 +135,8 @@ void sbappend(struct socket *so, struct mbuf *m)
* Copy the data from m into sb
* The caller is responsible to make sure there's enough room
*/
void sbappendsb(struct sbuf *sb, struct mbuf *m)
static void
sbappendsb(struct sbuf *sb, struct mbuf *m)
{
int len, n, nn;
@ -159,7 +172,12 @@ void sbappendsb(struct sbuf *sb, struct mbuf *m)
* Don't update the sbuf rptr, this will be
* done in sbdrop when the data is acked
*/
void sbcopy(struct sbuf *sb, u_int off, u_int len, char *to)
void
sbcopy(sb, off, len, to)
struct sbuf *sb;
int off;
int len;
char *to;
{
char *from;

View File

@ -8,8 +8,6 @@
#ifndef _SBUF_H_
#define _SBUF_H_
#include <stddef.h>
#define sbflush(sb) sbdrop((sb),(sb)->sb_cc)
#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc)
@ -23,11 +21,10 @@ struct sbuf {
char *sb_data; /* Actual data */
};
void sbfree(struct sbuf *);
void sbdrop(struct sbuf *, u_int);
void sbreserve(struct sbuf *, size_t);
void sbappend(struct socket *, struct mbuf *);
void sbappendsb(struct sbuf *, struct mbuf *);
void sbcopy(struct sbuf *, u_int, u_int, char *);
void sbfree _P((struct sbuf *));
void sbdrop _P((struct sbuf *, int));
void sbreserve _P((struct sbuf *, int));
void sbappend _P((struct socket *, struct mbuf *));
void sbcopy _P((struct sbuf *, int, int, char *));
#endif

View File

@ -12,7 +12,7 @@ struct in_addr special_addr;
/* virtual address alias for host */
struct in_addr alias_addr;
const uint8_t special_ethaddr[6] = {
static const uint8_t special_ethaddr[6] = {
0x52, 0x54, 0x00, 0x12, 0x35, 0x00
};
@ -84,7 +84,7 @@ static int get_dns_addr(struct in_addr *pdns_addr)
static int get_dns_addr(struct in_addr *pdns_addr)
{
char buff[512];
char buff2[256+1];
char buff2[256];
FILE *f;
int found = 0;
struct in_addr tmp_addr;
@ -93,7 +93,9 @@ static int get_dns_addr(struct in_addr *pdns_addr)
if (!f)
return -1;
#ifdef DEBUG
lprint("IP address of your DNS(s): ");
#endif
while (fgets(buff, 512, f) != NULL) {
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
if (!inet_aton(buff2, &tmp_addr))
@ -103,13 +105,20 @@ static int get_dns_addr(struct in_addr *pdns_addr)
/* If it's the first one, set it to dns_addr */
if (!found)
*pdns_addr = tmp_addr;
#ifdef DEBUG
else
lprint(", ");
#endif
if (++found > 3) {
#ifdef DEBUG
lprint("(more)");
#endif
break;
} else
}
#ifdef DEBUG
else
lprint("%s", inet_ntoa(tmp_addr));
#endif
}
}
fclose(f);
@ -121,13 +130,13 @@ static int get_dns_addr(struct in_addr *pdns_addr)
#endif
#ifdef _WIN32
void slirp_cleanup(void)
static void slirp_cleanup(void)
{
WSACleanup();
}
#endif
int slirp_init(void)
void slirp_init(void)
{
// debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
@ -150,13 +159,14 @@ int slirp_init(void)
/* set default addresses */
inet_aton("127.0.0.1", &loopback_addr);
if (get_dns_addr(&dns_addr) < 0)
return -1;
if (get_dns_addr(&dns_addr) < 0) {
dns_addr = loopback_addr;
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();
return 0;
}
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
@ -188,12 +198,13 @@ static void updtime(void)
}
#endif
int slirp_select_fill(int *pnfds,
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 timeout, tmp_time;
int tmp_time;
/* fail safe */
global_readfds = NULL;
@ -305,43 +316,36 @@ int slirp_select_fill(int *pnfds,
* Setup timeout to use minimum CPU usage, especially when idle
*/
timeout = -1;
/*
* If a slowtimo is needed, set timeout to 5ms from the last
* slow timeout. If a fast timeout is needed, set timeout within
* 2ms of when it was requested.
* 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.
*/
# define SLOW_TIMO 5
# define FAST_TIMO 2
if (do_slowtimo) {
timeout = (SLOW_TIMO - (curtime - last_slowtimo)) * 1000;
if (timeout < 0)
timeout = 0;
else if (timeout > (SLOW_TIMO * 1000))
timeout = SLOW_TIMO * 1000;
/* 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 = (FAST_TIMO - (curtime - time_fasttimo)) * 1000;
tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
if (tmp_time < 0)
tmp_time = 0;
/* Choose the smallest of the 2 */
if (tmp_time < timeout)
timeout = tmp_time;
if (tmp_time < timeout.tv_usec)
timeout.tv_usec = (u_int)tmp_time;
}
}
*pnfds = nfds;
/*
* Adjust the timeout to make the minimum timeout
* 2ms (XXX?) to lessen the CPU load
*/
if (timeout < (FAST_TIMO * 1000))
timeout = FAST_TIMO * 1000;
return timeout;
}
void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
@ -360,11 +364,11 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
* See if anything has timed out
*/
if (link_up) {
if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) {
if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
tcp_fasttimo();
time_fasttimo = 0;
}
if (do_slowtimo && ((curtime - last_slowtimo) >= SLOW_TIMO)) {
if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
ip_slowtimo();
tcp_slowtimo();
last_slowtimo = curtime;
@ -424,12 +428,11 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
/* Connected */
so->so_state &= ~SS_ISFCONNECTING;
ret = send(so->s, (char*)&ret, 0, 0);
ret = send(so->s, &ret, 0, 0);
if (ret < 0) {
/* XXXXX Must fix, zero bytes is a NOP */
int error = WSAGetLastError();
if (error == EAGAIN || error == WSAEWOULDBLOCK ||
error == WSAEINPROGRESS || error == WSAENOTCONN)
if (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINPROGRESS || errno == ENOTCONN)
continue;
/* else failed */
@ -442,8 +445,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
*/
tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
/* continue; */
}
else
} else
ret = sowrite(so);
/*
* XXXXX If we wrote something (a lot), there
@ -459,36 +461,32 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
*/
#ifdef PROBE_CONN
if (so->so_state & SS_ISFCONNECTING) {
ret = recv(so->s, (char *)&ret, 0, 0);
ret = recv(so->s, (char *)&ret, 0,0);
if (ret < 0) {
/* XXX */
int error = WSAGetLastError();
if (error == EAGAIN || error == WSAEWOULDBLOCK ||
error == WSAEINPROGRESS || error == WSAENOTCONN)
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);
} else {
ret = send(so->s, &ret, 0,0);
if (ret < 0) {
/* XXX */
int error = WSAGetLastError();
if (error == EAGAIN || error == WSAEWOULDBLOCK ||
error == WSAEINPROGRESS || error == WSAENOTCONN)
if (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINPROGRESS || errno == ENOTCONN)
continue;
/* else failed */
so->so_state = SS_NOFDREF;
}
else
} else
so->so_state &= ~SS_ISFCONNECTING;
}
tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
} /* SS_ISFCONNECTING */
#endif
}
@ -505,7 +503,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
sorecvfrom(so);
}
}
}
}
/*
* See if we can start outputting
@ -612,7 +610,7 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
if (pkt_len < ETH_HLEN)
return;
proto = (pkt[12] << 8) | pkt[13];
proto = ntohs(*(uint16_t *)(pkt + 12));
switch(proto) {
case ETH_P_ARP:
arp_input(pkt, pkt_len);

View File

@ -3,12 +3,21 @@
#define CONFIG_QEMU
#define DEBUG 1
//#define DEBUG 1
// Uncomment the following line to enable SLIRP statistics printing in Qemu
//#define LOG_ENABLED
#ifdef LOG_ENABLED
#define STAT(expr) expr
#else
#define STAT(expr) do { } while(0)
#endif
#ifndef CONFIG_QEMU
#include "version.h"
#endif
#include "config.h"
#include "config-host.h"
#include "slirp_config.h"
#ifdef _WIN32
@ -19,31 +28,20 @@ typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
typedef char *caddr_t;
typedef int socklen_t;
typedef unsigned long ioctlsockopt_t;
#define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <winsock2.h>
# include <WS2tcpip.h>
# include <sys/timeb.h>
# include <iphlpapi.h>
# define USE_FIONBIO 1
/* Basilisk II Router defines those */
# define udp_read_completion slirp_udp_read_completion
# define write_udp slirp_write_udp
# define init_udp slirp_init_udp
# define final_udp slirp_final_udp
# define EWOULDBLOCK WSAEWOULDBLOCK
# define EINPROGRESS WSAEINPROGRESS
# define ENOTCONN WSAENOTCONN
# define EHOSTUNREACH WSAEHOSTUNREACH
# define ENETUNREACH WSAENETUNREACH
# define ECONNREFUSED WSAECONNREFUSED
#else
# define WSAGetLastError() (int)(errno)
# define WSASetLastError(e) (void)(errno = (e))
# define WSAEWOULDBLOCK EWOULDBLOCK
# define WSAEINPROGRESS EINPROGRESS
# define WSAENOTCONN ENOTCONN
# define WSAEHOSTUNREACH EHOSTUNREACH
# define WSAENETUNREACH ENETUNREACH
# define WSAECONNREFUSED ECONNREFUSED
typedef int ioctlsockopt_t;
# define ioctlsocket ioctl
# define closesocket(s) close(s)
# define O_BINARY 0
@ -53,13 +51,8 @@ typedef int ioctlsockopt_t;
#ifdef HAVE_SYS_BITYPES_H
# include <sys/bitypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#ifndef _WIN32
#include <sys/time.h>
#endif
#ifdef NEED_TYPEDEFS
typedef char int8_t;
@ -90,11 +83,6 @@ typedef unsigned char u_int8_t;
# endif
#endif /* NEED_TYPEDEFS */
/* Basilisk II types glue */
typedef u_int8_t uint8;
typedef u_int16_t uint16;
typedef u_int32_t uint32;
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@ -129,6 +117,17 @@ typedef u_int32_t uint32;
#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
@ -139,23 +138,20 @@ typedef u_int32_t uint32;
/* Systems lacking strdup() definition in <string.h>. */
#if defined(ultrix)
char *strdup(const char *);
char *strdup _P((const char *));
#endif
/* Systems lacking malloc() definition in <stdlib.h>. */
#if defined(ultrix) || defined(hcx)
void *malloc(size_t arg);
void free(void *ptr);
void *malloc _P((size_t arg));
void free _P((void *ptr));
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *ia);
int inet_aton _P((const char *cp, struct in_addr *ia));
#endif
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#endif
#ifndef NO_UNIX_SOCKETS
#include <sys/un.h>
#endif
@ -187,7 +183,11 @@ int inet_aton(const char *cp, struct in_addr *ia);
#include <ppp/slirppp.h>
#endif
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <sys/stat.h>
@ -202,20 +202,6 @@ int inet_aton(const char *cp, struct in_addr *ia);
#include "debug.h"
#if defined __GNUC__
#define PACKED__ __attribute__ ((packed))
#elif defined _MSC_VER
#define PRAGMA_PACK_SUPPORTED 1
#define PACK_RESET
#define PACKED__
#elif defined __sgi
#define PRAGMA_PACK_SUPPORTED 1
#define PACK_RESET 0
#define PACKED__
#else
#error "Packed attribute or pragma shall be supported"
#endif
#include "ip.h"
#include "tcp.h"
#include "tcp_timer.h"
@ -246,47 +232,45 @@ extern struct ttys *ttys_unit[MAX_INTERFACES];
#endif
#ifndef FULL_BOLT
void if_start(void);
void if_start _P((void));
#else
void if_start(struct ttys *);
void if_start _P((struct ttys *));
#endif
#ifdef BAD_SPRINTF
# define vsprintf vsprintf_len
# define sprintf sprintf_len
extern int vsprintf_len(char *, const char *, va_list);
extern int sprintf_len(char *, const char *, ...);
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(char *, const char *, va_list);
extern int vsprintf _P((char *, const char *, va_list));
# endif
extern int vfprintf(FILE *, const char *, va_list);
extern int vfprintf _P((FILE *, const char *, va_list));
#endif
#ifndef HAVE_STRERROR
extern char *strerror(int error);
extern char *strerror _P((int error));
#endif
#ifndef HAVE_INDEX
char *index(const char *, int);
char *index _P((const char *, int));
#endif
#ifndef HAVE_GETHOSTID
long gethostid(void);
long gethostid _P((void));
#endif
void lprint(const char *, ...);
extern int do_echo;
void lprint _P((const char *, ...));
#if SIZEOF_CHAR_P == 4
# define insque_32 insque
# define remque_32 remque
#else
extern inline void insque_32(void *, void *);
extern inline void remque_32(void *);
inline void insque_32 _P((void *, void *));
inline void remque_32 _P((void *));
#endif
#ifndef _WIN32
@ -295,51 +279,46 @@ extern int do_echo;
#define DEFAULT_BAUD 115200
#define SO_OPTIONS DO_KEEPALIVE
#define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL)
/* cksum.c */
int cksum(struct mbuf *m, int len);
/* if.c */
void if_init(void);
void if_output(struct socket *, struct mbuf *);
void if_init _P((void));
void if_output _P((struct socket *, struct mbuf *));
/* ip_input.c */
void ip_init(void);
void ip_input(struct mbuf *);
struct ip * ip_reass(register struct ipasfrag *, register struct ipq *);
void ip_freef(struct ipq *);
void ip_enq(register struct ipasfrag *, register struct ipasfrag *);
void ip_deq(register struct ipasfrag *);
void ip_slowtimo(void);
void ip_stripoptions(register struct mbuf *, struct mbuf *);
void ip_init _P((void));
void ip_input _P((struct mbuf *));
void ip_slowtimo _P((void));
void ip_stripoptions _P((register struct mbuf *, struct mbuf *));
/* ip_output.c */
int ip_output(struct socket *, struct mbuf *);
int ip_output _P((struct socket *, struct mbuf *));
/* tcp_input.c */
int tcp_reass(register struct tcpcb *, register struct tcpiphdr *, struct mbuf *);
void tcp_input(register struct mbuf *, int, struct socket *);
void tcp_dooptions(struct tcpcb *, u_char *, int, struct tcpiphdr *);
void tcp_xmit_timer(register struct tcpcb *, int);
u_int tcp_mss(register struct tcpcb *, u_int);
void tcp_input _P((register struct mbuf *, int, struct socket *));
int tcp_mss _P((register struct tcpcb *, u_int));
/* tcp_output.c */
int tcp_output(register struct tcpcb *);
void tcp_setpersist(register struct tcpcb *);
int tcp_output _P((register struct tcpcb *));
void tcp_setpersist _P((register struct tcpcb *));
/* tcp_subr.c */
void tcp_init(void);
void tcp_template(struct tcpcb *);
void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int);
struct tcpcb * tcp_newtcpcb(struct socket *);
struct tcpcb * tcp_close(register struct tcpcb *);
void tcp_drain(void);
void tcp_sockclosed(struct tcpcb *);
int tcp_fconnect(struct socket *);
void tcp_connect(struct socket *);
int tcp_attach(struct socket *);
u_int8_t tcp_tos(struct socket *);
int tcp_emu(struct socket *, struct mbuf *);
int tcp_ctl(struct socket *);
void tcp_init _P((void));
void tcp_template _P((struct tcpcb *));
void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int));
struct tcpcb * tcp_newtcpcb _P((struct socket *));
struct tcpcb * tcp_close _P((register struct tcpcb *));
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 *, struct mbuf *));
int tcp_ctl _P((struct socket *));
struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
#ifdef USE_PPP
@ -355,4 +334,9 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
#define max(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifdef _WIN32
#undef errno
#define errno (WSAGetLastError())
#endif
#endif

View File

@ -40,6 +40,11 @@
*/
#undef USE_LOWCPU
/* Define this if your compiler doesn't like prototypes */
#ifndef __STDC__
#define NO_PROTOTYPES
#endif
/*********************************************************/
/*
* Autoconf defined configuration options
@ -49,11 +54,40 @@
/* Ignore this */
#undef DUMMY_PPP
/* XXX: Define according to how time.h should be included */
#undef TIME_WITH_SYS_TIME
/* 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
@ -69,17 +103,56 @@
/* 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 SIZEOF_VOID_P
#define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
/* Define if you have random() */
#undef HAVE_RANDOM
@ -87,6 +160,12 @@
/* 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

View File

@ -6,7 +6,6 @@
*/
#define WANT_SYS_IOCTL_H
#include <stdlib.h>
#include <slirp.h>
#include "ip_icmp.h"
#include "main.h"
@ -14,18 +13,16 @@
#include <sys/filio.h>
#endif
#ifdef _WIN32
#define IS_EAGAIN(e) ((e) == WSAEINTR || (e) == EAGAIN)
#else
#define IS_EAGAIN(e) ((e) == EAGAIN)
#endif
static void sofcantrcvmore(struct socket *so);
static void sofcantsendmore(struct socket *so);
void
#if 0
static void
so_init()
{
/* Nothing yet */
}
#endif
struct socket *
solookup(head, laddr, lport, faddr, fport)
@ -103,12 +100,11 @@ int
soread(so)
struct socket *so;
{
int n, nn;
u_int lss, total;
int n, nn, lss, total;
struct sbuf *sb = &so->so_snd;
u_int len = sb->sb_datalen - sb->sb_cc;
int len = sb->sb_datalen - sb->sb_cc;
struct iovec iov[2];
u_int mss = so->so_tcpcb->t_maxseg;
int mss = so->so_tcpcb->t_maxseg;
DEBUG_CALL("soread");
DEBUG_ARG("so = %lx", (long )so);
@ -166,8 +162,7 @@ soread(so)
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
#endif
if (nn <= 0) {
int error = WSAGetLastError();
if (nn < 0 && IS_EAGAIN(error))
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)));
@ -305,7 +300,7 @@ sowrite(so)
{
int n,nn;
struct sbuf *sb = &so->so_rcv;
u_int len = sb->sb_cc;
int len = sb->sb_cc;
struct iovec iov[2];
DEBUG_CALL("sowrite");
@ -352,11 +347,8 @@ sowrite(so)
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) {
int error = WSAGetLastError();
if (IS_EAGAIN(error))
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
return 0;
}
if (nn <= 0) {
DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
@ -400,7 +392,7 @@ sorecvfrom(so)
struct socket *so;
{
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
int addrlen = sizeof(struct sockaddr_in);
DEBUG_CALL("sorecvfrom");
DEBUG_ARG("so = %lx", (long)so);
@ -416,9 +408,8 @@ sorecvfrom(so)
if(len == -1 || len == 0) {
u_char code=ICMP_UNREACH_PORT;
int error = WSAGetLastError();
if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST;
else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET;
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)));
@ -431,11 +422,10 @@ sorecvfrom(so)
udp_detach(so);
} else { /* A "normal" UDP packet */
struct mbuf *m;
u_int len;
ioctlsockopt_t n;
int len, n;
if (!(m = m_get())) return;
m->m_data += if_maxlinkhdr;
m->m_data += IF_MAXLINKHDR;
/*
* XXX Shouldn't FIONREAD packets destined for port 53,
@ -454,14 +444,13 @@ sorecvfrom(so)
m->m_len = recvfrom(so->s, m->m_data, len, 0,
(struct sockaddr *)&addr, &addrlen);
DEBUG_MISC((dfd, " did recvfrom %zu, errno = %d-%s\n",
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;
int error = WSAGetLastError();
if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST;
else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET;
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));
@ -526,9 +515,7 @@ sosendto(so, m)
addr.sin_addr = so->so_faddr;
addr.sin_port = so->so_fport;
char addrstr[INET_ADDRSTRLEN];
DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n",
ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, addrstr, sizeof(addrstr))));
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,
@ -558,9 +545,7 @@ solisten(port, laddr, lport, flags)
{
struct sockaddr_in addr;
struct socket *so;
int s;
socklen_t addrlen = sizeof(addr);
int opt = 1;
int s, addrlen = sizeof(addr), opt = 1;
DEBUG_CALL("solisten");
DEBUG_ARG("port = %d", port);
@ -590,7 +575,6 @@ solisten(port, laddr, lport, flags)
so->so_lport = lport; /* Kept in network format */
so->so_laddr.s_addr = laddr; /* Ditto */
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = port;
@ -599,12 +583,16 @@ solisten(port, laddr, lport, flags)
(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
int error = WSAGetLastError(); /* Don't clobber the real reason we failed */
int tmperrno = errno; /* Don't clobber the real reason we failed */
close(s);
sofree(so);
/* Restore the real errno */
WSASetLastError(error);
#ifdef _WIN32
WSASetLastError(tmperrno);
#else
errno = tmperrno;
#endif
return NULL;
}
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
@ -620,12 +608,13 @@ solisten(port, laddr, lport, flags)
return so;
}
#if 0
/*
* Data is available in so_rcv
* Just write() the data to the socket
* XXX not yet...
*/
void
static void
sorwakeup(so)
struct socket *so;
{
@ -638,12 +627,13 @@ sorwakeup(so)
* We have room for a read() if we want to
* For now, don't read, it'll be done in the main loop
*/
void
static void
sowwakeup(so)
struct socket *so;
{
/* Nothing, yet */
}
#endif
/*
* Various session state calls
@ -668,9 +658,8 @@ soisfconnected(so)
so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
}
void
sofcantrcvmore(so)
struct socket *so;
static void
sofcantrcvmore(struct socket *so)
{
if ((so->so_state & SS_NOFDREF) == 0) {
shutdown(so->s,0);
@ -685,9 +674,8 @@ sofcantrcvmore(so)
so->so_state |= SS_FCANTRCVMORE;
}
void
sofcantsendmore(so)
struct socket *so;
static void
sofcantsendmore(struct socket *so)
{
if ((so->so_state & SS_NOFDREF) == 0) {
shutdown(so->s,1); /* send FIN to fhost */

View File

@ -81,24 +81,19 @@ struct iovec {
};
#endif
void so_init(void);
struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int);
struct socket * socreate(void);
void sofree(struct socket *);
int soread(struct socket *);
void sorecvoob(struct socket *);
int sosendoob(struct socket *);
int sowrite(struct socket *);
void sorecvfrom(struct socket *);
int sosendto(struct socket *, struct mbuf *);
struct socket * solisten(u_int, u_int32_t, u_int, int);
void sorwakeup(struct socket *);
void sowwakeup(struct socket *);
void soisfconnecting(register struct socket *);
void soisfconnected(register struct socket *);
void sofcantrcvmore(struct socket *);
void sofcantsendmore(struct socket *);
void soisfdisconnected(struct socket *);
void sofwdrain(struct socket *);
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 *, struct mbuf *));
struct socket * solisten _P((u_int, u_int32_t, u_int, int));
void soisfconnecting _P((register struct socket *));
void soisfconnected _P((register struct socket *));
void soisfdisconnected _P((struct socket *));
void sofwdrain _P((struct socket *));
#endif /* _SOCKET_H_ */

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -38,8 +42,6 @@ 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 size_t tcp_rcvspace;
extern size_t tcp_sndspace;
extern struct socket *tcp_last_so;
#define TCP_SNDSPACE 8192
@ -49,20 +51,16 @@ extern struct socket *tcp_last_so;
* TCP header.
* Per RFC 793, September, 1981.
*/
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
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_char th_off:4, /* data offset */
u_int th_off:4, /* data offset */
th_x2:4; /* (unused) */
#else
u_char th_x2:4, /* (unused) */
u_int th_x2:4, /* (unused) */
th_off:4; /* data offset */
#endif
u_int8_t th_flags;
@ -75,11 +73,7 @@ struct tcphdr {
u_int16_t th_win; /* window */
u_int16_t th_sum; /* checksum */
u_int16_t th_urp; /* urgent pointer */
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
#include "tcp_var.h"
@ -176,6 +170,6 @@ struct tcphdr {
extern tcp_seq tcp_iss; /* tcp initial send seq # */
extern char *tcpstates[];
extern const char * const tcpstates[];
#endif

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -38,13 +42,12 @@
* terms and conditions of the copyright.
*/
#include <stdlib.h>
#include <slirp.h>
#include "ip_icmp.h"
struct socket tcb;
int tcprexmtthresh = 3;
#define TCPREXMTTHRESH 3
struct socket *tcp_last_so = &tcb;
tcp_seq tcp_iss; /* tcp initial send seq # */
@ -76,8 +79,8 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
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;\
STAT(tcpstat.tcps_rcvpack++); \
STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \
if (so->so_emu) { \
if (tcp_emu((so),(m))) sbappend((so), (m)); \
} else \
@ -96,8 +99,8 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
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;\
STAT(tcpstat.tcps_rcvpack++); \
STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \
if (so->so_emu) { \
if (tcp_emu((so),(m))) sbappend(so, (m)); \
} else \
@ -109,9 +112,13 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
} \
}
#endif
static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
struct tcpiphdr *ti);
static void tcp_xmit_timer(register struct tcpcb *tp, int rtt);
int
tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *m)
static int
tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
struct mbuf *m)
{
register struct tcpiphdr *q;
struct socket *so = tp->t_socket;
@ -144,8 +151,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *
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;
STAT(tcpstat.tcps_rcvduppack++);
STAT(tcpstat.tcps_rcvdupbyte += ti->ti_len);
m_freem(m);
/*
* Try to present any queued data
@ -161,8 +168,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *
}
q = (struct tcpiphdr *)(q->ti_next);
}
tcpstat.tcps_rcvoopack++;
tcpstat.tcps_rcvoobyte += ti->ti_len;
STAT(tcpstat.tcps_rcvoopack++);
STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
REASS_MBUF(ti) = (mbufp_32) m; /* XXX */
/*
@ -226,7 +233,11 @@ present:
* TCP input routine, follows pages 65-76 of the
* protocol specification dated September, 1981 very closely.
*/
void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
void
tcp_input(m, iphlen, inso)
register struct mbuf *m;
int iphlen;
struct socket *inso;
{
struct ip save_ip, *ip;
register struct tcpiphdr *ti;
@ -236,18 +247,16 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
register struct tcpcb *tp = 0;
register int tiflags;
struct socket *so = 0;
int todrop;
u_int acked;
int ourfinisacked, needoutput = 0;
/* int dropsocket = 0; */
int todrop, acked, ourfinisacked, needoutput = 0;
/* int dropsocket = 0; */
int iss = 0;
u_long tiwin;
int ret;
/* int ts_present = 0; */
/* int ts_present = 0; */
DEBUG_CALL("tcp_input");
DEBUG_ARGS((dfd, " m = %8lx iphlen = %2d inso = %lx\n",
(long)m, iphlen, (long)inso));
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
@ -267,15 +276,15 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
}
tcpstat.tcps_rcvtotal++;
STAT(tcpstat.tcps_rcvtotal++);
/*
* Get IP and TCP header together in first mbuf.
* Note: IP leaves IP header in first mbuf.
*/
ti = mtod(m, struct tcpiphdr *);
if (iphlen > sizeof(struct ip)) {
if (iphlen > sizeof(struct ip )) {
ip_stripoptions(m, (struct mbuf *)0);
iphlen = sizeof(struct ip);
iphlen=sizeof(struct ip );
}
/* XXX Check if too short */
@ -284,27 +293,23 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
* Save a copy of the IP header in case we want restore it
* for sending an ICMP error message in response.
*/
ip = mtod(m, struct ip *);
ip=mtod(m, struct ip *);
save_ip = *ip;
save_ip.ip_len += iphlen;
save_ip.ip_len+= iphlen;
/*
* Checksum extended TCP header and data.
*/
tlen = ((struct ip *)ti)->ip_len;
//ti->ti_next = ti->ti_prev = 0;
tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0;
memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
ti->ti_next = ti->ti_prev = 0;
ti->ti_x1 = 0;
ti->ti_len = htons((u_int16_t)tlen);
len = sizeof(struct ip) + 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++;
if(cksum(m, len)) {
STAT(tcpstat.tcps_rcvbadsum++);
goto drop;
}
@ -313,15 +318,15 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
* pull out TCP options and adjust length. XXX
*/
off = ti->ti_off << 2;
if (off < sizeof(struct tcphdr) || off > tlen) {
tcpstat.tcps_rcvbadoff++;
if (off < sizeof (struct tcphdr) || off > tlen) {
STAT(tcpstat.tcps_rcvbadoff++);
goto drop;
}
tlen -= off;
ti->ti_len = tlen;
if (off > sizeof(struct tcphdr)) {
optlen = off - sizeof(struct tcphdr);
optp = mtod(m, caddr_t) + sizeof(struct tcpiphdr);
if (off > sizeof (struct tcphdr)) {
optlen = off - sizeof (struct tcphdr);
optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr);
/*
* Do quick retrieval of timestamp options ("options
@ -330,7 +335,7 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
* quickly get the values now and not bother calling
* tcp_dooptions(), etc.
*/
/* if ((optlen == TCPOLEN_TSTAMP_APPA ||
/* if ((optlen == TCPOLEN_TSTAMP_APPA ||
* (optlen > TCPOLEN_TSTAMP_APPA &&
* optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
* *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
@ -355,8 +360,8 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso)
/*
* 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);
m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
/*
* Locate pcb for segment.
@ -371,7 +376,7 @@ findso:
ti->ti_dst, ti->ti_dport);
if (so)
tcp_last_so = so;
++tcpstat.tcps_socachemiss;
STAT(tcpstat.tcps_socachemiss++);
}
/*
@ -388,7 +393,7 @@ findso:
* as if it was LISTENING, and continue...
*/
if (so == 0) {
if ((tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) != TH_SYN)
if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
goto dropwithreset;
if ((so = socreate()) == NULL)
@ -398,8 +403,8 @@ findso:
goto dropwithreset;
}
sbreserve(&so->so_snd, tcp_sndspace);
sbreserve(&so->so_rcv, tcp_rcvspace);
sbreserve(&so->so_snd, TCP_SNDSPACE);
sbreserve(&so->so_rcv, TCP_RCVSPACE);
/* tcp_last_so = so; */ /* XXX ? */
/* tp = sototcpcb(so); */
@ -444,10 +449,10 @@ findso:
* Reset idle time and keep-alive timer.
*/
tp->t_idle = 0;
if (so_options)
tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
if (SO_OPTIONS)
tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
else
tp->t_timer[TCPT_KEEP] = tcp_keepidle;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;
/*
* Process options if not in LISTEN state,
@ -455,8 +460,8 @@ findso:
*/
if (optp && tp->t_state != TCPS_LISTEN)
tcp_dooptions(tp, (u_char *)optp, optlen, ti);
/* , */
/* &ts_present, &ts_val, &ts_ecr); */
/* , */
/* &ts_present, &ts_val, &ts_ecr); */
/*
* Header prediction: check for the two common cases
@ -477,8 +482,8 @@ findso:
* 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)) && */
(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) {
@ -486,7 +491,7 @@ findso:
* 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) &&
/* 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;
@ -499,16 +504,16 @@ findso:
/*
* this is a pure ack for outstanding data.
*/
++tcpstat.tcps_predack;
/* if (ts_present)
STAT(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))
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;
STAT(tcpstat.tcps_rcvackpack++);
STAT(tcpstat.tcps_rcvackbyte += acked);
sbdrop(&so->so_snd, acked);
tp->snd_una = ti->ti_ack;
m_freem(m);
@ -531,7 +536,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* There's room in so_snd, sowwakup will read()
* from the socket if we can
*/
/* if (so->so_snd.sb_flags & SB_NOTIFY)
/* if (so->so_snd.sb_flags & SB_NOTIFY)
* sowwakeup(so);
*/
/*
@ -544,8 +549,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
return;
}
}
else if (ti->ti_ack == tp->snd_una &&
} else if (ti->ti_ack == tp->snd_una &&
tp->seg_next == (tcpiphdrp_32)tp &&
ti->ti_len <= sbspace(&so->so_rcv)) {
/*
@ -553,17 +557,16 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* with nothing on the reassembly queue and
* we have enough buffer space to take it.
*/
++tcpstat.tcps_preddat;
STAT(tcpstat.tcps_preddat++);
tp->rcv_nxt += ti->ti_len;
tcpstat.tcps_rcvpack++;
tcpstat.tcps_rcvbyte += ti->ti_len;
STAT(tcpstat.tcps_rcvpack++);
STAT(tcpstat.tcps_rcvbyte += ti->ti_len);
/*
* Add data to socket buffer.
*/
if (so->so_emu) {
if (tcp_emu(so, m)) sbappend(so, m);
}
else
if (tcp_emu(so,m)) sbappend(so, m);
} else
sbappend(so, m);
/*
@ -571,7 +574,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* if we can actually write() to the socket
* XXX Need to check? It's be NON_BLOCKING
*/
/* sorwakeup(so); */
/* sorwakeup(so); */
/*
* If this is a short packet, then ACK now - with Nagel
@ -633,27 +636,26 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* 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;
if (lastbyte != CTL_ALIAS && lastbyte != CTL_DNS) {
int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff;
if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) {
#if 0
if (lastbyte == CTL_CMD || lastbyte == CTL_EXEC) {
if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) {
/* Command or exec adress */
so->so_state |= SS_CTL;
}
else
} else
#endif
{
/* May be an add exec */
struct ex_list *ex_ptr;
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == so->so_fport &&
for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if(ex_ptr->ex_fport == so->so_fport &&
lastbyte == ex_ptr->ex_addr) {
so->so_state |= SS_CTL;
break;
}
}
}
if (so->so_state & SS_CTL) goto cont_input;
if(so->so_state & SS_CTL) goto cont_input;
}
/* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */
}
@ -663,34 +665,28 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
goto cont_input;
}
if (tcp_fconnect(so) == -1) {
int error = WSAGetLastError();
if ((error != WSAEINPROGRESS) && (error != WSAEWOULDBLOCK)) {
u_char code = ICMP_UNREACH_NET;
DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n",
errno, strerror(errno)));
if (error == WSAECONNREFUSED) {
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 (error == WSAEHOSTUNREACH) code = ICMP_UNREACH_HOST;
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));
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);
m_free(m);
return;
}
}
} else {
/*
* Haven't connected yet, save the current mbuf
* and ti, and return
@ -701,6 +697,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
so->so_ti = ti;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
tp->t_state = TCPS_SYN_RECEIVED;
}
return;
cont_conn:
@ -723,14 +720,14 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
tp->iss = iss;
else
tp->iss = tcp_iss;
tcp_iss += TCP_ISSINCR / 2;
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++;
STAT(tcpstat.tcps_accepts++);
goto trimthenstep6;
} /* case TCPS_LISTEN */
@ -754,7 +751,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if (tiflags & TH_RST) {
if (tiflags & TH_ACK)
tp = tcp_drop(tp, 0); /* XXX Check t_softerror! */
tp = tcp_drop(tp,0); /* XXX Check t_softerror! */
goto drop;
}
@ -771,7 +768,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
tcp_rcvseqinit(tp);
tp->t_flags |= TF_ACKNOW;
if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
tcpstat.tcps_connects++;
STAT(tcpstat.tcps_connects++);
soisfconnected(so);
tp->t_state = TCPS_ESTABLISHED;
@ -782,7 +779,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* tp->rcv_scale = tp->request_r_scale;
* }
*/
(void)tcp_reass(tp, (struct tcpiphdr *)0,
(void) tcp_reass(tp, (struct tcpiphdr *)0,
(struct mbuf *)0);
/*
* if we didn't have to retransmit the SYN,
@ -790,11 +787,10 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
*/
if (tp->t_rtt)
tcp_xmit_timer(tp, tp->t_rtt);
}
else
} else
tp->t_state = TCPS_SYN_RECEIVED;
trimthenstep6:
trimthenstep6:
/*
* Advance ti->ti_seq to correspond to first data byte.
* If data, trim to stay within window,
@ -806,8 +802,8 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
m_adj(m, -todrop);
ti->ti_len = tp->rcv_wnd;
tiflags &= ~TH_FIN;
tcpstat.tcps_rcvpackafterwin++;
tcpstat.tcps_rcvbyteafterwin += todrop;
STAT(tcpstat.tcps_rcvpackafterwin++);
STAT(tcpstat.tcps_rcvbyteafterwin += todrop);
}
tp->snd_wl1 = ti->ti_seq - 1;
tp->rcv_up = ti->ti_seq;
@ -823,11 +819,11 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* 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 &&
/* 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) {
/* 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
@ -839,7 +835,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* * because we don't want out-of-order segments to be
* * dropped when ts_recent is old.
* */
/* tp->ts_recent = 0;
/* tp->ts_recent = 0;
* } else {
* tcpstat.tcps_rcvduppack++;
* tcpstat.tcps_rcvdupbyte += ti->ti_len;
@ -878,12 +874,11 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
*/
tp->t_flags |= TF_ACKNOW;
todrop = ti->ti_len;
tcpstat.tcps_rcvduppack++;
tcpstat.tcps_rcvdupbyte += todrop;
}
else {
tcpstat.tcps_rcvpartduppack++;
tcpstat.tcps_rcvpartdupbyte += todrop;
STAT(tcpstat.tcps_rcvduppack++);
STAT(tcpstat.tcps_rcvdupbyte += todrop);
} else {
STAT(tcpstat.tcps_rcvpartduppack++);
STAT(tcpstat.tcps_rcvpartdupbyte += todrop);
}
m_adj(m, todrop);
ti->ti_seq += todrop;
@ -902,7 +897,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if ((so->so_state & SS_NOFDREF) &&
tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
tp = tcp_close(tp);
tcpstat.tcps_rcvafterclose++;
STAT(tcpstat.tcps_rcvafterclose++);
goto dropwithreset;
}
@ -910,11 +905,11 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* 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);
todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
if (todrop > 0) {
tcpstat.tcps_rcvpackafterwin++;
STAT(tcpstat.tcps_rcvpackafterwin++);
if (todrop >= ti->ti_len) {
tcpstat.tcps_rcvbyteafterwin += ti->ti_len;
STAT(tcpstat.tcps_rcvbyteafterwin += ti->ti_len);
/*
* If a new connection request is received
* while in TIME_WAIT, drop the old connection
@ -937,23 +932,21 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
*/
if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
tp->t_flags |= TF_ACKNOW;
tcpstat.tcps_rcvwinprobe++;
}
else
STAT(tcpstat.tcps_rcvwinprobe++);
} else
goto dropafterack;
}
else
tcpstat.tcps_rcvbyteafterwin += todrop;
} else
STAT(tcpstat.tcps_rcvbyteafterwin += todrop);
m_adj(m, -todrop);
ti->ti_len -= todrop;
tiflags &= ~(TH_PUSH | TH_FIN);
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) &&
/* 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;
@ -974,17 +967,17 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if (tiflags&TH_RST) switch (tp->t_state) {
case TCPS_SYN_RECEIVED:
/* so->so_error = ECONNREFUSED; */
/* 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; */
/* so->so_error = ECONNRESET; */
close:
tp->t_state = TCPS_CLOSED;
tcpstat.tcps_drops++;
STAT(tcpstat.tcps_drops++);
tp = tcp_close(tp);
goto drop;
@ -1000,7 +993,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* error and we send an RST and drop the connection.
*/
if (tiflags & TH_SYN) {
tp = tcp_drop(tp, 0);
tp = tcp_drop(tp,0);
goto dropwithreset;
}
@ -1023,7 +1016,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
SEQ_GT(ti->ti_ack, tp->snd_max))
goto dropwithreset;
tcpstat.tcps_connects++;
STAT(tcpstat.tcps_connects++);
tp->t_state = TCPS_ESTABLISHED;
/*
* The sent SYN is ack'ed with our sequence number +1
@ -1032,23 +1025,20 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* SS_CTL since the buffer is empty otherwise.
* tp->snd_una++; or:
*/
tp->snd_una = ti->ti_ack;
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) {
} else if (ret == 2) {
so->so_state = SS_NOFDREF; /* CTL_CMD */
}
else {
} else {
needoutput = 1;
tp->t_state = TCPS_FIN_WAIT_1;
}
}
else {
} else {
soisfconnected(so);
}
@ -1059,7 +1049,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* tp->rcv_scale = tp->request_r_scale;
* }
*/
(void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0);
(void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0);
tp->snd_wl1 = ti->ti_seq - 1;
/* Avoid ack processing; snd_una==ti_ack => dup ack */
goto synrx_to_est;
@ -1083,9 +1073,9 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
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));
STAT(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
@ -1113,7 +1103,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if (tp->t_timer[TCPT_REXMT] == 0 ||
ti->ti_ack != tp->snd_una)
tp->t_dupacks = 0;
else if (++tp->t_dupacks == tcprexmtthresh) {
else if (++tp->t_dupacks == TCPREXMTTHRESH) {
tcp_seq onxt = tp->snd_nxt;
u_int win =
min(tp->snd_wnd, tp->snd_cwnd) / 2 /
@ -1126,20 +1116,18 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
tp->t_rtt = 0;
tp->snd_nxt = ti->ti_ack;
tp->snd_cwnd = tp->t_maxseg;
(void)tcp_output(tp);
(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) {
} else if (tp->t_dupacks > TCPREXMTTHRESH) {
tp->snd_cwnd += tp->t_maxseg;
(void)tcp_output(tp);
(void) tcp_output(tp);
goto drop;
}
}
else
} else
tp->t_dupacks = 0;
break;
}
@ -1148,17 +1136,17 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* If the congestion window was inflated to account
* for the other side's cached packets, retract it.
*/
if (tp->t_dupacks > tcprexmtthresh &&
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++;
STAT(tcpstat.tcps_rcvacktoomuch++);
goto dropafterack;
}
acked = ti->ti_ack - tp->snd_una;
tcpstat.tcps_rcvackpack++;
tcpstat.tcps_rcvackbyte += acked;
STAT(tcpstat.tcps_rcvackpack++);
STAT(tcpstat.tcps_rcvackbyte += acked);
/*
* If we have a timestamp reply, update smoothed
@ -1169,12 +1157,12 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* timer backoff (cf., Phil Karn's retransmit alg.).
* Recompute the initial retransmit timer.
*/
/* if (ts_present)
/* 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);
tcp_xmit_timer(tp,tp->t_rtt);
/*
* If all outstanding data is acked, stop retransmit
@ -1185,8 +1173,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if (ti->ti_ack == tp->snd_max) {
tp->t_timer[TCPT_REXMT] = 0;
needoutput = 1;
}
else if (tp->t_timer[TCPT_PERSIST] == 0)
} 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.
@ -1201,14 +1188,13 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
if (cw > tp->snd_ssthresh)
incr = incr * incr / cw;
tp->snd_cwnd = min(cw + incr, (u_int32_t) (TCP_MAXWIN << tp->snd_scale));
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;
sbdrop(&so->so_snd, so->so_snd.sb_cc);
sbdrop(&so->so_snd, (int )so->so_snd.sb_cc);
ourfinisacked = 1;
}
else {
} else {
sbdrop(&so->so_snd, acked);
tp->snd_wnd -= acked;
ourfinisacked = 0;
@ -1217,7 +1203,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
* 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)
/* if (so->so_snd.sb_flags & SB_NOTIFY)
* sowwakeup(so);
*/
tp->snd_una = ti->ti_ack;
@ -1242,7 +1228,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq))
*/
if (so->so_state & SS_FCANTRCVMORE) {
soisfdisconnected(so);
tp->t_timer[TCPT_2MSL] = tcp_maxidle;
tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE;
}
tp->t_state = TCPS_FIN_WAIT_2;
}
@ -1299,7 +1285,7 @@ step6:
/* keep track of pure window updates */
if (ti->ti_len == 0 &&
tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)
tcpstat.tcps_rcvwinupd++;
STAT(tcpstat.tcps_rcvwinupd++);
tp->snd_wnd = tiwin;
tp->snd_wl1 = ti->ti_seq;
tp->snd_wl2 = ti->ti_ack;
@ -1338,15 +1324,14 @@ step6:
* 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)) {
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
} else
/*
* If no out of band data is expected,
* pull receive urgent pointer along
@ -1373,8 +1358,7 @@ dodata:
* buffer size.
*/
len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt);
}
else {
} else {
m_free(m);
tiflags &= ~TH_FIN;
}
@ -1394,7 +1378,7 @@ dodata:
* will got to TCPS_LAST_ACK, and use tcp_output()
* to send the FIN.
*/
/* sofcantrcvmore(so); */
/* sofcantrcvmore(so); */
sofwdrain(so);
tp->t_flags |= TF_ACKNOW;
@ -1408,7 +1392,7 @@ dodata:
*/
case TCPS_SYN_RECEIVED:
case TCPS_ESTABLISHED:
if (so->so_emu == EMU_CTL) /* no shutdown on socket */
if(so->so_emu == EMU_CTL) /* no shutdown on socket */
tp->t_state = TCPS_LAST_ACK;
else
tp->t_state = TCPS_CLOSE_WAIT;
@ -1450,9 +1434,9 @@ dodata:
*
* See above.
*/
/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) {
/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) {
*/
/* 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)) {
@ -1466,7 +1450,7 @@ dodata:
* Return any desired output.
*/
if (needoutput || (tp->t_flags & TF_ACKNOW)) {
(void)tcp_output(tp);
(void) tcp_output(tp);
}
return;
@ -1479,7 +1463,7 @@ dropafterack:
goto drop;
m_freem(m);
tp->t_flags |= TF_ACKNOW;
(void)tcp_output(tp);
(void) tcp_output(tp);
return;
dropwithreset:
@ -1488,8 +1472,8 @@ dropwithreset:
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);
tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
TH_RST|TH_ACK);
}
return;
@ -1507,7 +1491,7 @@ drop:
/* int *ts_present;
* u_int32_t *ts_val, *ts_ecr;
*/
void
static void
tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
{
u_int16_t mss;
@ -1539,7 +1523,7 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
continue;
memcpy((char *) &mss, (char *) cp + 2, sizeof(mss));
NTOHS(mss);
tcp_mss(tp, mss); /* sets t_maxseg */
(void) tcp_mss(tp, mss); /* sets t_maxseg */
break;
/* case TCPOPT_WINDOW:
@ -1584,7 +1568,11 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
#ifdef notdef
void tcp_pulloutofband(struct socket *so, struct tcpiphdr *ti, register struct mbuf *m)
void
tcp_pulloutofband(so, ti, m)
struct socket *so;
struct tcpiphdr *ti;
register struct mbuf *m;
{
int cnt = ti->ti_urp - 1;
@ -1614,7 +1602,8 @@ void tcp_pulloutofband(struct socket *so, struct tcpiphdr *ti, register struct m
* and update averages and current timeout.
*/
void tcp_xmit_timer(register struct tcpcb *tp, int rtt)
static void
tcp_xmit_timer(register struct tcpcb *tp, int rtt)
{
register short delta;
@ -1622,7 +1611,7 @@ void tcp_xmit_timer(register struct tcpcb *tp, int rtt)
DEBUG_ARG("tp = %lx", (long)tp);
DEBUG_ARG("rtt = %d", rtt);
tcpstat.tcps_rttupdated++;
STAT(tcpstat.tcps_rttupdated++);
if (tp->t_srtt != 0) {
/*
* srtt is stored as fixed point with 3 bits after the
@ -1701,16 +1690,19 @@ void tcp_xmit_timer(register struct tcpcb *tp, int rtt)
* parameters from pre-set or cached values in the routing entry.
*/
u_int tcp_mss(register struct tcpcb *tp, u_int offer)
int
tcp_mss(tp, offer)
register struct tcpcb *tp;
u_int offer;
{
struct socket *so = tp->t_socket;
u_int mss;
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);
mss = min(IF_MTU, IF_MRU) - sizeof(struct tcpiphdr);
if (offer)
mss = min(mss, offer);
mss = max(mss, 32);
@ -1719,8 +1711,12 @@ u_int tcp_mss(register struct tcpcb *tp, u_int offer)
tp->snd_cwnd = mss;
sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0));
sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0));
sbreserve(&so->so_snd, TCP_SNDSPACE + ((TCP_SNDSPACE % mss) ?
(mss - (TCP_SNDSPACE % mss)) :
0));
sbreserve(&so->so_rcv, TCP_RCVSPACE + ((TCP_RCVSPACE % mss) ?
(mss - (TCP_RCVSPACE % mss)) :
0));
DEBUG_MISC((dfd, " returning mss = %d\n", mss));

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -44,14 +48,14 @@
* Since this is only used in "stats socket", we give meaning
* names instead of the REAL names
*/
char *tcpstates[] = {
const char * const 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] = {
static const 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,
@ -63,7 +67,9 @@ u_char tcp_outflags[TCP_NSTATES] = {
/*
* Tcp output routine: figure out what should be sent and send it.
*/
int tcp_output(register struct tcpcb *tp)
int
tcp_output(tp)
register struct tcpcb *tp;
{
register struct socket *so = tp->t_socket;
register long len, win;
@ -124,7 +130,7 @@ again:
* to send then the probe will be the FIN
* itself.
*/
if (off < (int)so->so_snd.sb_cc)
if (off < so->so_snd.sb_cc)
flags &= ~TH_FIN;
win = 1;
} else {
@ -199,12 +205,12 @@ again:
* taking into account that we are limited by
* TCP_MAXWIN << tp->rcv_scale.
*/
long adv = min(win, 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))
if (adv >= (long) (2 * tp->t_maxseg))
goto send;
if (2 * adv >= (long)so->so_rcv.sb_datalen)
if (2 * adv >= (long) so->so_rcv.sb_datalen)
goto send;
}
@ -257,7 +263,7 @@ again:
/*
* No reason to send a segment, just return.
*/
tcpstat.tcps_didnuttin++;
STAT(tcpstat.tcps_didnuttin++);
return (0);
@ -333,13 +339,13 @@ send:
*/
if (len) {
if (tp->t_force && len == 1)
tcpstat.tcps_sndprobe++;
STAT(tcpstat.tcps_sndprobe++);
else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
tcpstat.tcps_sndrexmitpack++;
tcpstat.tcps_sndrexmitbyte += len;
STAT(tcpstat.tcps_sndrexmitpack++);
STAT(tcpstat.tcps_sndrexmitbyte += len);
} else {
tcpstat.tcps_sndpack++;
tcpstat.tcps_sndbyte += len;
STAT(tcpstat.tcps_sndpack++);
STAT(tcpstat.tcps_sndbyte += len);
}
m = m_get();
@ -348,7 +354,7 @@ send:
error = 1;
goto out;
}
m->m_data += if_maxlinkhdr;
m->m_data += IF_MAXLINKHDR;
m->m_len = hdrlen;
/*
@ -357,7 +363,7 @@ send:
*/
/* if (len <= MHLEN - hdrlen - max_linkhdr) { */
sbcopy(&so->so_snd, off, len, mtod(m, caddr_t) + hdrlen);
sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen);
m->m_len += len;
/* } else {
@ -376,13 +382,13 @@ send:
flags |= TH_PUSH;
} else {
if (tp->t_flags & TF_ACKNOW)
tcpstat.tcps_sndacks++;
STAT(tcpstat.tcps_sndacks++);
else if (flags & (TH_SYN|TH_FIN|TH_RST))
tcpstat.tcps_sndctrl++;
STAT(tcpstat.tcps_sndctrl++);
else if (SEQ_GT(tp->snd_up, tp->snd_una))
tcpstat.tcps_sndurg++;
STAT(tcpstat.tcps_sndurg++);
else
tcpstat.tcps_sndwinup++;
STAT(tcpstat.tcps_sndwinup++);
m = m_get();
if (m == NULL) {
@ -390,7 +396,7 @@ send:
error = 1;
goto out;
}
m->m_data += if_maxlinkhdr;
m->m_data += IF_MAXLINKHDR;
m->m_len = hdrlen;
}
@ -433,12 +439,12 @@ send:
* Calculate receive window. Don't shrink window,
* but avoid silly window syndrome.
*/
if (win < (so->so_rcv.sb_datalen / 4) && win < tp->t_maxseg)
if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg)
win = 0;
if (win > (u_long) (TCP_MAXWIN << tp->rcv_scale))
win = (u_long) (TCP_MAXWIN << tp->rcv_scale);
if (win < (tp->rcv_adv - tp->rcv_nxt))
win = (tp->rcv_adv - tp->rcv_nxt);
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)) {
@ -494,7 +500,7 @@ send:
if (tp->t_rtt == 0) {
tp->t_rtt = 1;
tp->t_rtseq = startseq;
tcpstat.tcps_segstimed++;
STAT(tcpstat.tcps_segstimed++);
}
}
@ -528,9 +534,9 @@ send:
{
((struct ip *)ti)->ip_len = (u_int16_t) m->m_len;
((struct ip *)ti)->ip_len = m->m_len;
((struct ip *)ti)->ip_ttl = ip_defttl;
((struct ip *)ti)->ip_ttl = IPDEFTTL;
((struct ip *)ti)->ip_tos = so->so_iptos;
/* #if BSD >= 43 */
@ -561,7 +567,7 @@ out:
*/
return (error);
}
tcpstat.tcps_sndtotal++;
STAT(tcpstat.tcps_sndtotal++);
/*
* Data sent (as far as we can tell).
@ -579,7 +585,9 @@ out:
return (0);
}
void tcp_setpersist(register struct tcpcb *tp)
void
tcp_setpersist(tp)
register struct tcpcb *tp;
{
int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -39,31 +43,20 @@
*/
#define WANT_SYS_IOCTL_H
#include <stdlib.h>
#include <slirp.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 */
size_t tcp_rcvspace; /* You may want to change this */
size_t tcp_sndspace; /* Keep small if you have an error prone link */
/* Don't do rfc1323 performance enhancements */
#define TCP_DO_RFC1323 0
/*
* Tcp initialization
*/
void tcp_init()
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));
}
/*
@ -73,7 +66,9 @@ void tcp_init()
* necessary when the connection is used.
*/
/* struct tcpiphdr * */
void tcp_template(struct tcpcb *tp)
void
tcp_template(tp)
struct tcpcb *tp;
{
struct socket *so = tp->t_socket;
register struct tcpiphdr *n = &tp->t_template;
@ -110,8 +105,13 @@ void tcp_template(struct tcpcb *tp)
* In any case the ack and sequence number of the transmitted
* segment are as specified by the parameters.
*/
void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti,
register struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags)
void
tcp_respond(tp, ti, m, ack, seq, flags)
struct tcpcb *tp;
register struct tcpiphdr *ti;
register struct mbuf *m;
tcp_seq ack, seq;
int flags;
{
register int tlen;
int win = 0;
@ -134,7 +134,7 @@ void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti,
#else
tlen = 0;
#endif
m->m_data += if_maxlinkhdr;
m->m_data += IF_MAXLINKHDR;
*mtod(m, struct tcpiphdr *) = *ti;
ti = mtod(m, struct tcpiphdr *);
flags = TH_ACK;
@ -175,7 +175,7 @@ void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti,
if(flags & TH_RST)
((struct ip *)ti)->ip_ttl = MAXTTL;
else
((struct ip *)ti)->ip_ttl = ip_defttl;
((struct ip *)ti)->ip_ttl = IPDEFTTL;
(void) ip_output((struct socket *)0, m);
}
@ -185,7 +185,9 @@ void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti,
* empty reassembly queue and hooking it to the argument
* protocol control block.
*/
struct tcpcb *tcp_newtcpcb(struct socket *so)
struct tcpcb *
tcp_newtcpcb(so)
struct socket *so;
{
register struct tcpcb *tp;
@ -195,9 +197,9 @@ struct tcpcb *tcp_newtcpcb(struct socket *so)
memset((char *) tp, 0, sizeof(struct tcpcb));
tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
tp->t_maxseg = tcp_mssdflt;
tp->t_maxseg = TCP_MSS;
tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
tp->t_socket = so;
/*
@ -206,7 +208,7 @@ struct tcpcb *tcp_newtcpcb(struct socket *so)
* reasonable initial retransmit time.
*/
tp->t_srtt = TCPTV_SRTTBASE;
tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
tp->t_rttvar = TCPTV_SRTTDFLT << 2;
tp->t_rttmin = TCPTV_MIN;
TCPT_RANGESET(tp->t_rxtcur,
@ -242,9 +244,9 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
if (TCPS_HAVERCVDSYN(tp->t_state)) {
tp->t_state = TCPS_CLOSED;
(void) tcp_output(tp);
tcpstat.tcps_drops++;
STAT(tcpstat.tcps_drops++);
} else
tcpstat.tcps_conndrops++;
STAT(tcpstat.tcps_conndrops++);
/* if (errno == ETIMEDOUT && tp->t_softerror)
* errno = tp->t_softerror;
*/
@ -258,7 +260,9 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
* discard internet protocol block
* wake up any sleepers
*/
struct tcpcb *tcp_close(register struct tcpcb *tp)
struct tcpcb *
tcp_close(tp)
register struct tcpcb *tp;
{
register struct tcpiphdr *t;
struct socket *so = tp->t_socket;
@ -290,11 +294,13 @@ struct tcpcb *tcp_close(register struct tcpcb *tp)
sbfree(&so->so_rcv);
sbfree(&so->so_snd);
sofree(so);
tcpstat.tcps_closed++;
STAT(tcpstat.tcps_closed++);
return ((struct tcpcb *)0);
}
void tcp_drain()
#ifdef notdef
void
tcp_drain()
{
/* XXX */
}
@ -303,10 +309,10 @@ void tcp_drain()
* When a source quench is received, close congestion window
* to one segment. We will gradually open it again as we proceed.
*/
void
tcp_quench(i, errno)
#ifdef notdef
void tcp_quench(int i, int errno)
int errno;
{
struct tcpcb *tp = intotcpcb(inp);
@ -330,7 +336,9 @@ void tcp_quench(int i, int errno)
* 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(struct tcpcb *tp)
void
tcp_sockclosed(tp)
struct tcpcb *tp;
{
DEBUG_CALL("tcp_sockclosed");
@ -371,7 +379,8 @@ void tcp_sockclosed(struct tcpcb *tp)
* nonblocking. Connect returns after the SYN is sent, and does
* not wait for ACK+SYN.
*/
int tcp_fconnect(struct socket *so)
int tcp_fconnect(so)
struct socket *so;
{
int ret=0;
@ -381,7 +390,6 @@ int tcp_fconnect(struct socket *so)
if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) {
int opt, s=so->s;
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
fd_nonblock(s);
opt = 1;
@ -405,11 +413,9 @@ int tcp_fconnect(struct socket *so)
addr.sin_addr = so->so_faddr;
addr.sin_port = so->so_fport;
char addrstr[INET_ADDRSTRLEN];
DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, "
"addr.sin_addr.s_addr=%.16s\n",
ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr,
addrstr, sizeof(addrstr))));
ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
/* We don't care what port we get */
ret = connect(s,(struct sockaddr *)&addr,sizeof (addr));
@ -435,11 +441,13 @@ int tcp_fconnect(struct socket *so)
* the time it gets to accept(), so... We simply accept
* here and SYN the local-host.
*/
void tcp_connect(struct socket *inso)
void
tcp_connect(inso)
struct socket *inso;
{
struct socket *so;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
int addrlen = sizeof(struct sockaddr_in);
struct tcpcb *tp;
int s, opt;
@ -467,7 +475,7 @@ void tcp_connect(struct socket *inso)
so->so_lport = inso->so_lport;
}
tcp_mss(sototcpcb(so), 0);
(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 */
@ -507,7 +515,7 @@ void tcp_connect(struct socket *inso)
*/
/* soisconnecting(so); */ /* NOFDREF used instead */
tcpstat.tcps_connattempt++;
STAT(tcpstat.tcps_connattempt++);
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
@ -520,7 +528,9 @@ void tcp_connect(struct socket *inso)
/*
* Attach a TCPCB to a socket.
*/
int tcp_attach(struct socket *so)
int
tcp_attach(so)
struct socket *so;
{
if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
return -1;
@ -533,7 +543,7 @@ int tcp_attach(struct socket *so)
/*
* Set the socket's type of service field
*/
struct tos_t tcptos[] = {
static const 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 */
@ -549,12 +559,17 @@ struct tos_t tcptos[] = {
{0, 0, 0, 0}
};
#ifdef CONFIG_QEMU
static
#endif
struct emu_t *tcpemu = 0;
/*
* Return TOS according to the above table
*/
u_int8_t tcp_tos(struct socket *so)
u_int8_t
tcp_tos(so)
struct socket *so;
{
int i = 0;
struct emu_t *emup;
@ -580,7 +595,9 @@ u_int8_t tcp_tos(struct socket *so)
return 0;
}
#if 0
int do_echo = -1;
#endif
/*
* Emulate programs that try and connect to us
@ -606,7 +623,10 @@ int do_echo = -1;
*
* NOTE: if you return 0 you MUST m_free() the mbuf!
*/
int tcp_emu(struct socket *so, struct mbuf *m)
int
tcp_emu(so, m)
struct socket *so;
struct mbuf *m;
{
u_int n1, n2, n3, n4, n5, n6;
char buff[256];
@ -629,7 +649,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
{
struct socket *tmpso;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
int addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = &so->so_rcv;
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
@ -637,7 +657,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
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) {
if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) {
HTONS(n1);
HTONS(n2);
/* n2 is the one on our host */
@ -807,7 +827,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
ns->so_laddr=so->so_laddr;
ns->so_lport=htons(port);
tcp_mss(sototcpcb(ns), 0);
(void) tcp_mss(sototcpcb(ns), 0);
ns->so_faddr=so->so_faddr;
ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */
@ -829,7 +849,7 @@ int tcp_emu(struct socket *so, struct mbuf *m)
/*soisfconnecting(ns);*/
tcpstat.tcps_connattempt++;
STAT(tcpstat.tcps_connattempt++);
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
@ -963,7 +983,7 @@ do_prompt:
/*
* Need to emulate the PORT command
*/
x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]",
&n1, &n2, &n3, &n4, &n5, &n6, buff);
if (x < 6)
return 1;
@ -994,7 +1014,7 @@ do_prompt:
/*
* Need to emulate the PASV response
*/
x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]",
x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]",
&n1, &n2, &n3, &n4, &n5, &n6, buff);
if (x < 6)
return 1;
@ -1034,7 +1054,7 @@ do_prompt:
* of the connection as a NUL-terminated decimal ASCII string.
*/
so->so_emu = 0;
for (lport = 0, i = 0; i < (int) (m->m_len-1); ++i) {
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;
@ -1219,7 +1239,9 @@ do_prompt:
* Return 0 if this connections is to be closed, 1 otherwise,
* return 2 if this is a command-line connection
*/
int tcp_ctl(struct socket *so)
int
tcp_ctl(so)
struct socket *so;
{
struct sbuf *sb = &so->so_snd;
int command;

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -32,14 +36,14 @@
#include <slirp.h>
int tcp_keepidle = TCPTV_KEEP_IDLE;
int tcp_keepintvl = TCPTV_KEEPINTVL;
int tcp_maxidle;
int so_options = DO_KEEPALIVE;
#ifdef LOG_ENABLED
struct tcpstat tcpstat; /* tcp statistics */
#endif
u_int32_t tcp_now; /* for RFC 1323 timestamps */
static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
/*
* Fast timeout routine for processing delayed acks
*/
@ -58,7 +62,7 @@ tcp_fasttimo()
(tp->t_flags & TF_DELACK)) {
tp->t_flags &= ~TF_DELACK;
tp->t_flags |= TF_ACKNOW;
tcpstat.tcps_delack++;
STAT(tcpstat.tcps_delack++);
(void) tcp_output(tp);
}
}
@ -77,7 +81,6 @@ tcp_slowtimo()
DEBUG_CALL("tcp_slowtimo");
tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
/*
* Search through tcb's and update active timers.
*/
@ -123,16 +126,14 @@ tcp_canceltimers(tp)
tp->t_timer[i] = 0;
}
int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
const 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;
static struct tcpcb *
tcp_timers(register struct tcpcb *tp, int timer)
{
register int rexmt;
@ -148,8 +149,8 @@ tcp_timers(tp, timer)
*/
case TCPT_2MSL:
if (tp->t_state != TCPS_TIME_WAIT &&
tp->t_idle <= tcp_maxidle)
tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
tp->t_idle <= TCP_MAXIDLE)
tp->t_timer[TCPT_2MSL] = TCPTV_KEEPINTVL;
else
tp = tcp_close(tp);
break;
@ -188,7 +189,7 @@ tcp_timers(tp, timer)
* We tried our best, now the connection must die!
*/
tp->t_rxtshift = TCP_MAXRXTSHIFT;
tcpstat.tcps_timeoutdrop++;
STAT(tcpstat.tcps_timeoutdrop++);
tp = tcp_drop(tp, tp->t_softerror);
/* tp->t_softerror : ETIMEDOUT); */ /* XXX */
return (tp); /* XXX */
@ -200,7 +201,7 @@ tcp_timers(tp, timer)
*/
tp->t_rxtshift = 6;
}
tcpstat.tcps_rexmttimeo++;
STAT(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 */
@ -263,7 +264,7 @@ tcp_timers(tp, timer)
* Force a byte to be output, if possible.
*/
case TCPT_PERSIST:
tcpstat.tcps_persisttimeo++;
STAT(tcpstat.tcps_persisttimeo++);
tcp_setpersist(tp);
tp->t_force = 1;
(void) tcp_output(tp);
@ -275,13 +276,13 @@ tcp_timers(tp, timer)
* or drop connection if idle for too long.
*/
case TCPT_KEEP:
tcpstat.tcps_keeptimeo++;
STAT(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)
if ((SO_OPTIONS) && tp->t_state <= TCPS_CLOSE_WAIT) {
if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE)
goto dropit;
/*
* Send a packet designed to force a response
@ -295,7 +296,7 @@ tcp_timers(tp, timer)
* by the protocol spec, this requires the
* correspondent TCP to respond.
*/
tcpstat.tcps_keepprobe++;
STAT(tcpstat.tcps_keepprobe++);
#ifdef TCP_COMPAT_42
/*
* The keepalive packet must have nonzero length
@ -307,13 +308,13 @@ tcp_timers(tp, timer)
tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
tp->rcv_nxt, tp->snd_una - 1, 0);
#endif
tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
} else
tp->t_timer[TCPT_KEEP] = tcp_keepidle;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;
break;
dropit:
tcpstat.tcps_keepdrops++;
STAT(tcpstat.tcps_keepdrops++);
tp = tcp_drop(tp, 0); /* ETIMEDOUT); */
break;
}

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -122,17 +126,12 @@ char *tcptimers[] =
(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[];
extern const int tcp_backoff[];
struct tcpcb;
void tcp_fasttimo(void);
void tcp_slowtimo(void);
void tcp_canceltimers(struct tcpcb *);
struct tcpcb * tcp_timers(register struct tcpcb *, int);
void tcp_fasttimo _P((void));
void tcp_slowtimo _P((void));
void tcp_canceltimers _P((struct tcpcb *));
#endif

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -181,6 +185,7 @@ typedef u_int32_t mbufp_32;
#endif
#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
#ifdef LOG_ENABLED
/*
* TCP statistics.
* Many of these should be kept per connection,
@ -243,6 +248,8 @@ struct tcpstat {
};
extern struct tcpstat tcpstat; /* tcp statistics */
#endif
extern u_int32_t tcp_now; /* for RFC 1323 timestamps */
#endif

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*

View File

@ -26,7 +26,7 @@
struct tftp_session {
int in_use;
char filename[TFTP_FILENAME_MAX];
unsigned char filename[TFTP_FILENAME_MAX];
struct in_addr client_ip;
u_int16_t client_port;
@ -34,7 +34,7 @@ struct tftp_session {
int timestamp;
};
struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
const char *tftp_prefix;
@ -102,8 +102,15 @@ static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr,
{
int fd;
int bytes_read = 0;
char buffer[1024];
int n;
fd = open(spt->filename, O_RDONLY | O_BINARY);
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;
@ -120,6 +127,45 @@ static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr,
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;
struct mbuf *m;
struct tftp_t *tp;
int n = 0;
m = m_get();
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(tp->x.tp_buf + n, "%s", key) + 1;
n += sprintf(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)
@ -127,6 +173,7 @@ static int tftp_send_error(struct tftp_session *spt,
struct sockaddr_in saddr, daddr;
struct mbuf *m;
struct tftp_t *tp;
int nobytes;
m = m_get();
@ -136,14 +183,13 @@ static int tftp_send_error(struct tftp_session *spt,
memset(m->m_data, 0, m->m_size);
m->m_data += if_maxlinkhdr;
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);
strncpy((char *)tp->x.tp_error.tp_msg, msg, sizeof(tp->x.tp_error.tp_msg));
tp->x.tp_error.tp_msg[sizeof(tp->x.tp_error.tp_msg)-1] = 0;
strcpy(tp->x.tp_error.tp_msg, msg);
saddr.sin_addr = recv_tp->ip.ip_dst;
saddr.sin_port = recv_tp->udp.uh_dport;
@ -151,6 +197,8 @@ static int tftp_send_error(struct tftp_session *spt,
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);
@ -182,7 +230,7 @@ static int tftp_send_data(struct tftp_session *spt,
memset(m->m_data, 0, m->m_size);
m->m_data += if_maxlinkhdr;
m->m_data += IF_MAXLINKHDR;
tp = (void *)m->m_data;
m->m_data += sizeof(struct udpiphdr);
@ -237,7 +285,7 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
spt = &tftp_sessions[s];
src = tp->x.tp_buf;
dst = (u_int8_t *)spt->filename;
dst = spt->filename;
n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
/* get name */
@ -271,6 +319,8 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
return;
}
k += 6; /* skipping octet */
/* do sanity checks on the filename */
if ((spt->filename[0] != '/')
@ -282,19 +332,60 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
/* only allow exported prefixes */
if (!tftp_prefix
|| (strncmp(spt->filename, tftp_prefix, strlen(tftp_prefix)) != 0)) {
if (!tftp_prefix) {
tftp_send_error(spt, 2, "Access violation", tp);
return;
}
/* check if the file exists */
if (tftp_read_data(spt, 0, (u_int8_t *)spt->filename, 0) < 0) {
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 = src + k;
k += strlen(key) + 1;
if (k >= n) {
tftp_send_error(spt, 2, "Access violation", tp);
return;
}
value = 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);
}

View File

@ -9,13 +9,10 @@
#define TFTP_DATA 3
#define TFTP_ACK 4
#define TFTP_ERROR 5
#define TFTP_OACK 6
#define TFTP_FILENAME_MAX 512
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
struct tftp_t {
struct ip ip;
struct udphdr udp;
@ -31,10 +28,6 @@ struct tftp_t {
} tp_error;
u_int8_t tp_buf[512 + 2];
} x;
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
void tftp_input(struct mbuf *m);

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -38,22 +42,26 @@
* terms and conditions of the copyright.
*/
#include <stdlib.h>
#include <slirp.h>
#include "ip_icmp.h"
#ifdef LOG_ENABLED
struct udpstat udpstat;
#endif
struct socket udb;
static u_int8_t udp_tos(struct socket *so);
static void udp_emu(struct socket *so, struct mbuf *m);
/*
* UDP protocol implementation.
* Per RFC 768, August, 1980.
*/
#ifndef COMPAT_42
int udpcksum = 1;
#define UDPCKSUM 1
#else
int udpcksum = 0; /* XXX */
#define UDPCKSUM 0 /* XXX */
#endif
struct socket *udp_last_so = &udb;
@ -83,7 +91,7 @@ udp_input(m, iphlen)
DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("iphlen = %d", iphlen);
udpstat.udps_ipackets++;
STAT(udpstat.udps_ipackets++);
/*
* Strip IP options, if any; should skip this,
@ -110,7 +118,7 @@ udp_input(m, iphlen)
if (ip->ip_len != len) {
if (len > ip->ip_len) {
udpstat.udps_badlen++;
STAT(udpstat.udps_badlen++);
goto bad;
}
m_adj(m, len - ip->ip_len);
@ -127,7 +135,7 @@ udp_input(m, iphlen)
/*
* Checksum extended UDP header and data.
*/
if (udpcksum && uh->uh_sum) {
if (UDPCKSUM && uh->uh_sum) {
((struct ipovly *)ip)->ih_next = 0;
((struct ipovly *)ip)->ih_prev = 0;
((struct ipovly *)ip)->ih_x1 = 0;
@ -137,7 +145,7 @@ udp_input(m, iphlen)
* if (uh->uh_sum) {
*/
if(cksum(m, len + sizeof(struct ip))) {
udpstat.udps_badsum++;
STAT(udpstat.udps_badsum++);
goto bad;
}
}
@ -178,7 +186,7 @@ udp_input(m, iphlen)
if (tmp == &udb) {
so = NULL;
} else {
udpstat.udpps_pcbcachemiss++;
STAT(udpstat.udpps_pcbcachemiss++);
udp_last_so = so;
}
}
@ -272,13 +280,10 @@ int udp_output2(struct socket *so, struct mbuf *m,
* and addresses and length put into network format.
*/
ui = mtod(m, struct udpiphdr *);
//ui->ui_next = ui->ui_prev = 0;
memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
ui->ui_next = ui->ui_prev = 0;
ui->ui_x1 = 0;
ui->ui_pr = IPPROTO_UDP;
ui->ui_len = htons((u_short) (m->m_len - sizeof(struct ip))); /* + sizeof (struct udphdr)); */
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;
@ -290,16 +295,16 @@ int udp_output2(struct socket *so, struct mbuf *m,
* Stuff checksum and output datagram.
*/
ui->ui_sum = 0;
if (udpcksum) {
if (UDPCKSUM) {
if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0)
ui->ui_sum = 0xffff;
}
((struct ip *)ui)->ip_len = (u_int16_t) m->m_len;
((struct ip *)ui)->ip_len = m->m_len;
((struct ip *)ui)->ip_ttl = ip_defttl;
((struct ip *)ui)->ip_ttl = IPDEFTTL;
((struct ip *)ui)->ip_tos = iptos;
udpstat.udps_opackets++;
STAT(udpstat.udps_opackets++);
error = ip_output(so, m);
@ -336,15 +341,18 @@ udp_attach(so)
* (sendto() on an unbound socket will bind it), it's done
* here so that emulation of ytalk etc. don't have to do it
*/
memset(&addr, 0, sizeof(struct sockaddr_in));
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 error = WSAGetLastError();
int lasterrno=errno;
closesocket(so->s);
so->s=-1;
WSASetLastError(error);
#ifdef _WIN32
WSASetLastError(lasterrno);
#else
errno=lasterrno;
#endif
} else {
/* success, insert in queue */
so->so_expire = curtime + SO_EXPIRE;
@ -364,7 +372,7 @@ udp_detach(so)
sofree(so);
}
struct tos_t udptos[] = {
static const struct tos_t udptos[] = {
{0, 53, IPTOS_LOWDELAY, 0}, /* DNS */
{517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */
{518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */
@ -372,9 +380,8 @@ struct tos_t udptos[] = {
{0, 0, 0, 0}
};
u_int8_t
udp_tos(so)
struct socket *so;
static u_int8_t
udp_tos(struct socket *so)
{
int i = 0;
@ -397,13 +404,11 @@ udp_tos(so)
/*
* Here, talk/ytalk/ntalk requests must be emulated
*/
void
udp_emu(so, m)
struct socket *so;
struct mbuf *m;
static void
udp_emu(struct socket *so, struct mbuf *m)
{
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
int addrlen = sizeof(addr);
#ifdef EMULATE_TALK
CTL_MSG_OLD *omsg;
CTL_MSG *nmsg;
@ -634,8 +639,7 @@ udp_listen(port, laddr, lport, flags)
{
struct sockaddr_in addr;
struct socket *so;
socklen_t addrlen = sizeof(struct sockaddr_in);
int opt = 1;
int addrlen = sizeof(struct sockaddr_in), opt = 1;
if ((so = socreate()) == NULL) {
free(so);
@ -645,7 +649,6 @@ udp_listen(port, laddr, lport, flags)
so->so_expire = curtime + SO_EXPIRE;
insque(so,&udb);
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = port;

View File

@ -10,7 +10,11 @@
* 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. Neither the name of the University nor the names of its contributors
* 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.
*
@ -42,20 +46,12 @@ extern struct socket *udp_last_so;
* Udp protocol header.
* Per RFC 768, September, 1981.
*/
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(1)
#endif
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 */
} PACKED__;
#ifdef PRAGMA_PACK_SUPPORTED
#pragma pack(PACK_RESET)
#endif
};
/*
* UDP kernel structures and variables.
@ -76,6 +72,7 @@ struct udpiphdr {
#define ui_ulen ui_u.uh_ulen
#define ui_sum ui_u.uh_sum
#ifdef LOG_ENABLED
struct udpstat {
/* input statistics: */
u_long udps_ipackets; /* total input packets */
@ -89,6 +86,7 @@ struct udpstat {
/* output statistics: */
u_long udps_opackets; /* total output packets */
};
#endif
/*
* Names for UDP sysctl objects
@ -96,18 +94,19 @@ struct udpstat {
#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
#define UDPCTL_MAXID 2
#ifdef LOG_ENABLED
extern struct udpstat udpstat;
#endif
extern struct socket udb;
struct mbuf;
void udp_init(void);
void udp_input(register struct mbuf *, int);
int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *);
int udp_attach(struct socket *);
void udp_detach(struct socket *);
u_int8_t udp_tos(struct socket *);
void udp_emu(struct socket *, struct mbuf *);
struct socket * udp_listen(u_int, u_int32_t, u_int, int);
void udp_init _P((void));
void udp_input _P((register struct mbuf *, int));
int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *));
int udp_attach _P((struct socket *));
void udp_detach _P((struct socket *));
struct socket * udp_listen _P((u_int, u_int32_t, u_int, int));
int udp_output2(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos);