mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-11 13:29:30 +00:00
SLIRP 0.9.1
This commit is contained in:
parent
000ec0f135
commit
4682bb80a1
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user