mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-11 13:29:30 +00:00
SLIRP 0.10.1
64 Bits clean ?
This commit is contained in:
parent
4682bb80a1
commit
ef4725552e
|
@ -25,9 +25,6 @@ The copyright terms and conditions:
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
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,
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
|
|
@ -36,7 +36,7 @@ typedef struct {
|
||||||
uint8_t macaddr[6];
|
uint8_t macaddr[6];
|
||||||
} BOOTPClient;
|
} BOOTPClient;
|
||||||
|
|
||||||
BOOTPClient bootp_clients[NB_ADDR];
|
static BOOTPClient bootp_clients[NB_ADDR];
|
||||||
|
|
||||||
const char *bootp_filename;
|
const char *bootp_filename;
|
||||||
|
|
||||||
|
@ -172,7 +172,8 @@ static void bootp_reply(struct bootp_t *bp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bootp_filename)
|
if (bootp_filename)
|
||||||
snprintf(rbp->bp_file, sizeof(rbp->bp_file), "%s", bootp_filename);
|
snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
|
||||||
|
bootp_filename);
|
||||||
|
|
||||||
dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr));
|
dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr));
|
||||||
|
|
||||||
|
@ -190,6 +191,8 @@ static void bootp_reply(struct bootp_t *bp)
|
||||||
rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
|
rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
|
||||||
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
|
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
|
||||||
|
|
||||||
|
daddr.sin_addr.s_addr = 0xffffffffu;
|
||||||
|
|
||||||
q = rbp->bp_vend;
|
q = rbp->bp_vend;
|
||||||
memcpy(q, rfc1533_cookie, 4);
|
memcpy(q, rfc1533_cookie, 4);
|
||||||
q += 4;
|
q += 4;
|
||||||
|
@ -218,16 +221,18 @@ static void bootp_reply(struct bootp_t *bp)
|
||||||
*q++ = 0xff;
|
*q++ = 0xff;
|
||||||
*q++ = 0x00;
|
*q++ = 0x00;
|
||||||
|
|
||||||
*q++ = RFC1533_GATEWAY;
|
if (!slirp_restrict) {
|
||||||
*q++ = 4;
|
*q++ = RFC1533_GATEWAY;
|
||||||
memcpy(q, &saddr.sin_addr, 4);
|
*q++ = 4;
|
||||||
q += 4;
|
memcpy(q, &saddr.sin_addr, 4);
|
||||||
|
q += 4;
|
||||||
|
|
||||||
*q++ = RFC1533_DNS;
|
*q++ = RFC1533_DNS;
|
||||||
*q++ = 4;
|
*q++ = 4;
|
||||||
dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
|
dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
|
||||||
memcpy(q, &dns_addr, 4);
|
memcpy(q, &dns_addr, 4);
|
||||||
q += 4;
|
q += 4;
|
||||||
|
}
|
||||||
|
|
||||||
*q++ = RFC2132_LEASE_TIME;
|
*q++ = RFC2132_LEASE_TIME;
|
||||||
*q++ = 4;
|
*q++ = 4;
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,8 +16,6 @@ int dostats = 0;
|
||||||
#endif
|
#endif
|
||||||
int slirp_debug = 0;
|
int slirp_debug = 0;
|
||||||
|
|
||||||
extern char *strerror _P((int));
|
|
||||||
|
|
||||||
/* Carry over one item from main.c so that the tty's restored.
|
/* Carry over one item from main.c so that the tty's restored.
|
||||||
* Only done when the tty being used is /dev/tty --RedWolf */
|
* Only done when the tty being used is /dev/tty --RedWolf */
|
||||||
#ifndef CONFIG_QEMU
|
#ifndef CONFIG_QEMU
|
||||||
|
|
|
@ -37,4 +37,3 @@ extern int slirp_debug;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void debug_init _P((char *, int));
|
void debug_init _P((char *, int));
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,9 +15,8 @@ struct mbuf *next_m; /* Pointer to next mbuf to output */
|
||||||
|
|
||||||
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
|
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
|
||||||
|
|
||||||
void
|
static void
|
||||||
ifs_insque(ifm, ifmhead)
|
ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
|
||||||
struct mbuf *ifm, *ifmhead;
|
|
||||||
{
|
{
|
||||||
ifm->ifs_next = ifmhead->ifs_next;
|
ifm->ifs_next = ifmhead->ifs_next;
|
||||||
ifmhead->ifs_next = ifm;
|
ifmhead->ifs_next = ifm;
|
||||||
|
@ -25,9 +24,8 @@ ifs_insque(ifm, ifmhead)
|
||||||
ifm->ifs_next->ifs_prev = ifm;
|
ifm->ifs_next->ifs_prev = ifm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ifs_remque(ifm)
|
ifs_remque(struct mbuf *ifm)
|
||||||
struct mbuf *ifm;
|
|
||||||
{
|
{
|
||||||
ifm->ifs_prev->ifs_next = ifm->ifs_next;
|
ifm->ifs_prev->ifs_next = ifm->ifs_next;
|
||||||
ifm->ifs_next->ifs_prev = ifm->ifs_prev;
|
ifm->ifs_next->ifs_prev = ifm->ifs_prev;
|
||||||
|
@ -291,7 +289,7 @@ if_start(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encapsulate the packet for sending */
|
/* Encapsulate the packet for sending */
|
||||||
if_encap(ifm->m_data, ifm->m_len);
|
if_encap((uint8_t *)ifm->m_data, ifm->m_len);
|
||||||
|
|
||||||
m_free(ifm);
|
m_free(ifm);
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -183,35 +179,31 @@ struct ip_timestamp {
|
||||||
|
|
||||||
#define IP_MSS 576 /* default maximum segment size */
|
#define IP_MSS 576 /* default maximum segment size */
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */
|
|
||||||
#include <sys/types32.h>
|
|
||||||
#else
|
|
||||||
#if SIZEOF_CHAR_P == 4
|
#if SIZEOF_CHAR_P == 4
|
||||||
typedef caddr_t caddr32_t;
|
struct mbuf_ptr {
|
||||||
|
struct mbuf *mptr;
|
||||||
|
uint32_t dummy;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
typedef u_int32_t caddr32_t;
|
struct mbuf_ptr {
|
||||||
#endif
|
struct mbuf *mptr;
|
||||||
#endif
|
};
|
||||||
|
|
||||||
#if SIZEOF_CHAR_P == 4
|
|
||||||
typedef struct ipq *ipqp_32;
|
|
||||||
typedef struct ipasfrag *ipasfragp_32;
|
|
||||||
#else
|
|
||||||
typedef caddr32_t ipqp_32;
|
|
||||||
typedef caddr32_t ipasfragp_32;
|
|
||||||
#endif
|
#endif
|
||||||
|
struct qlink {
|
||||||
|
void *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Overlay for ip header used by other protocols (tcp, udp).
|
* Overlay for ip header used by other protocols (tcp, udp).
|
||||||
*/
|
*/
|
||||||
struct ipovly {
|
struct ipovly {
|
||||||
caddr32_t ih_next, ih_prev; /* for protocol sequence q's */
|
struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */
|
||||||
u_int8_t ih_x1; /* (unused) */
|
u_int8_t ih_x1; /* (unused) */
|
||||||
u_int8_t ih_pr; /* protocol */
|
u_int8_t ih_pr; /* protocol */
|
||||||
u_int16_t ih_len; /* protocol length */
|
u_int16_t ih_len; /* protocol length */
|
||||||
struct in_addr ih_src; /* source internet address */
|
struct in_addr ih_src; /* source internet address */
|
||||||
struct in_addr ih_dst; /* destination internet address */
|
struct in_addr ih_dst; /* destination internet address */
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ip reassembly queue structure. Each fragment
|
* Ip reassembly queue structure. Each fragment
|
||||||
|
@ -221,44 +213,30 @@ struct ipovly {
|
||||||
* size 28 bytes
|
* size 28 bytes
|
||||||
*/
|
*/
|
||||||
struct ipq {
|
struct ipq {
|
||||||
ipqp_32 next,prev; /* to other reass headers */
|
struct qlink frag_link; /* to ip headers of fragments */
|
||||||
|
struct qlink ip_link; /* to other reass headers */
|
||||||
u_int8_t ipq_ttl; /* time for reass q to live */
|
u_int8_t ipq_ttl; /* time for reass q to live */
|
||||||
u_int8_t ipq_p; /* protocol of this fragment */
|
u_int8_t ipq_p; /* protocol of this fragment */
|
||||||
u_int16_t ipq_id; /* sequence id for reassembly */
|
u_int16_t ipq_id; /* sequence id for reassembly */
|
||||||
ipasfragp_32 ipq_next,ipq_prev;
|
|
||||||
/* to ip headers of fragments */
|
|
||||||
struct in_addr ipq_src,ipq_dst;
|
struct in_addr ipq_src,ipq_dst;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ip header, when holding a fragment.
|
* Ip header, when holding a fragment.
|
||||||
*
|
*
|
||||||
* Note: ipf_next must be at same offset as ipq_next above
|
* Note: ipf_link must be at same offset as frag_link above
|
||||||
*/
|
*/
|
||||||
struct ipasfrag {
|
struct ipasfrag {
|
||||||
#ifdef WORDS_BIGENDIAN
|
struct qlink ipf_link;
|
||||||
u_int ip_v:4,
|
struct ip ipf_ip;
|
||||||
ip_hl:4;
|
|
||||||
#else
|
|
||||||
u_int ip_hl:4,
|
|
||||||
ip_v:4;
|
|
||||||
#endif
|
|
||||||
/* BUG : u_int changed to u_int8_t.
|
|
||||||
* sizeof(u_int)==4 on linux 2.0
|
|
||||||
*/
|
|
||||||
u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit
|
|
||||||
* to avoid destroying tos (PPPDTRuu);
|
|
||||||
* copied from (ip_off&IP_MF) */
|
|
||||||
u_int16_t ip_len;
|
|
||||||
u_int16_t ip_id;
|
|
||||||
u_int16_t ip_off;
|
|
||||||
u_int8_t ip_ttl;
|
|
||||||
u_int8_t ip_p;
|
|
||||||
u_int16_t ip_sum;
|
|
||||||
ipasfragp_32 ipf_next; /* next fragment */
|
|
||||||
ipasfragp_32 ipf_prev; /* previous fragment */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ipf_off ipf_ip.ip_off
|
||||||
|
#define ipf_tos ipf_ip.ip_tos
|
||||||
|
#define ipf_len ipf_ip.ip_len
|
||||||
|
#define ipf_next ipf_link.next
|
||||||
|
#define ipf_prev ipf_link.prev
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure stored in mbuf in inpcb.ip_options
|
* Structure stored in mbuf in inpcb.ip_options
|
||||||
* and passed to ip_output when ip options are in use.
|
* and passed to ip_output when ip options are in use.
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -43,7 +39,7 @@ struct icmpstat icmpstat;
|
||||||
|
|
||||||
/* The message sent when emulating PING */
|
/* The message sent when emulating PING */
|
||||||
/* Be nice and tell them it's just a pseudo-ping packet */
|
/* 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";
|
static 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 */
|
/* list of actions for icmp_error() on RX of an icmp message */
|
||||||
static const int icmp_flush[19] = {
|
static const int icmp_flush[19] = {
|
||||||
|
@ -207,12 +203,8 @@ end_error:
|
||||||
|
|
||||||
#define ICMP_MAXDATALEN (IP_MSS-28)
|
#define ICMP_MAXDATALEN (IP_MSS-28)
|
||||||
void
|
void
|
||||||
icmp_error(msrc, type, code, minsize, message)
|
icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
|
||||||
struct mbuf *msrc;
|
const char *message)
|
||||||
u_char type;
|
|
||||||
u_char code;
|
|
||||||
int minsize;
|
|
||||||
char *message;
|
|
||||||
{
|
{
|
||||||
unsigned hlen, shlen, s_ip_len;
|
unsigned hlen, shlen, s_ip_len;
|
||||||
register struct ip *ip;
|
register struct ip *ip;
|
||||||
|
@ -228,7 +220,7 @@ icmp_error(msrc, type, code, minsize, message)
|
||||||
/* check msrc */
|
/* check msrc */
|
||||||
if(!msrc) goto end_error;
|
if(!msrc) goto end_error;
|
||||||
ip = mtod(msrc, struct ip *);
|
ip = mtod(msrc, struct ip *);
|
||||||
#if DEBUG
|
#ifdef DEBUG
|
||||||
{ char bufa[20], bufb[20];
|
{ char bufa[20], bufb[20];
|
||||||
strcpy(bufa, inet_ntoa(ip->ip_src));
|
strcpy(bufa, inet_ntoa(ip->ip_src));
|
||||||
strcpy(bufb, inet_ntoa(ip->ip_dst));
|
strcpy(bufb, inet_ntoa(ip->ip_dst));
|
||||||
|
@ -285,7 +277,7 @@ icmp_error(msrc, type, code, minsize, message)
|
||||||
HTONS(icp->icmp_ip.ip_id);
|
HTONS(icp->icmp_ip.ip_id);
|
||||||
HTONS(icp->icmp_ip.ip_off);
|
HTONS(icp->icmp_ip.ip_off);
|
||||||
|
|
||||||
#if DEBUG
|
#ifdef DEBUG
|
||||||
if(message) { /* DEBUG : append message to ICMP packet */
|
if(message) { /* DEBUG : append message to ICMP packet */
|
||||||
int message_len;
|
int message_len;
|
||||||
char *cpnt;
|
char *cpnt;
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -158,7 +154,8 @@ struct icmp {
|
||||||
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
|
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
|
||||||
|
|
||||||
void icmp_input _P((struct mbuf *, int));
|
void icmp_input _P((struct mbuf *, int));
|
||||||
void icmp_error _P((struct mbuf *, u_char, u_char, int, char *));
|
void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
|
||||||
|
const char *message);
|
||||||
void icmp_reflect _P((struct mbuf *));
|
void icmp_reflect _P((struct mbuf *));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -43,6 +39,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <slirp.h>
|
#include <slirp.h>
|
||||||
|
#include <osdep.h>
|
||||||
#include "ip_icmp.h"
|
#include "ip_icmp.h"
|
||||||
|
|
||||||
#ifdef LOG_ENABLED
|
#ifdef LOG_ENABLED
|
||||||
|
@ -51,7 +48,7 @@ struct ipstat ipstat;
|
||||||
|
|
||||||
struct ipq ipq;
|
struct ipq ipq;
|
||||||
|
|
||||||
static struct ip *ip_reass(register struct ipasfrag *ip,
|
static struct ip *ip_reass(register struct ip *ip,
|
||||||
register struct ipq *fp);
|
register struct ipq *fp);
|
||||||
static void ip_freef(struct ipq *fp);
|
static void ip_freef(struct ipq *fp);
|
||||||
static void ip_enq(register struct ipasfrag *p,
|
static void ip_enq(register struct ipasfrag *p,
|
||||||
|
@ -65,7 +62,7 @@ static void ip_deq(register struct ipasfrag *p);
|
||||||
void
|
void
|
||||||
ip_init()
|
ip_init()
|
||||||
{
|
{
|
||||||
ipq.next = ipq.prev = (ipqp_32)&ipq;
|
ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
|
||||||
ip_id = tt.tv_sec & 0xffff;
|
ip_id = tt.tv_sec & 0xffff;
|
||||||
udp_init();
|
udp_init();
|
||||||
tcp_init();
|
tcp_init();
|
||||||
|
@ -136,6 +133,27 @@ ip_input(m)
|
||||||
STAT(ipstat.ips_tooshort++);
|
STAT(ipstat.ips_tooshort++);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (slirp_restrict) {
|
||||||
|
if (memcmp(&ip->ip_dst.s_addr, &special_addr, 3)) {
|
||||||
|
if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP)
|
||||||
|
goto bad;
|
||||||
|
} else {
|
||||||
|
int host = ntohl(ip->ip_dst.s_addr) & 0xff;
|
||||||
|
struct ex_list *ex_ptr;
|
||||||
|
|
||||||
|
if (host == 0xff)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
|
||||||
|
if (ex_ptr->ex_addr == host)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ex_ptr)
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Should drop packet if mbuf too long? hmmm... */
|
/* Should drop packet if mbuf too long? hmmm... */
|
||||||
if (m->m_len > ip->ip_len)
|
if (m->m_len > ip->ip_len)
|
||||||
m_adj(m, ip->ip_len - m->m_len);
|
m_adj(m, ip->ip_len - m->m_len);
|
||||||
|
@ -167,18 +185,20 @@ ip_input(m)
|
||||||
*/
|
*/
|
||||||
if (ip->ip_off &~ IP_DF) {
|
if (ip->ip_off &~ IP_DF) {
|
||||||
register struct ipq *fp;
|
register struct ipq *fp;
|
||||||
|
struct qlink *l;
|
||||||
/*
|
/*
|
||||||
* Look for queue of fragments
|
* Look for queue of fragments
|
||||||
* of this datagram.
|
* of this datagram.
|
||||||
*/
|
*/
|
||||||
for (fp = (struct ipq *) ipq.next; fp != &ipq;
|
for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
|
||||||
fp = (struct ipq *) fp->next)
|
fp = container_of(l, struct ipq, ip_link);
|
||||||
if (ip->ip_id == fp->ipq_id &&
|
if (ip->ip_id == fp->ipq_id &&
|
||||||
ip->ip_src.s_addr == fp->ipq_src.s_addr &&
|
ip->ip_src.s_addr == fp->ipq_src.s_addr &&
|
||||||
ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
|
ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
|
||||||
ip->ip_p == fp->ipq_p)
|
ip->ip_p == fp->ipq_p)
|
||||||
goto found;
|
goto found;
|
||||||
fp = 0;
|
}
|
||||||
|
fp = NULL;
|
||||||
found:
|
found:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -188,9 +208,9 @@ ip_input(m)
|
||||||
*/
|
*/
|
||||||
ip->ip_len -= hlen;
|
ip->ip_len -= hlen;
|
||||||
if (ip->ip_off & IP_MF)
|
if (ip->ip_off & IP_MF)
|
||||||
((struct ipasfrag *)ip)->ipf_mff |= 1;
|
ip->ip_tos |= 1;
|
||||||
else
|
else
|
||||||
((struct ipasfrag *)ip)->ipf_mff &= ~1;
|
ip->ip_tos &= ~1;
|
||||||
|
|
||||||
ip->ip_off <<= 3;
|
ip->ip_off <<= 3;
|
||||||
|
|
||||||
|
@ -199,9 +219,9 @@ ip_input(m)
|
||||||
* or if this is not the first fragment,
|
* or if this is not the first fragment,
|
||||||
* attempt reassembly; if it succeeds, proceed.
|
* attempt reassembly; if it succeeds, proceed.
|
||||||
*/
|
*/
|
||||||
if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
|
if (ip->ip_tos & 1 || ip->ip_off) {
|
||||||
STAT(ipstat.ips_fragments++);
|
STAT(ipstat.ips_fragments++);
|
||||||
ip = ip_reass((struct ipasfrag *)ip, fp);
|
ip = ip_reass(ip, fp);
|
||||||
if (ip == 0)
|
if (ip == 0)
|
||||||
return;
|
return;
|
||||||
STAT(ipstat.ips_reassembled++);
|
STAT(ipstat.ips_reassembled++);
|
||||||
|
@ -237,6 +257,8 @@ bad:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink)))
|
||||||
|
#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink)))
|
||||||
/*
|
/*
|
||||||
* Take incoming datagram fragment and try to
|
* Take incoming datagram fragment and try to
|
||||||
* reassemble it into whole datagram. If a chain for
|
* reassemble it into whole datagram. If a chain for
|
||||||
|
@ -244,7 +266,7 @@ bad:
|
||||||
* is given as fp; otherwise have to make a chain.
|
* is given as fp; otherwise have to make a chain.
|
||||||
*/
|
*/
|
||||||
static struct ip *
|
static struct ip *
|
||||||
ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
|
ip_reass(register struct ip *ip, register struct ipq *fp)
|
||||||
{
|
{
|
||||||
register struct mbuf *m = dtom(ip);
|
register struct mbuf *m = dtom(ip);
|
||||||
register struct ipasfrag *q;
|
register struct ipasfrag *q;
|
||||||
|
@ -271,13 +293,13 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
|
||||||
struct mbuf *t;
|
struct mbuf *t;
|
||||||
if ((t = m_get()) == NULL) goto dropfrag;
|
if ((t = m_get()) == NULL) goto dropfrag;
|
||||||
fp = mtod(t, struct ipq *);
|
fp = mtod(t, struct ipq *);
|
||||||
insque_32(fp, &ipq);
|
insque(&fp->ip_link, &ipq.ip_link);
|
||||||
fp->ipq_ttl = IPFRAGTTL;
|
fp->ipq_ttl = IPFRAGTTL;
|
||||||
fp->ipq_p = ip->ip_p;
|
fp->ipq_p = ip->ip_p;
|
||||||
fp->ipq_id = ip->ip_id;
|
fp->ipq_id = ip->ip_id;
|
||||||
fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;
|
fp->frag_link.next = fp->frag_link.prev = &fp->frag_link;
|
||||||
fp->ipq_src = ((struct ip *)ip)->ip_src;
|
fp->ipq_src = ip->ip_src;
|
||||||
fp->ipq_dst = ((struct ip *)ip)->ip_dst;
|
fp->ipq_dst = ip->ip_dst;
|
||||||
q = (struct ipasfrag *)fp;
|
q = (struct ipasfrag *)fp;
|
||||||
goto insert;
|
goto insert;
|
||||||
}
|
}
|
||||||
|
@ -285,9 +307,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
|
||||||
/*
|
/*
|
||||||
* Find a segment which begins after this one does.
|
* Find a segment which begins after this one does.
|
||||||
*/
|
*/
|
||||||
for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;
|
for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
|
||||||
q = (struct ipasfrag *)q->ipf_next)
|
q = q->ipf_next)
|
||||||
if (q->ip_off > ip->ip_off)
|
if (q->ipf_off > ip->ip_off)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -295,9 +317,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
|
||||||
* our data already. If so, drop the data from the incoming
|
* our data already. If so, drop the data from the incoming
|
||||||
* segment. If it provides all of our data, drop us.
|
* segment. If it provides all of our data, drop us.
|
||||||
*/
|
*/
|
||||||
if (q->ipf_prev != (ipasfragp_32)fp) {
|
if (q->ipf_prev != &fp->frag_link) {
|
||||||
i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +
|
struct ipasfrag *pq = q->ipf_prev;
|
||||||
((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off;
|
i = pq->ipf_off + pq->ipf_len - ip->ip_off;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (i >= ip->ip_len)
|
if (i >= ip->ip_len)
|
||||||
goto dropfrag;
|
goto dropfrag;
|
||||||
|
@ -311,17 +333,18 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
|
||||||
* While we overlap succeeding segments trim them or,
|
* While we overlap succeeding segments trim them or,
|
||||||
* if they are completely covered, dequeue them.
|
* if they are completely covered, dequeue them.
|
||||||
*/
|
*/
|
||||||
while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
|
while (q != (struct ipasfrag*)&fp->frag_link &&
|
||||||
i = (ip->ip_off + ip->ip_len) - q->ip_off;
|
ip->ip_off + ip->ip_len > q->ipf_off) {
|
||||||
if (i < q->ip_len) {
|
i = (ip->ip_off + ip->ip_len) - q->ipf_off;
|
||||||
q->ip_len -= i;
|
if (i < q->ipf_len) {
|
||||||
q->ip_off += i;
|
q->ipf_len -= i;
|
||||||
|
q->ipf_off += i;
|
||||||
m_adj(dtom(q), i);
|
m_adj(dtom(q), i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
q = (struct ipasfrag *) q->ipf_next;
|
q = q->ipf_next;
|
||||||
m_freem(dtom((struct ipasfrag *) q->ipf_prev));
|
m_freem(dtom(q->ipf_prev));
|
||||||
ip_deq((struct ipasfrag *) q->ipf_prev);
|
ip_deq(q->ipf_prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert:
|
insert:
|
||||||
|
@ -329,27 +352,26 @@ insert:
|
||||||
* Stick new segment in its place;
|
* Stick new segment in its place;
|
||||||
* check for complete reassembly.
|
* check for complete reassembly.
|
||||||
*/
|
*/
|
||||||
ip_enq(ip, (struct ipasfrag *) q->ipf_prev);
|
ip_enq(iptofrag(ip), q->ipf_prev);
|
||||||
next = 0;
|
next = 0;
|
||||||
for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
|
for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link;
|
||||||
q = (struct ipasfrag *) q->ipf_next) {
|
q = q->ipf_next) {
|
||||||
if (q->ip_off != next)
|
if (q->ipf_off != next)
|
||||||
return (0);
|
return (0);
|
||||||
next += q->ip_len;
|
next += q->ipf_len;
|
||||||
}
|
}
|
||||||
if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1)
|
if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reassembly is complete; concatenate fragments.
|
* Reassembly is complete; concatenate fragments.
|
||||||
*/
|
*/
|
||||||
q = (struct ipasfrag *) fp->ipq_next;
|
q = fp->frag_link.next;
|
||||||
m = dtom(q);
|
m = dtom(q);
|
||||||
|
|
||||||
q = (struct ipasfrag *) q->ipf_next;
|
q = (struct ipasfrag *) q->ipf_next;
|
||||||
while (q != (struct ipasfrag *)fp) {
|
while (q != (struct ipasfrag*)&fp->frag_link) {
|
||||||
struct mbuf *t;
|
struct mbuf *t = dtom(q);
|
||||||
t = dtom(q);
|
|
||||||
q = (struct ipasfrag *) q->ipf_next;
|
q = (struct ipasfrag *) q->ipf_next;
|
||||||
m_cat(m, t);
|
m_cat(m, t);
|
||||||
}
|
}
|
||||||
|
@ -360,7 +382,7 @@ insert:
|
||||||
* dequeue and discard fragment reassembly header.
|
* dequeue and discard fragment reassembly header.
|
||||||
* Make header visible.
|
* Make header visible.
|
||||||
*/
|
*/
|
||||||
ip = (struct ipasfrag *) fp->ipq_next;
|
q = fp->frag_link.next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the fragments concatenated to an mbuf that's
|
* If the fragments concatenated to an mbuf that's
|
||||||
|
@ -370,25 +392,24 @@ insert:
|
||||||
* into the new buffer.
|
* into the new buffer.
|
||||||
*/
|
*/
|
||||||
if (m->m_flags & M_EXT) {
|
if (m->m_flags & M_EXT) {
|
||||||
int delta;
|
int delta = (char *)q - m->m_dat;
|
||||||
delta = (char *)ip - m->m_dat;
|
q = (struct ipasfrag *)(m->m_ext + delta);
|
||||||
ip = (struct ipasfrag *)(m->m_ext + delta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DEBUG_ARG("ip = %lx", (long)ip);
|
/* DEBUG_ARG("ip = %lx", (long)ip);
|
||||||
* ip=(struct ipasfrag *)m->m_data; */
|
* ip=(struct ipasfrag *)m->m_data; */
|
||||||
|
|
||||||
|
ip = fragtoip(q);
|
||||||
ip->ip_len = next;
|
ip->ip_len = next;
|
||||||
ip->ipf_mff &= ~1;
|
ip->ip_tos &= ~1;
|
||||||
((struct ip *)ip)->ip_src = fp->ipq_src;
|
ip->ip_src = fp->ipq_src;
|
||||||
((struct ip *)ip)->ip_dst = fp->ipq_dst;
|
ip->ip_dst = fp->ipq_dst;
|
||||||
remque_32(fp);
|
remque(&fp->ip_link);
|
||||||
(void) m_free(dtom(fp));
|
(void) m_free(dtom(fp));
|
||||||
m = dtom(ip);
|
|
||||||
m->m_len += (ip->ip_hl << 2);
|
m->m_len += (ip->ip_hl << 2);
|
||||||
m->m_data -= (ip->ip_hl << 2);
|
m->m_data -= (ip->ip_hl << 2);
|
||||||
|
|
||||||
return ((struct ip *)ip);
|
return ip;
|
||||||
|
|
||||||
dropfrag:
|
dropfrag:
|
||||||
STAT(ipstat.ips_fragdropped++);
|
STAT(ipstat.ips_fragdropped++);
|
||||||
|
@ -405,13 +426,12 @@ ip_freef(struct ipq *fp)
|
||||||
{
|
{
|
||||||
register struct ipasfrag *q, *p;
|
register struct ipasfrag *q, *p;
|
||||||
|
|
||||||
for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
|
for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
|
||||||
q = p) {
|
p = q->ipf_next;
|
||||||
p = (struct ipasfrag *) q->ipf_next;
|
|
||||||
ip_deq(q);
|
ip_deq(q);
|
||||||
m_freem(dtom(q));
|
m_freem(dtom(q));
|
||||||
}
|
}
|
||||||
remque_32(fp);
|
remque(&fp->ip_link);
|
||||||
(void) m_free(dtom(fp));
|
(void) m_free(dtom(fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,10 +444,10 @@ ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev)
|
||||||
{
|
{
|
||||||
DEBUG_CALL("ip_enq");
|
DEBUG_CALL("ip_enq");
|
||||||
DEBUG_ARG("prev = %lx", (long)prev);
|
DEBUG_ARG("prev = %lx", (long)prev);
|
||||||
p->ipf_prev = (ipasfragp_32) prev;
|
p->ipf_prev = prev;
|
||||||
p->ipf_next = prev->ipf_next;
|
p->ipf_next = prev->ipf_next;
|
||||||
((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p;
|
((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p;
|
||||||
prev->ipf_next = (ipasfragp_32) p;
|
prev->ipf_next = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -448,20 +468,21 @@ ip_deq(register struct ipasfrag *p)
|
||||||
void
|
void
|
||||||
ip_slowtimo()
|
ip_slowtimo()
|
||||||
{
|
{
|
||||||
register struct ipq *fp;
|
struct qlink *l;
|
||||||
|
|
||||||
DEBUG_CALL("ip_slowtimo");
|
DEBUG_CALL("ip_slowtimo");
|
||||||
|
|
||||||
fp = (struct ipq *) ipq.next;
|
l = ipq.ip_link.next;
|
||||||
if (fp == 0)
|
|
||||||
|
if (l == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (fp != &ipq) {
|
while (l != &ipq.ip_link) {
|
||||||
--fp->ipq_ttl;
|
struct ipq *fp = container_of(l, struct ipq, ip_link);
|
||||||
fp = (struct ipq *) fp->next;
|
l = l->next;
|
||||||
if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
|
if (--fp->ipq_ttl == 0) {
|
||||||
STAT(ipstat.ips_fragtimeout++);
|
STAT(ipstat.ips_fragtimeout++);
|
||||||
ip_freef((struct ipq *) fp->prev);
|
ip_freef(fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void slirp_init(void);
|
void slirp_init(int restrict, char *special_ip);
|
||||||
|
|
||||||
void slirp_select_fill(int *pnfds,
|
void slirp_select_fill(int *pnfds,
|
||||||
fd_set *readfds, fd_set *writefds, fd_set *xfds);
|
fd_set *readfds, fd_set *writefds, fd_set *xfds);
|
||||||
|
@ -20,13 +20,16 @@ void slirp_output(const uint8_t *pkt, int pkt_len);
|
||||||
|
|
||||||
int slirp_redir(int is_udp, int host_port,
|
int slirp_redir(int is_udp, int host_port,
|
||||||
struct in_addr guest_addr, int guest_port);
|
struct in_addr guest_addr, int guest_port);
|
||||||
int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
|
int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
|
||||||
int guest_port);
|
int guest_port);
|
||||||
|
|
||||||
extern const char *tftp_prefix;
|
extern const char *tftp_prefix;
|
||||||
extern char slirp_hostname[33];
|
extern char slirp_hostname[33];
|
||||||
|
|
||||||
void slirp_stats(void);
|
void slirp_stats(void);
|
||||||
|
void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
|
||||||
|
int size);
|
||||||
|
size_t slirp_socket_can_recv(int addr_low_byte, int guest_port);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ extern int towrite_max;
|
||||||
extern int ppp_exit;
|
extern int ppp_exit;
|
||||||
extern int tcp_keepintvl;
|
extern int tcp_keepintvl;
|
||||||
extern uint8_t client_ethaddr[6];
|
extern uint8_t client_ethaddr[6];
|
||||||
|
extern const char *slirp_special_ip;
|
||||||
|
extern int slirp_restrict;
|
||||||
|
|
||||||
#define PROTO_SLIP 0x1
|
#define PROTO_SLIP 0x1
|
||||||
#ifdef USE_PPP
|
#ifdef USE_PPP
|
||||||
|
@ -51,3 +53,4 @@ extern uint8_t client_ethaddr[6];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void if_encap(const uint8_t *ip_data, int ip_data_len);
|
void if_encap(const uint8_t *ip_data, int ip_data_len);
|
||||||
|
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
#include <slirp.h>
|
#include <slirp.h>
|
||||||
|
|
||||||
struct mbuf *mbutl;
|
|
||||||
char *mclrefcnt;
|
|
||||||
int mbuf_alloced = 0;
|
int mbuf_alloced = 0;
|
||||||
struct mbuf m_freelist, m_usedlist;
|
struct mbuf m_freelist, m_usedlist;
|
||||||
#define MBUF_THRESH 30
|
#define MBUF_THRESH 30
|
||||||
|
@ -28,7 +26,7 @@ int mbuf_max = 0;
|
||||||
* Find a nice value for msize
|
* Find a nice value for msize
|
||||||
* XXX if_maxlinkhdr already in mtu
|
* XXX if_maxlinkhdr already in mtu
|
||||||
*/
|
*/
|
||||||
#define MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
|
#define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6)
|
||||||
|
|
||||||
void
|
void
|
||||||
m_init()
|
m_init()
|
||||||
|
@ -54,7 +52,7 @@ m_get()
|
||||||
DEBUG_CALL("m_get");
|
DEBUG_CALL("m_get");
|
||||||
|
|
||||||
if (m_freelist.m_next == &m_freelist) {
|
if (m_freelist.m_next == &m_freelist) {
|
||||||
m = (struct mbuf *)malloc(MSIZE);
|
m = (struct mbuf *)malloc(SLIRP_MSIZE);
|
||||||
if (m == NULL) goto end_error;
|
if (m == NULL) goto end_error;
|
||||||
mbuf_alloced++;
|
mbuf_alloced++;
|
||||||
if (mbuf_alloced > MBUF_THRESH)
|
if (mbuf_alloced > MBUF_THRESH)
|
||||||
|
@ -71,7 +69,7 @@ m_get()
|
||||||
m->m_flags = (flags | M_USEDLIST);
|
m->m_flags = (flags | M_USEDLIST);
|
||||||
|
|
||||||
/* Initialise it */
|
/* Initialise it */
|
||||||
m->m_size = MSIZE - sizeof(struct m_hdr);
|
m->m_size = SLIRP_MSIZE - sizeof(struct m_hdr);
|
||||||
m->m_data = m->m_dat;
|
m->m_data = m->m_dat;
|
||||||
m->m_len = 0;
|
m->m_len = 0;
|
||||||
m->m_nextpkt = 0;
|
m->m_nextpkt = 0;
|
||||||
|
@ -236,4 +234,3 @@ dtom(dat)
|
||||||
|
|
||||||
return (struct mbuf *)0;
|
return (struct mbuf *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -66,20 +66,6 @@ redir_x(inaddr, start_port, display, screen)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_INET_ATON
|
|
||||||
int
|
|
||||||
inet_aton(cp, ia)
|
|
||||||
const char *cp;
|
|
||||||
struct in_addr *ia;
|
|
||||||
{
|
|
||||||
u_int32_t addr = inet_addr(cp);
|
|
||||||
if (addr == 0xffffffff)
|
|
||||||
return 0;
|
|
||||||
ia->s_addr = addr;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get our IP address and put it in our_addr
|
* Get our IP address and put it in our_addr
|
||||||
*/
|
*/
|
||||||
|
@ -97,39 +83,6 @@ getouraddr()
|
||||||
our_addr.s_addr = loopback_addr.s_addr;
|
our_addr.s_addr = loopback_addr.s_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIZEOF_CHAR_P == 8
|
|
||||||
|
|
||||||
struct quehead_32 {
|
|
||||||
u_int32_t qh_link;
|
|
||||||
u_int32_t qh_rlink;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void
|
|
||||||
insque_32(a, b)
|
|
||||||
void *a;
|
|
||||||
void *b;
|
|
||||||
{
|
|
||||||
register struct quehead_32 *element = (struct quehead_32 *) a;
|
|
||||||
register struct quehead_32 *head = (struct quehead_32 *) b;
|
|
||||||
element->qh_link = head->qh_link;
|
|
||||||
head->qh_link = (u_int32_t)element;
|
|
||||||
element->qh_rlink = (u_int32_t)head;
|
|
||||||
((struct quehead_32 *)(element->qh_link))->qh_rlink
|
|
||||||
= (u_int32_t)element;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
remque_32(a)
|
|
||||||
void *a;
|
|
||||||
{
|
|
||||||
register struct quehead_32 *element = (struct quehead_32 *) a;
|
|
||||||
((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
|
|
||||||
((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;
|
|
||||||
element->qh_rlink = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SIZEOF_CHAR_P == 8 */
|
|
||||||
|
|
||||||
struct quehead {
|
struct quehead {
|
||||||
struct quehead *qh_link;
|
struct quehead *qh_link;
|
||||||
struct quehead *qh_rlink;
|
struct quehead *qh_rlink;
|
||||||
|
@ -183,7 +136,7 @@ add_exec(ex_ptr, do_pty, exec, addr, port)
|
||||||
(*ex_ptr)->ex_fport = port;
|
(*ex_ptr)->ex_fport = port;
|
||||||
(*ex_ptr)->ex_addr = addr;
|
(*ex_ptr)->ex_addr = addr;
|
||||||
(*ex_ptr)->ex_pty = do_pty;
|
(*ex_ptr)->ex_pty = do_pty;
|
||||||
(*ex_ptr)->ex_exec = strdup(exec);
|
(*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
|
||||||
(*ex_ptr)->ex_next = tmp_ptr;
|
(*ex_ptr)->ex_next = tmp_ptr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -304,10 +257,10 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int addrlen = sizeof(addr);
|
socklen_t addrlen = sizeof(addr);
|
||||||
int opt;
|
int opt;
|
||||||
int master = -1;
|
int master = -1;
|
||||||
char *argv[256];
|
const char *argv[256];
|
||||||
#if 0
|
#if 0
|
||||||
char buff[256];
|
char buff[256];
|
||||||
#endif
|
#endif
|
||||||
|
@ -411,14 +364,15 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
|
||||||
} while (c);
|
} while (c);
|
||||||
|
|
||||||
argv[i] = 0;
|
argv[i] = 0;
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], (char **)argv);
|
||||||
|
|
||||||
/* Ooops, failed, let's tell the user why */
|
/* Ooops, failed, let's tell the user why */
|
||||||
{
|
{
|
||||||
char buff[256];
|
char buff[256];
|
||||||
|
|
||||||
sprintf(buff, "Error: execvp of %s failed: %s\n",
|
snprintf(buff, sizeof(buff),
|
||||||
argv[0], strerror(errno));
|
"Error: execvp of %s failed: %s\n",
|
||||||
|
argv[0], strerror(errno));
|
||||||
write(2, buff, strlen(buff)+1);
|
write(2, buff, strlen(buff)+1);
|
||||||
}
|
}
|
||||||
close(0); close(1); close(2); /* XXX */
|
close(0); close(1); close(2); /* XXX */
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct ex_list {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct ex_list *exec_list;
|
extern struct ex_list *exec_list;
|
||||||
extern u_int curtime, time_fasttimo, last_slowtimo;
|
extern u_int time_fasttimo, last_slowtimo;
|
||||||
|
|
||||||
extern int (*lprint_print) _P((void *, const char *, va_list));
|
extern int (*lprint_print) _P((void *, const char *, va_list));
|
||||||
extern char *lprint_ptr, *lprint_ptr2, **lprint_arg;
|
extern char *lprint_ptr, *lprint_ptr2, **lprint_arg;
|
||||||
|
@ -72,8 +72,8 @@ extern int x_port, x_server, x_display;
|
||||||
int show_x _P((char *, struct socket *));
|
int show_x _P((char *, struct socket *));
|
||||||
void redir_x _P((u_int32_t, int, int, int));
|
void redir_x _P((u_int32_t, int, int, int));
|
||||||
void getouraddr _P((void));
|
void getouraddr _P((void));
|
||||||
inline void slirp_insque _P((void *, void *));
|
void slirp_insque _P((void *, void *));
|
||||||
inline void slirp_remque _P((void *));
|
void slirp_remque _P((void *));
|
||||||
int add_exec _P((struct ex_list **, int, char *, int, int));
|
int add_exec _P((struct ex_list **, int, char *, int, int));
|
||||||
int slirp_openpty _P((int *, int *));
|
int slirp_openpty _P((int *, int *));
|
||||||
int fork_exec(struct socket *so, const char *ex, int do_pty);
|
int fork_exec(struct socket *so, const char *ex, int do_pty);
|
||||||
|
|
|
@ -108,7 +108,7 @@ sbappend(so, m)
|
||||||
* ottherwise it'll arrive out of order, and hence corrupt
|
* ottherwise it'll arrive out of order, and hence corrupt
|
||||||
*/
|
*/
|
||||||
if (!so->so_rcv.sb_cc)
|
if (!so->so_rcv.sb_cc)
|
||||||
ret = send(so->s, m->m_data, m->m_len, 0);
|
ret = slirp_send(so, m->m_data, m->m_len, 0);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
/*
|
/*
|
||||||
|
@ -198,4 +198,3 @@ sbcopy(sb, off, len, to)
|
||||||
memcpy(to+off,sb->sb_data,len);
|
memcpy(to+off,sb->sb_data,len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,30 @@
|
||||||
|
/*
|
||||||
|
* libslirp glue
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004-2008 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "qemu-common.h"
|
||||||
|
#include "qemu-char.h"
|
||||||
#include "slirp.h"
|
#include "slirp.h"
|
||||||
|
#include "hw/hw.h"
|
||||||
|
|
||||||
/* host address */
|
/* host address */
|
||||||
struct in_addr our_addr;
|
struct in_addr our_addr;
|
||||||
|
@ -16,8 +42,14 @@ static const uint8_t special_ethaddr[6] = {
|
||||||
0x52, 0x54, 0x00, 0x12, 0x35, 0x00
|
0x52, 0x54, 0x00, 0x12, 0x35, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ARP cache for the guest IP addresses (XXX: allow many entries) */
|
||||||
uint8_t client_ethaddr[6];
|
uint8_t client_ethaddr[6];
|
||||||
|
static struct in_addr client_ipaddr;
|
||||||
|
|
||||||
|
static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
const char *slirp_special_ip = CTL_SPECIAL;
|
||||||
|
int slirp_restrict;
|
||||||
int do_slowtimo;
|
int do_slowtimo;
|
||||||
int link_up;
|
int link_up;
|
||||||
struct timeval tt;
|
struct timeval tt;
|
||||||
|
@ -84,7 +116,7 @@ static int get_dns_addr(struct in_addr *pdns_addr)
|
||||||
static int get_dns_addr(struct in_addr *pdns_addr)
|
static int get_dns_addr(struct in_addr *pdns_addr)
|
||||||
{
|
{
|
||||||
char buff[512];
|
char buff[512];
|
||||||
char buff2[256];
|
char buff2[257];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
struct in_addr tmp_addr;
|
struct in_addr tmp_addr;
|
||||||
|
@ -136,7 +168,10 @@ static void slirp_cleanup(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void slirp_init(void)
|
static void slirp_state_save(QEMUFile *f, void *opaque);
|
||||||
|
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
|
||||||
|
|
||||||
|
void slirp_init(int restrict, char *special_ip)
|
||||||
{
|
{
|
||||||
// debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
|
// debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
|
||||||
|
|
||||||
|
@ -149,6 +184,7 @@ void slirp_init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
link_up = 1;
|
link_up = 1;
|
||||||
|
slirp_restrict = restrict;
|
||||||
|
|
||||||
if_init();
|
if_init();
|
||||||
ip_init();
|
ip_init();
|
||||||
|
@ -164,9 +200,13 @@ void slirp_init(void)
|
||||||
fprintf (stderr, "Warning: No DNS servers found\n");
|
fprintf (stderr, "Warning: No DNS servers found\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
inet_aton(CTL_SPECIAL, &special_addr);
|
if (special_ip)
|
||||||
|
slirp_special_ip = special_ip;
|
||||||
|
|
||||||
|
inet_aton(slirp_special_ip, &special_addr);
|
||||||
alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
|
alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
|
||||||
getouraddr();
|
getouraddr();
|
||||||
|
register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
|
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
|
||||||
|
@ -222,7 +262,7 @@ void slirp_select_fill(int *pnfds,
|
||||||
* in the fragment queue, or there are TCP connections active
|
* in the fragment queue, or there are TCP connections active
|
||||||
*/
|
*/
|
||||||
do_slowtimo = ((tcb.so_next != &tcb) ||
|
do_slowtimo = ((tcb.so_next != &tcb) ||
|
||||||
((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
|
(&ipq.ip_link != ipq.ip_link.next));
|
||||||
|
|
||||||
for (so = tcb.so_next; so != &tcb; so = so_next) {
|
for (so = tcb.so_next; so != &tcb; so = so_next) {
|
||||||
so_next = so->so_next;
|
so_next = so->so_next;
|
||||||
|
@ -554,7 +594,7 @@ struct arphdr
|
||||||
unsigned char ar_tip[4]; /* target IP address */
|
unsigned char ar_tip[4]; /* target IP address */
|
||||||
};
|
};
|
||||||
|
|
||||||
void arp_input(const uint8_t *pkt, int pkt_len)
|
static void arp_input(const uint8_t *pkt, int pkt_len)
|
||||||
{
|
{
|
||||||
struct ethhdr *eh = (struct ethhdr *)pkt;
|
struct ethhdr *eh = (struct ethhdr *)pkt;
|
||||||
struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
|
struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
|
||||||
|
@ -597,6 +637,13 @@ void arp_input(const uint8_t *pkt, int pkt_len)
|
||||||
slirp_output(arp_reply, sizeof(arp_reply));
|
slirp_output(arp_reply, sizeof(arp_reply));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ARPOP_REPLY:
|
||||||
|
/* reply to request of client mac address ? */
|
||||||
|
if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
|
||||||
|
!memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) {
|
||||||
|
memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -620,6 +667,9 @@ void slirp_input(const uint8_t *pkt, int pkt_len)
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
/* Note: we add to align the IP header */
|
/* Note: we add to align the IP header */
|
||||||
|
if (M_FREEROOM(m) < pkt_len + 2) {
|
||||||
|
m_inc(m, pkt_len + 2);
|
||||||
|
}
|
||||||
m->m_len = pkt_len + 2;
|
m->m_len = pkt_len + 2;
|
||||||
memcpy(m->m_data + 2, pkt, pkt_len);
|
memcpy(m->m_data + 2, pkt, pkt_len);
|
||||||
|
|
||||||
|
@ -641,14 +691,47 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
|
||||||
|
|
||||||
if (ip_data_len + ETH_HLEN > sizeof(buf))
|
if (ip_data_len + ETH_HLEN > sizeof(buf))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
|
||||||
|
uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
|
||||||
|
struct ethhdr *reh = (struct ethhdr *)arp_req;
|
||||||
|
struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
|
||||||
|
const struct ip *iph = (const struct ip *)ip_data;
|
||||||
|
|
||||||
memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
|
/* If the client addr is not known, there is no point in
|
||||||
memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
|
sending the packet to it. Normally the sender should have
|
||||||
/* XXX: not correct */
|
done an ARP request to get its MAC address. Here we do it
|
||||||
eh->h_source[5] = CTL_ALIAS;
|
in place of sending the packet and we hope that the sender
|
||||||
eh->h_proto = htons(ETH_P_IP);
|
will retry sending its packet. */
|
||||||
memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
|
memset(reh->h_dest, 0xff, ETH_ALEN);
|
||||||
slirp_output(buf, ip_data_len + ETH_HLEN);
|
memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
|
||||||
|
reh->h_source[5] = CTL_ALIAS;
|
||||||
|
reh->h_proto = htons(ETH_P_ARP);
|
||||||
|
rah->ar_hrd = htons(1);
|
||||||
|
rah->ar_pro = htons(ETH_P_IP);
|
||||||
|
rah->ar_hln = ETH_ALEN;
|
||||||
|
rah->ar_pln = 4;
|
||||||
|
rah->ar_op = htons(ARPOP_REQUEST);
|
||||||
|
/* source hw addr */
|
||||||
|
memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
|
||||||
|
rah->ar_sha[5] = CTL_ALIAS;
|
||||||
|
/* source IP */
|
||||||
|
memcpy(rah->ar_sip, &alias_addr, 4);
|
||||||
|
/* target hw addr (none) */
|
||||||
|
memset(rah->ar_tha, 0, ETH_ALEN);
|
||||||
|
/* target IP */
|
||||||
|
memcpy(rah->ar_tip, &iph->ip_dst, 4);
|
||||||
|
client_ipaddr = iph->ip_dst;
|
||||||
|
slirp_output(arp_req, sizeof(arp_req));
|
||||||
|
} else {
|
||||||
|
memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
|
||||||
|
memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
|
||||||
|
/* XXX: not correct */
|
||||||
|
eh->h_source[5] = CTL_ALIAS;
|
||||||
|
eh->h_proto = htons(ETH_P_IP);
|
||||||
|
memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
|
||||||
|
slirp_output(buf, ip_data_len + ETH_HLEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int slirp_redir(int is_udp, int host_port,
|
int slirp_redir(int is_udp, int host_port,
|
||||||
|
@ -666,9 +749,291 @@ int slirp_redir(int is_udp, int host_port,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
|
int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
|
||||||
int guest_port)
|
int guest_port)
|
||||||
{
|
{
|
||||||
return add_exec(&exec_list, do_pty, (char *)args,
|
return add_exec(&exec_list, do_pty, (char *)args,
|
||||||
addr_low_byte, htons(guest_port));
|
addr_low_byte, htons(guest_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
|
||||||
|
{
|
||||||
|
if (so->s == -1 && so->extra) {
|
||||||
|
qemu_chr_write(so->extra, buf, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return send(so->s, buf, len, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
|
||||||
|
{
|
||||||
|
struct socket *so;
|
||||||
|
|
||||||
|
for (so = tcb.so_next; so != &tcb; so = so->so_next) {
|
||||||
|
if ((so->so_faddr.s_addr & htonl(0xffffff00)) ==
|
||||||
|
special_addr.s_addr
|
||||||
|
&& (ntohl(so->so_faddr.s_addr) & 0xff) ==
|
||||||
|
addr_low_byte
|
||||||
|
&& htons(so->so_fport) == guest_port)
|
||||||
|
return so;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
struct socket *so;
|
||||||
|
|
||||||
|
if (!link_up)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
so = slirp_find_ctl_socket(addr_low_byte, guest_port);
|
||||||
|
|
||||||
|
if (!so || so->so_state & SS_NOFDREF)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return sopreprbuf(so, iov, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);
|
||||||
|
|
||||||
|
if (!so)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = soreadbuf(so, (const char *)buf, size);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
tcp_output(sototcpcb(so));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
qemu_put_sbe16(f, tp->t_state);
|
||||||
|
for (i = 0; i < TCPT_NTIMERS; i++)
|
||||||
|
qemu_put_sbe16(f, tp->t_timer[i]);
|
||||||
|
qemu_put_sbe16(f, tp->t_rxtshift);
|
||||||
|
qemu_put_sbe16(f, tp->t_rxtcur);
|
||||||
|
qemu_put_sbe16(f, tp->t_dupacks);
|
||||||
|
qemu_put_be16(f, tp->t_maxseg);
|
||||||
|
qemu_put_sbyte(f, tp->t_force);
|
||||||
|
qemu_put_be16(f, tp->t_flags);
|
||||||
|
qemu_put_be32(f, tp->snd_una);
|
||||||
|
qemu_put_be32(f, tp->snd_nxt);
|
||||||
|
qemu_put_be32(f, tp->snd_up);
|
||||||
|
qemu_put_be32(f, tp->snd_wl1);
|
||||||
|
qemu_put_be32(f, tp->snd_wl2);
|
||||||
|
qemu_put_be32(f, tp->iss);
|
||||||
|
qemu_put_be32(f, tp->snd_wnd);
|
||||||
|
qemu_put_be32(f, tp->rcv_wnd);
|
||||||
|
qemu_put_be32(f, tp->rcv_nxt);
|
||||||
|
qemu_put_be32(f, tp->rcv_up);
|
||||||
|
qemu_put_be32(f, tp->irs);
|
||||||
|
qemu_put_be32(f, tp->rcv_adv);
|
||||||
|
qemu_put_be32(f, tp->snd_max);
|
||||||
|
qemu_put_be32(f, tp->snd_cwnd);
|
||||||
|
qemu_put_be32(f, tp->snd_ssthresh);
|
||||||
|
qemu_put_sbe16(f, tp->t_idle);
|
||||||
|
qemu_put_sbe16(f, tp->t_rtt);
|
||||||
|
qemu_put_be32(f, tp->t_rtseq);
|
||||||
|
qemu_put_sbe16(f, tp->t_srtt);
|
||||||
|
qemu_put_sbe16(f, tp->t_rttvar);
|
||||||
|
qemu_put_be16(f, tp->t_rttmin);
|
||||||
|
qemu_put_be32(f, tp->max_sndwnd);
|
||||||
|
qemu_put_byte(f, tp->t_oobflags);
|
||||||
|
qemu_put_byte(f, tp->t_iobc);
|
||||||
|
qemu_put_sbe16(f, tp->t_softerror);
|
||||||
|
qemu_put_byte(f, tp->snd_scale);
|
||||||
|
qemu_put_byte(f, tp->rcv_scale);
|
||||||
|
qemu_put_byte(f, tp->request_r_scale);
|
||||||
|
qemu_put_byte(f, tp->requested_s_scale);
|
||||||
|
qemu_put_be32(f, tp->ts_recent);
|
||||||
|
qemu_put_be32(f, tp->ts_recent_age);
|
||||||
|
qemu_put_be32(f, tp->last_ack_sent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
|
||||||
|
{
|
||||||
|
uint32_t off;
|
||||||
|
|
||||||
|
qemu_put_be32(f, sbuf->sb_cc);
|
||||||
|
qemu_put_be32(f, sbuf->sb_datalen);
|
||||||
|
off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
|
||||||
|
qemu_put_sbe32(f, off);
|
||||||
|
off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
|
||||||
|
qemu_put_sbe32(f, off);
|
||||||
|
qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slirp_socket_save(QEMUFile *f, struct socket *so)
|
||||||
|
{
|
||||||
|
qemu_put_be32(f, so->so_urgc);
|
||||||
|
qemu_put_be32(f, so->so_faddr.s_addr);
|
||||||
|
qemu_put_be32(f, so->so_laddr.s_addr);
|
||||||
|
qemu_put_be16(f, so->so_fport);
|
||||||
|
qemu_put_be16(f, so->so_lport);
|
||||||
|
qemu_put_byte(f, so->so_iptos);
|
||||||
|
qemu_put_byte(f, so->so_emu);
|
||||||
|
qemu_put_byte(f, so->so_type);
|
||||||
|
qemu_put_be32(f, so->so_state);
|
||||||
|
slirp_sbuf_save(f, &so->so_rcv);
|
||||||
|
slirp_sbuf_save(f, &so->so_snd);
|
||||||
|
slirp_tcp_save(f, so->so_tcpcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slirp_state_save(QEMUFile *f, void *opaque)
|
||||||
|
{
|
||||||
|
struct ex_list *ex_ptr;
|
||||||
|
|
||||||
|
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
|
||||||
|
if (ex_ptr->ex_pty == 3) {
|
||||||
|
struct socket *so;
|
||||||
|
so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
|
||||||
|
if (!so)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
qemu_put_byte(f, 42);
|
||||||
|
slirp_socket_save(f, so);
|
||||||
|
}
|
||||||
|
qemu_put_byte(f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tp->t_state = qemu_get_sbe16(f);
|
||||||
|
for (i = 0; i < TCPT_NTIMERS; i++)
|
||||||
|
tp->t_timer[i] = qemu_get_sbe16(f);
|
||||||
|
tp->t_rxtshift = qemu_get_sbe16(f);
|
||||||
|
tp->t_rxtcur = qemu_get_sbe16(f);
|
||||||
|
tp->t_dupacks = qemu_get_sbe16(f);
|
||||||
|
tp->t_maxseg = qemu_get_be16(f);
|
||||||
|
tp->t_force = qemu_get_sbyte(f);
|
||||||
|
tp->t_flags = qemu_get_be16(f);
|
||||||
|
tp->snd_una = qemu_get_be32(f);
|
||||||
|
tp->snd_nxt = qemu_get_be32(f);
|
||||||
|
tp->snd_up = qemu_get_be32(f);
|
||||||
|
tp->snd_wl1 = qemu_get_be32(f);
|
||||||
|
tp->snd_wl2 = qemu_get_be32(f);
|
||||||
|
tp->iss = qemu_get_be32(f);
|
||||||
|
tp->snd_wnd = qemu_get_be32(f);
|
||||||
|
tp->rcv_wnd = qemu_get_be32(f);
|
||||||
|
tp->rcv_nxt = qemu_get_be32(f);
|
||||||
|
tp->rcv_up = qemu_get_be32(f);
|
||||||
|
tp->irs = qemu_get_be32(f);
|
||||||
|
tp->rcv_adv = qemu_get_be32(f);
|
||||||
|
tp->snd_max = qemu_get_be32(f);
|
||||||
|
tp->snd_cwnd = qemu_get_be32(f);
|
||||||
|
tp->snd_ssthresh = qemu_get_be32(f);
|
||||||
|
tp->t_idle = qemu_get_sbe16(f);
|
||||||
|
tp->t_rtt = qemu_get_sbe16(f);
|
||||||
|
tp->t_rtseq = qemu_get_be32(f);
|
||||||
|
tp->t_srtt = qemu_get_sbe16(f);
|
||||||
|
tp->t_rttvar = qemu_get_sbe16(f);
|
||||||
|
tp->t_rttmin = qemu_get_be16(f);
|
||||||
|
tp->max_sndwnd = qemu_get_be32(f);
|
||||||
|
tp->t_oobflags = qemu_get_byte(f);
|
||||||
|
tp->t_iobc = qemu_get_byte(f);
|
||||||
|
tp->t_softerror = qemu_get_sbe16(f);
|
||||||
|
tp->snd_scale = qemu_get_byte(f);
|
||||||
|
tp->rcv_scale = qemu_get_byte(f);
|
||||||
|
tp->request_r_scale = qemu_get_byte(f);
|
||||||
|
tp->requested_s_scale = qemu_get_byte(f);
|
||||||
|
tp->ts_recent = qemu_get_be32(f);
|
||||||
|
tp->ts_recent_age = qemu_get_be32(f);
|
||||||
|
tp->last_ack_sent = qemu_get_be32(f);
|
||||||
|
tcp_template(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
|
||||||
|
{
|
||||||
|
uint32_t off, sb_cc, sb_datalen;
|
||||||
|
|
||||||
|
sb_cc = qemu_get_be32(f);
|
||||||
|
sb_datalen = qemu_get_be32(f);
|
||||||
|
|
||||||
|
sbreserve(sbuf, sb_datalen);
|
||||||
|
|
||||||
|
if (sbuf->sb_datalen != sb_datalen)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
sbuf->sb_cc = sb_cc;
|
||||||
|
|
||||||
|
off = qemu_get_sbe32(f);
|
||||||
|
sbuf->sb_wptr = sbuf->sb_data + off;
|
||||||
|
off = qemu_get_sbe32(f);
|
||||||
|
sbuf->sb_rptr = sbuf->sb_data + off;
|
||||||
|
qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int slirp_socket_load(QEMUFile *f, struct socket *so)
|
||||||
|
{
|
||||||
|
if (tcp_attach(so) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
so->so_urgc = qemu_get_be32(f);
|
||||||
|
so->so_faddr.s_addr = qemu_get_be32(f);
|
||||||
|
so->so_laddr.s_addr = qemu_get_be32(f);
|
||||||
|
so->so_fport = qemu_get_be16(f);
|
||||||
|
so->so_lport = qemu_get_be16(f);
|
||||||
|
so->so_iptos = qemu_get_byte(f);
|
||||||
|
so->so_emu = qemu_get_byte(f);
|
||||||
|
so->so_type = qemu_get_byte(f);
|
||||||
|
so->so_state = qemu_get_be32(f);
|
||||||
|
if (slirp_sbuf_load(f, &so->so_rcv) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
if (slirp_sbuf_load(f, &so->so_snd) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
slirp_tcp_load(f, so->so_tcpcb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
|
{
|
||||||
|
struct ex_list *ex_ptr;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
while ((r = qemu_get_byte(f))) {
|
||||||
|
int ret;
|
||||||
|
struct socket *so = socreate();
|
||||||
|
|
||||||
|
if (!so)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = slirp_socket_load(f, so);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if ((so->so_faddr.s_addr & htonl(0xffffff00)) != special_addr.s_addr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
|
||||||
|
if (ex_ptr->ex_pty == 3 &&
|
||||||
|
(ntohl(so->so_faddr.s_addr) & 0xff) == ex_ptr->ex_addr &&
|
||||||
|
so->so_fport == ex_ptr->ex_fport)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ex_ptr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
so->extra = (void *)ex_ptr->ex_exec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef char *caddr_t;
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
|
# include <ws2tcpip.h>
|
||||||
# include <sys/timeb.h>
|
# include <sys/timeb.h>
|
||||||
# include <iphlpapi.h>
|
# include <iphlpapi.h>
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ typedef unsigned char u_int8_t;
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
#else
|
#else
|
||||||
# if HAVE_SYS_TIME_H
|
# ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# else
|
# else
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
|
@ -119,13 +120,12 @@ typedef unsigned char u_int8_t;
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _P
|
#undef _P
|
||||||
#ifndef NO_PROTOTYPES
|
#ifndef NO_PROTOTYPES
|
||||||
# define _P(x) x
|
# define _P(x) x
|
||||||
#else
|
#else
|
||||||
# define _P(x) ()
|
# define _P(x) ()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -265,14 +265,6 @@ void if_start _P((struct ttys *));
|
||||||
|
|
||||||
void lprint _P((const char *, ...));
|
void lprint _P((const char *, ...));
|
||||||
|
|
||||||
#if SIZEOF_CHAR_P == 4
|
|
||||||
# define insque_32 insque
|
|
||||||
# define remque_32 remque
|
|
||||||
#else
|
|
||||||
inline void insque_32 _P((void *, void *));
|
|
||||||
inline void remque_32 _P((void *));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -128,10 +128,10 @@
|
||||||
#undef HAVE_SYS_STROPTS_H
|
#undef HAVE_SYS_STROPTS_H
|
||||||
|
|
||||||
/* Define to whatever your compiler thinks inline should be */
|
/* Define to whatever your compiler thinks inline should be */
|
||||||
#define inline inline
|
//#define inline inline
|
||||||
|
|
||||||
/* Define to whatever your compiler thinks const should be */
|
/* Define to whatever your compiler thinks const should be */
|
||||||
#define const const
|
//#define const const
|
||||||
|
|
||||||
/* Define if your compiler doesn't like prototypes */
|
/* Define if your compiler doesn't like prototypes */
|
||||||
#undef NO_PROTOTYPES
|
#undef NO_PROTOTYPES
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
#undef HAVE_SETENV
|
#undef HAVE_SETENV
|
||||||
|
|
||||||
/* Define if you have index() */
|
/* Define if you have index() */
|
||||||
#undef HAVE_INDEX
|
#define HAVE_INDEX
|
||||||
|
|
||||||
/* Define if you have bcmp() */
|
/* Define if you have bcmp() */
|
||||||
#undef HAVE_BCMP
|
#undef HAVE_BCMP
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
#define HAVE_MEMMOVE
|
#define HAVE_MEMMOVE
|
||||||
|
|
||||||
/* Define if you have gethostid */
|
/* Define if you have gethostid */
|
||||||
#undef HAVE_GETHOSTID
|
#define HAVE_GETHOSTID
|
||||||
|
|
||||||
/* Define if you DON'T have unix-domain sockets */
|
/* Define if you DON'T have unix-domain sockets */
|
||||||
#undef NO_UNIX_SOCKETS
|
#undef NO_UNIX_SOCKETS
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
* terms and conditions of the copyright.
|
* terms and conditions of the copyright.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "qemu-common.h"
|
||||||
#define WANT_SYS_IOCTL_H
|
#define WANT_SYS_IOCTL_H
|
||||||
#include <slirp.h>
|
#include <slirp.h>
|
||||||
#include "ip_icmp.h"
|
#include "ip_icmp.h"
|
||||||
#include "main.h"
|
|
||||||
#ifdef __sun__
|
#ifdef __sun__
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,32 +91,24 @@ sofree(so)
|
||||||
free(so);
|
free(so);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
|
||||||
* Read from so's socket into sb_snd, updating all relevant sbuf fields
|
|
||||||
* NOTE: This will only be called if it is select()ed for reading, so
|
|
||||||
* a read() of 0 (or less) means it's disconnected
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
soread(so)
|
|
||||||
struct socket *so;
|
|
||||||
{
|
{
|
||||||
int n, nn, lss, total;
|
int n, lss, total;
|
||||||
struct sbuf *sb = &so->so_snd;
|
struct sbuf *sb = &so->so_snd;
|
||||||
int len = sb->sb_datalen - sb->sb_cc;
|
int len = sb->sb_datalen - sb->sb_cc;
|
||||||
struct iovec iov[2];
|
|
||||||
int mss = so->so_tcpcb->t_maxseg;
|
int mss = so->so_tcpcb->t_maxseg;
|
||||||
|
|
||||||
DEBUG_CALL("soread");
|
DEBUG_CALL("sopreprbuf");
|
||||||
DEBUG_ARG("so = %lx", (long )so);
|
DEBUG_ARG("so = %lx", (long )so);
|
||||||
|
|
||||||
/*
|
|
||||||
* No need to check if there's enough room to read.
|
|
||||||
* soread wouldn't have been called if there weren't
|
|
||||||
*/
|
|
||||||
|
|
||||||
len = sb->sb_datalen - sb->sb_cc;
|
len = sb->sb_datalen - sb->sb_cc;
|
||||||
|
|
||||||
|
if (len <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
iov[0].iov_base = sb->sb_wptr;
|
iov[0].iov_base = sb->sb_wptr;
|
||||||
|
iov[1].iov_base = NULL;
|
||||||
|
iov[1].iov_len = 0;
|
||||||
if (sb->sb_wptr < sb->sb_rptr) {
|
if (sb->sb_wptr < sb->sb_rptr) {
|
||||||
iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
|
iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
|
||||||
/* Should never succeed, but... */
|
/* Should never succeed, but... */
|
||||||
|
@ -154,6 +146,33 @@ soread(so)
|
||||||
n = 1;
|
n = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (np)
|
||||||
|
*np = n;
|
||||||
|
|
||||||
|
return iov[0].iov_len + (n - 1) * iov[1].iov_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read from so's socket into sb_snd, updating all relevant sbuf fields
|
||||||
|
* NOTE: This will only be called if it is select()ed for reading, so
|
||||||
|
* a read() of 0 (or less) means it's disconnected
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
soread(so)
|
||||||
|
struct socket *so;
|
||||||
|
{
|
||||||
|
int n, nn;
|
||||||
|
struct sbuf *sb = &so->so_snd;
|
||||||
|
struct iovec iov[2];
|
||||||
|
|
||||||
|
DEBUG_CALL("soread");
|
||||||
|
DEBUG_ARG("so = %lx", (long )so);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to check if there's enough room to read.
|
||||||
|
* soread wouldn't have been called if there weren't
|
||||||
|
*/
|
||||||
|
sopreprbuf(so, iov, &n);
|
||||||
|
|
||||||
#ifdef HAVE_READV
|
#ifdef HAVE_READV
|
||||||
nn = readv(so->s, (struct iovec *)iov, n);
|
nn = readv(so->s, (struct iovec *)iov, n);
|
||||||
|
@ -200,6 +219,48 @@ soread(so)
|
||||||
return nn;
|
return nn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int soreadbuf(struct socket *so, const char *buf, int size)
|
||||||
|
{
|
||||||
|
int n, nn, copy = size;
|
||||||
|
struct sbuf *sb = &so->so_snd;
|
||||||
|
struct iovec iov[2];
|
||||||
|
|
||||||
|
DEBUG_CALL("soreadbuf");
|
||||||
|
DEBUG_ARG("so = %lx", (long )so);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to check if there's enough room to read.
|
||||||
|
* soread wouldn't have been called if there weren't
|
||||||
|
*/
|
||||||
|
if (sopreprbuf(so, iov, &n) < size)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
nn = MIN(iov[0].iov_len, copy);
|
||||||
|
memcpy(iov[0].iov_base, buf, nn);
|
||||||
|
|
||||||
|
copy -= nn;
|
||||||
|
buf += nn;
|
||||||
|
|
||||||
|
if (copy == 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
memcpy(iov[1].iov_base, buf, copy);
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Update fields */
|
||||||
|
sb->sb_cc += size;
|
||||||
|
sb->sb_wptr += size;
|
||||||
|
if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
|
||||||
|
sb->sb_wptr -= sb->sb_datalen;
|
||||||
|
return size;
|
||||||
|
err:
|
||||||
|
|
||||||
|
sofcantrcvmore(so);
|
||||||
|
tcp_sockclosed(sototcpcb(so));
|
||||||
|
fprintf(stderr, "soreadbuf buffer to small");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get urgent data
|
* Get urgent data
|
||||||
*
|
*
|
||||||
|
@ -253,7 +314,7 @@ sosendoob(so)
|
||||||
|
|
||||||
if (sb->sb_rptr < sb->sb_wptr) {
|
if (sb->sb_rptr < sb->sb_wptr) {
|
||||||
/* We can send it directly */
|
/* We can send it directly */
|
||||||
n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
|
n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
|
||||||
so->so_urgc -= n;
|
so->so_urgc -= n;
|
||||||
|
|
||||||
DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
|
DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
|
||||||
|
@ -274,7 +335,7 @@ sosendoob(so)
|
||||||
so->so_urgc -= n;
|
so->so_urgc -= n;
|
||||||
len += n;
|
len += n;
|
||||||
}
|
}
|
||||||
n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
|
n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (n != len)
|
if (n != len)
|
||||||
DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
|
DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
|
||||||
|
@ -320,6 +381,8 @@ sowrite(so)
|
||||||
len = sb->sb_cc;
|
len = sb->sb_cc;
|
||||||
|
|
||||||
iov[0].iov_base = sb->sb_rptr;
|
iov[0].iov_base = sb->sb_rptr;
|
||||||
|
iov[1].iov_base = NULL;
|
||||||
|
iov[1].iov_len = 0;
|
||||||
if (sb->sb_rptr < sb->sb_wptr) {
|
if (sb->sb_rptr < sb->sb_wptr) {
|
||||||
iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
|
iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
|
||||||
/* Should never succeed, but... */
|
/* Should never succeed, but... */
|
||||||
|
@ -344,7 +407,7 @@ sowrite(so)
|
||||||
|
|
||||||
DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
|
DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
|
||||||
#else
|
#else
|
||||||
nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
|
nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
|
||||||
#endif
|
#endif
|
||||||
/* This should never happen, but people tell me it does *shrug* */
|
/* This should never happen, but people tell me it does *shrug* */
|
||||||
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
|
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
|
||||||
|
@ -361,7 +424,7 @@ sowrite(so)
|
||||||
#ifndef HAVE_READV
|
#ifndef HAVE_READV
|
||||||
if (n == 2 && nn == iov[0].iov_len) {
|
if (n == 2 && nn == iov[0].iov_len) {
|
||||||
int ret;
|
int ret;
|
||||||
ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
|
ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
nn += ret;
|
nn += ret;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +455,7 @@ sorecvfrom(so)
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int addrlen = sizeof(struct sockaddr_in);
|
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
DEBUG_CALL("sorecvfrom");
|
DEBUG_CALL("sorecvfrom");
|
||||||
DEBUG_ARG("so = %lx", (long)so);
|
DEBUG_ARG("so = %lx", (long)so);
|
||||||
|
@ -545,7 +608,8 @@ solisten(port, laddr, lport, flags)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
int s, addrlen = sizeof(addr), opt = 1;
|
int s, opt = 1;
|
||||||
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
|
||||||
DEBUG_CALL("solisten");
|
DEBUG_CALL("solisten");
|
||||||
DEBUG_ARG("port = %d", port);
|
DEBUG_ARG("port = %d", port);
|
||||||
|
@ -718,4 +782,3 @@ sofwdrain(so)
|
||||||
else
|
else
|
||||||
sofcantsendmore(so);
|
sofcantsendmore(so);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,14 +73,6 @@ struct socket {
|
||||||
|
|
||||||
extern struct socket tcb;
|
extern struct socket tcb;
|
||||||
|
|
||||||
|
|
||||||
#if defined(DECLARE_IOVEC) && !defined(HAVE_READV)
|
|
||||||
struct iovec {
|
|
||||||
char *iov_base;
|
|
||||||
size_t iov_len;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int));
|
struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int));
|
||||||
struct socket * socreate _P((void));
|
struct socket * socreate _P((void));
|
||||||
void sofree _P((struct socket *));
|
void sofree _P((struct socket *));
|
||||||
|
@ -95,5 +87,7 @@ void soisfconnecting _P((register struct socket *));
|
||||||
void soisfconnected _P((register struct socket *));
|
void soisfconnected _P((register struct socket *));
|
||||||
void soisfdisconnected _P((struct socket *));
|
void soisfdisconnected _P((struct socket *));
|
||||||
void sofwdrain _P((struct socket *));
|
void sofwdrain _P((struct socket *));
|
||||||
|
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np);
|
||||||
|
int soreadbuf(struct socket *so, const char *buf, int size);
|
||||||
|
|
||||||
#endif /* _SOCKET_H_ */
|
#endif /* _SOCKET_H_ */
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -71,7 +67,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
|
||||||
#ifdef TCP_ACK_HACK
|
#ifdef TCP_ACK_HACK
|
||||||
#define TCP_REASS(tp, ti, m, so, flags) {\
|
#define TCP_REASS(tp, ti, m, so, flags) {\
|
||||||
if ((ti)->ti_seq == (tp)->rcv_nxt && \
|
if ((ti)->ti_seq == (tp)->rcv_nxt && \
|
||||||
(tp)->seg_next == (tcpiphdrp_32)(tp) && \
|
tcpfrag_list_empty(tp) && \
|
||||||
(tp)->t_state == TCPS_ESTABLISHED) {\
|
(tp)->t_state == TCPS_ESTABLISHED) {\
|
||||||
if (ti->ti_flags & TH_PUSH) \
|
if (ti->ti_flags & TH_PUSH) \
|
||||||
tp->t_flags |= TF_ACKNOW; \
|
tp->t_flags |= TF_ACKNOW; \
|
||||||
|
@ -94,7 +90,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
|
||||||
#else
|
#else
|
||||||
#define TCP_REASS(tp, ti, m, so, flags) { \
|
#define TCP_REASS(tp, ti, m, so, flags) { \
|
||||||
if ((ti)->ti_seq == (tp)->rcv_nxt && \
|
if ((ti)->ti_seq == (tp)->rcv_nxt && \
|
||||||
(tp)->seg_next == (tcpiphdrp_32)(tp) && \
|
tcpfrag_list_empty(tp) && \
|
||||||
(tp)->t_state == TCPS_ESTABLISHED) { \
|
(tp)->t_state == TCPS_ESTABLISHED) { \
|
||||||
tp->t_flags |= TF_DELACK; \
|
tp->t_flags |= TF_DELACK; \
|
||||||
(tp)->rcv_nxt += (ti)->ti_len; \
|
(tp)->rcv_nxt += (ti)->ti_len; \
|
||||||
|
@ -134,8 +130,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
|
||||||
/*
|
/*
|
||||||
* Find a segment which begins after this one does.
|
* Find a segment which begins after this one does.
|
||||||
*/
|
*/
|
||||||
for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp;
|
for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp);
|
||||||
q = (struct tcpiphdr *)q->ti_next)
|
q = tcpiphdr_next(q))
|
||||||
if (SEQ_GT(q->ti_seq, ti->ti_seq))
|
if (SEQ_GT(q->ti_seq, ti->ti_seq))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -144,9 +140,9 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
|
||||||
* our data already. If so, drop the data from the incoming
|
* our data already. If so, drop the data from the incoming
|
||||||
* segment. If it provides all of our data, drop us.
|
* segment. If it provides all of our data, drop us.
|
||||||
*/
|
*/
|
||||||
if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
|
if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) {
|
||||||
register int i;
|
register int i;
|
||||||
q = (struct tcpiphdr *)q->ti_prev;
|
q = tcpiphdr_prev(q);
|
||||||
/* conversion to int (in i) handles seq wraparound */
|
/* conversion to int (in i) handles seq wraparound */
|
||||||
i = q->ti_seq + q->ti_len - ti->ti_seq;
|
i = q->ti_seq + q->ti_len - ti->ti_seq;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
@ -166,36 +162,36 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
|
||||||
ti->ti_len -= i;
|
ti->ti_len -= i;
|
||||||
ti->ti_seq += i;
|
ti->ti_seq += i;
|
||||||
}
|
}
|
||||||
q = (struct tcpiphdr *)(q->ti_next);
|
q = tcpiphdr_next(q);
|
||||||
}
|
}
|
||||||
STAT(tcpstat.tcps_rcvoopack++);
|
STAT(tcpstat.tcps_rcvoopack++);
|
||||||
STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
|
STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
|
||||||
REASS_MBUF(ti) = (mbufp_32) m; /* XXX */
|
ti->ti_mbuf = m;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* While we overlap succeeding segments trim them or,
|
* While we overlap succeeding segments trim them or,
|
||||||
* if they are completely covered, dequeue them.
|
* if they are completely covered, dequeue them.
|
||||||
*/
|
*/
|
||||||
while (q != (struct tcpiphdr *)tp) {
|
while (!tcpfrag_list_end(q, tp)) {
|
||||||
register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
|
register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
|
||||||
if (i <= 0)
|
if (i <= 0)
|
||||||
break;
|
break;
|
||||||
if (i < q->ti_len) {
|
if (i < q->ti_len) {
|
||||||
q->ti_seq += i;
|
q->ti_seq += i;
|
||||||
q->ti_len -= i;
|
q->ti_len -= i;
|
||||||
m_adj((struct mbuf *) REASS_MBUF(q), i);
|
m_adj(q->ti_mbuf, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
q = (struct tcpiphdr *)q->ti_next;
|
q = tcpiphdr_next(q);
|
||||||
m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev);
|
m = tcpiphdr_prev(q)->ti_mbuf;
|
||||||
remque_32((void *)(q->ti_prev));
|
remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stick new segment in its place.
|
* Stick new segment in its place.
|
||||||
*/
|
*/
|
||||||
insque_32(ti, (void *)(q->ti_prev));
|
insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q)));
|
||||||
|
|
||||||
present:
|
present:
|
||||||
/*
|
/*
|
||||||
|
@ -204,17 +200,17 @@ present:
|
||||||
*/
|
*/
|
||||||
if (!TCPS_HAVEESTABLISHED(tp->t_state))
|
if (!TCPS_HAVEESTABLISHED(tp->t_state))
|
||||||
return (0);
|
return (0);
|
||||||
ti = (struct tcpiphdr *) tp->seg_next;
|
ti = tcpfrag_list_first(tp);
|
||||||
if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
|
if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
|
||||||
return (0);
|
return (0);
|
||||||
if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
|
if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
|
||||||
return (0);
|
return (0);
|
||||||
do {
|
do {
|
||||||
tp->rcv_nxt += ti->ti_len;
|
tp->rcv_nxt += ti->ti_len;
|
||||||
flags = ti->ti_flags & TH_FIN;
|
flags = ti->ti_flags & TH_FIN;
|
||||||
remque_32(ti);
|
remque(tcpiphdr2qlink(ti));
|
||||||
m = (struct mbuf *) REASS_MBUF(ti); /* XXX */
|
m = ti->ti_mbuf;
|
||||||
ti = (struct tcpiphdr *)ti->ti_next;
|
ti = tcpiphdr_next(ti);
|
||||||
/* if (so->so_state & SS_FCANTRCVMORE) */
|
/* if (so->so_state & SS_FCANTRCVMORE) */
|
||||||
if (so->so_state & SS_FCANTSENDMORE)
|
if (so->so_state & SS_FCANTSENDMORE)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
|
@ -253,6 +249,7 @@ tcp_input(m, iphlen, inso)
|
||||||
u_long tiwin;
|
u_long tiwin;
|
||||||
int ret;
|
int ret;
|
||||||
/* int ts_present = 0; */
|
/* int ts_present = 0; */
|
||||||
|
struct ex_list *ex_ptr;
|
||||||
|
|
||||||
DEBUG_CALL("tcp_input");
|
DEBUG_CALL("tcp_input");
|
||||||
DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
|
DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
|
||||||
|
@ -301,7 +298,8 @@ tcp_input(m, iphlen, inso)
|
||||||
* Checksum extended TCP header and data.
|
* Checksum extended TCP header and data.
|
||||||
*/
|
*/
|
||||||
tlen = ((struct ip *)ti)->ip_len;
|
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_x1 = 0;
|
ti->ti_x1 = 0;
|
||||||
ti->ti_len = htons((u_int16_t)tlen);
|
ti->ti_len = htons((u_int16_t)tlen);
|
||||||
len = sizeof(struct ip ) + tlen;
|
len = sizeof(struct ip ) + tlen;
|
||||||
|
@ -363,6 +361,15 @@ tcp_input(m, iphlen, inso)
|
||||||
m->m_data += 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);
|
m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
|
||||||
|
|
||||||
|
if (slirp_restrict) {
|
||||||
|
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
|
||||||
|
if (ex_ptr->ex_fport == ti->ti_dport &&
|
||||||
|
(ntohl(ti->ti_dst.s_addr) & 0xff) == ex_ptr->ex_addr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ex_ptr)
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Locate pcb for segment.
|
* Locate pcb for segment.
|
||||||
*/
|
*/
|
||||||
|
@ -550,7 +557,7 @@ findso:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (ti->ti_ack == tp->snd_una &&
|
} else if (ti->ti_ack == tp->snd_una &&
|
||||||
tp->seg_next == (tcpiphdrp_32)tp &&
|
tcpfrag_list_empty(tp) &&
|
||||||
ti->ti_len <= sbspace(&so->so_rcv)) {
|
ti->ti_len <= sbspace(&so->so_rcv)) {
|
||||||
/*
|
/*
|
||||||
* this is a pure, in-sequence data packet
|
* this is a pure, in-sequence data packet
|
||||||
|
@ -646,7 +653,6 @@ findso:
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* May be an add exec */
|
/* May be an add exec */
|
||||||
struct ex_list *ex_ptr;
|
|
||||||
for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
|
for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
|
||||||
if(ex_ptr->ex_fport == so->so_fport &&
|
if(ex_ptr->ex_fport == so->so_fport &&
|
||||||
lastbyte == ex_ptr->ex_addr) {
|
lastbyte == ex_ptr->ex_addr) {
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -73,7 +69,7 @@ tcp_template(tp)
|
||||||
struct socket *so = tp->t_socket;
|
struct socket *so = tp->t_socket;
|
||||||
register struct tcpiphdr *n = &tp->t_template;
|
register struct tcpiphdr *n = &tp->t_template;
|
||||||
|
|
||||||
n->ti_next = n->ti_prev = 0;
|
n->ti_mbuf = NULL;
|
||||||
n->ti_x1 = 0;
|
n->ti_x1 = 0;
|
||||||
n->ti_pr = IPPROTO_TCP;
|
n->ti_pr = IPPROTO_TCP;
|
||||||
n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
|
n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
|
||||||
|
@ -156,7 +152,7 @@ tcp_respond(tp, ti, m, ack, seq, flags)
|
||||||
tlen += sizeof (struct tcpiphdr);
|
tlen += sizeof (struct tcpiphdr);
|
||||||
m->m_len = tlen;
|
m->m_len = tlen;
|
||||||
|
|
||||||
ti->ti_next = ti->ti_prev = 0;
|
ti->ti_mbuf = 0;
|
||||||
ti->ti_x1 = 0;
|
ti->ti_x1 = 0;
|
||||||
ti->ti_seq = htonl(seq);
|
ti->ti_seq = htonl(seq);
|
||||||
ti->ti_ack = htonl(ack);
|
ti->ti_ack = htonl(ack);
|
||||||
|
@ -196,7 +192,7 @@ tcp_newtcpcb(so)
|
||||||
return ((struct tcpcb *)0);
|
return ((struct tcpcb *)0);
|
||||||
|
|
||||||
memset((char *) tp, 0, sizeof(struct tcpcb));
|
memset((char *) tp, 0, sizeof(struct tcpcb));
|
||||||
tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
|
tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
|
||||||
tp->t_maxseg = TCP_MSS;
|
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;
|
||||||
|
@ -272,11 +268,11 @@ tcp_close(tp)
|
||||||
DEBUG_ARG("tp = %lx", (long )tp);
|
DEBUG_ARG("tp = %lx", (long )tp);
|
||||||
|
|
||||||
/* free the reassembly queue, if any */
|
/* free the reassembly queue, if any */
|
||||||
t = (struct tcpiphdr *) tp->seg_next;
|
t = tcpfrag_list_first(tp);
|
||||||
while (t != (struct tcpiphdr *)tp) {
|
while (!tcpfrag_list_end(t, tp)) {
|
||||||
t = (struct tcpiphdr *)t->ti_next;
|
t = tcpiphdr_next(t);
|
||||||
m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev);
|
m = tcpiphdr_prev(t)->ti_mbuf;
|
||||||
remque_32((struct tcpiphdr *) t->ti_prev);
|
remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
/* It's static */
|
/* It's static */
|
||||||
|
@ -447,7 +443,7 @@ tcp_connect(inso)
|
||||||
{
|
{
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int addrlen = sizeof(struct sockaddr_in);
|
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||||
struct tcpcb *tp;
|
struct tcpcb *tp;
|
||||||
int s, opt;
|
int s, opt;
|
||||||
|
|
||||||
|
@ -629,7 +625,7 @@ tcp_emu(so, m)
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
{
|
{
|
||||||
u_int n1, n2, n3, n4, n5, n6;
|
u_int n1, n2, n3, n4, n5, n6;
|
||||||
char buff[256];
|
char buff[257];
|
||||||
u_int32_t laddr;
|
u_int32_t laddr;
|
||||||
u_int lport;
|
u_int lport;
|
||||||
char *bptr;
|
char *bptr;
|
||||||
|
@ -649,7 +645,7 @@ tcp_emu(so, m)
|
||||||
{
|
{
|
||||||
struct socket *tmpso;
|
struct socket *tmpso;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int addrlen = sizeof(struct sockaddr_in);
|
socklen_t addrlen = sizeof(struct sockaddr_in);
|
||||||
struct sbuf *so_rcv = &so->so_rcv;
|
struct sbuf *so_rcv = &so->so_rcv;
|
||||||
|
|
||||||
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
|
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
|
||||||
|
@ -673,7 +669,9 @@ tcp_emu(so, m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2);
|
so_rcv->sb_cc = snprintf(so_rcv->sb_data,
|
||||||
|
so_rcv->sb_datalen,
|
||||||
|
"%d,%d\r\n", n1, n2);
|
||||||
so_rcv->sb_rptr = so_rcv->sb_data;
|
so_rcv->sb_rptr = so_rcv->sb_data;
|
||||||
so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
|
so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
|
||||||
}
|
}
|
||||||
|
@ -1007,8 +1005,9 @@ do_prompt:
|
||||||
n4 = (laddr & 0xff);
|
n4 = (laddr & 0xff);
|
||||||
|
|
||||||
m->m_len = bptr - m->m_data; /* Adjust length */
|
m->m_len = bptr - m->m_data; /* Adjust length */
|
||||||
m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
|
m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len,
|
||||||
n1, n2, n3, n4, n5, n6, x==7?buff:"");
|
"ORT %d,%d,%d,%d,%d,%d\r\n%s",
|
||||||
|
n1, n2, n3, n4, n5, n6, x==7?buff:"");
|
||||||
return 1;
|
return 1;
|
||||||
} else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
|
} else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
|
||||||
/*
|
/*
|
||||||
|
@ -1038,8 +1037,9 @@ do_prompt:
|
||||||
n4 = (laddr & 0xff);
|
n4 = (laddr & 0xff);
|
||||||
|
|
||||||
m->m_len = bptr - m->m_data; /* Adjust length */
|
m->m_len = bptr - m->m_data; /* Adjust length */
|
||||||
m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
|
m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len,
|
||||||
n1, n2, n3, n4, n5, n6, x==7?buff:"");
|
"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
|
||||||
|
n1, n2, n3, n4, n5, n6, x==7?buff:"");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1062,7 +1062,8 @@ do_prompt:
|
||||||
}
|
}
|
||||||
if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
|
if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
|
||||||
(so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
|
(so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
|
||||||
m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;
|
m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d",
|
||||||
|
ntohs(so->so_fport)) + 1;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EMU_IRC:
|
case EMU_IRC:
|
||||||
|
@ -1079,25 +1080,28 @@ do_prompt:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
m->m_len = bptr - m->m_data; /* Adjust length */
|
m->m_len = bptr - m->m_data; /* Adjust length */
|
||||||
m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",
|
m->m_len += snprintf(bptr, m->m_hdr.mh_size,
|
||||||
(unsigned long)ntohl(so->so_faddr.s_addr),
|
"DCC CHAT chat %lu %u%c\n",
|
||||||
ntohs(so->so_fport), 1);
|
(unsigned long)ntohl(so->so_faddr.s_addr),
|
||||||
|
ntohs(so->so_fport), 1);
|
||||||
} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
|
} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
|
||||||
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
m->m_len = bptr - m->m_data; /* Adjust length */
|
m->m_len = bptr - m->m_data; /* Adjust length */
|
||||||
m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
|
m->m_len += snprintf(bptr, m->m_hdr.mh_size,
|
||||||
buff, (unsigned long)ntohl(so->so_faddr.s_addr),
|
"DCC SEND %s %lu %u %u%c\n", buff,
|
||||||
ntohs(so->so_fport), n1, 1);
|
(unsigned long)ntohl(so->so_faddr.s_addr),
|
||||||
|
ntohs(so->so_fport), n1, 1);
|
||||||
} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
|
} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
|
||||||
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
m->m_len = bptr - m->m_data; /* Adjust length */
|
m->m_len = bptr - m->m_data; /* Adjust length */
|
||||||
m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",
|
m->m_len += snprintf(bptr, m->m_hdr.mh_size,
|
||||||
buff, (unsigned long)ntohl(so->so_faddr.s_addr),
|
"DCC MOVE %s %lu %u %u%c\n", buff,
|
||||||
ntohs(so->so_fport), n1, 1);
|
(unsigned long)ntohl(so->so_faddr.s_addr),
|
||||||
|
ntohs(so->so_fport), n1, 1);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -1273,6 +1277,11 @@ tcp_ctl(so)
|
||||||
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
|
for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
|
||||||
if (ex_ptr->ex_fport == so->so_fport &&
|
if (ex_ptr->ex_fport == so->so_fport &&
|
||||||
command == ex_ptr->ex_addr) {
|
command == ex_ptr->ex_addr) {
|
||||||
|
if (ex_ptr->ex_pty == 3) {
|
||||||
|
so->s = -1;
|
||||||
|
so->extra = (void *)ex_ptr->ex_exec;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
do_pty = ex_ptr->ex_pty;
|
do_pty = ex_ptr->ex_pty;
|
||||||
goto do_exec;
|
goto do_exec;
|
||||||
}
|
}
|
||||||
|
@ -1285,8 +1294,8 @@ tcp_ctl(so)
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case CTL_ALIAS:
|
case CTL_ALIAS:
|
||||||
sb->sb_cc = sprintf(sb->sb_wptr,
|
sb->sb_cc = snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data),
|
||||||
"Error: No application configured.\r\n");
|
"Error: No application configured.\r\n");
|
||||||
sb->sb_wptr += sb->sb_cc;
|
sb->sb_wptr += sb->sb_cc;
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -40,18 +36,12 @@
|
||||||
#include "tcpip.h"
|
#include "tcpip.h"
|
||||||
#include "tcp_timer.h"
|
#include "tcp_timer.h"
|
||||||
|
|
||||||
#if SIZEOF_CHAR_P == 4
|
|
||||||
typedef struct tcpiphdr *tcpiphdrp_32;
|
|
||||||
#else
|
|
||||||
typedef u_int32_t tcpiphdrp_32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tcp control block, one per tcp; fields:
|
* Tcp control block, one per tcp; fields:
|
||||||
*/
|
*/
|
||||||
struct tcpcb {
|
struct tcpcb {
|
||||||
tcpiphdrp_32 seg_next; /* sequencing queue */
|
struct tcpiphdr *seg_next; /* sequencing queue */
|
||||||
tcpiphdrp_32 seg_prev;
|
struct tcpiphdr *seg_prev;
|
||||||
short t_state; /* state of this connection */
|
short t_state; /* state of this connection */
|
||||||
short t_timer[TCPT_NTIMERS]; /* tcp timers */
|
short t_timer[TCPT_NTIMERS]; /* tcp timers */
|
||||||
short t_rxtshift; /* log(2) of rexmt exp. backoff */
|
short t_rxtshift; /* log(2) of rexmt exp. backoff */
|
||||||
|
@ -170,21 +160,6 @@ struct tcpcb {
|
||||||
#define TCP_REXMTVAL(tp) \
|
#define TCP_REXMTVAL(tp) \
|
||||||
(((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
|
(((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
|
||||||
|
|
||||||
/* XXX
|
|
||||||
* We want to avoid doing m_pullup on incoming packets but that
|
|
||||||
* means avoiding dtom on the tcp reassembly code. That in turn means
|
|
||||||
* keeping an mbuf pointer in the reassembly queue (since we might
|
|
||||||
* have a cluster). As a quick hack, the source & destination
|
|
||||||
* port numbers (which are no longer needed once we've located the
|
|
||||||
* tcpcb) are overlayed with an mbuf pointer.
|
|
||||||
*/
|
|
||||||
#if SIZEOF_CHAR_P == 4
|
|
||||||
typedef struct mbuf *mbufp_32;
|
|
||||||
#else
|
|
||||||
typedef u_int32_t mbufp_32;
|
|
||||||
#endif
|
|
||||||
#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
|
|
||||||
|
|
||||||
#ifdef LOG_ENABLED
|
#ifdef LOG_ENABLED
|
||||||
/*
|
/*
|
||||||
* TCP statistics.
|
* TCP statistics.
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -44,8 +40,7 @@ struct tcpiphdr {
|
||||||
struct ipovly ti_i; /* overlaid ip structure */
|
struct ipovly ti_i; /* overlaid ip structure */
|
||||||
struct tcphdr ti_t; /* tcp header */
|
struct tcphdr ti_t; /* tcp header */
|
||||||
};
|
};
|
||||||
#define ti_next ti_i.ih_next
|
#define ti_mbuf ti_i.ih_mbuf.mptr
|
||||||
#define ti_prev ti_i.ih_prev
|
|
||||||
#define ti_x1 ti_i.ih_x1
|
#define ti_x1 ti_i.ih_x1
|
||||||
#define ti_pr ti_i.ih_pr
|
#define ti_pr ti_i.ih_pr
|
||||||
#define ti_len ti_i.ih_len
|
#define ti_len ti_i.ih_len
|
||||||
|
@ -62,6 +57,14 @@ struct tcpiphdr {
|
||||||
#define ti_sum ti_t.th_sum
|
#define ti_sum ti_t.th_sum
|
||||||
#define ti_urp ti_t.th_urp
|
#define ti_urp ti_t.th_urp
|
||||||
|
|
||||||
|
#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink)))
|
||||||
|
#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink)))
|
||||||
|
#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next)
|
||||||
|
#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev)
|
||||||
|
#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next)
|
||||||
|
#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T))
|
||||||
|
#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just a clean way to get to the first byte
|
* Just a clean way to get to the first byte
|
||||||
* of the packet
|
* of the packet
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <slirp.h>
|
#include <slirp.h>
|
||||||
|
#include "qemu-common.h" // for pstrcpy
|
||||||
|
|
||||||
struct tftp_session {
|
struct tftp_session {
|
||||||
int in_use;
|
int in_use;
|
||||||
|
@ -148,8 +149,10 @@ static int tftp_send_oack(struct tftp_session *spt,
|
||||||
m->m_data += sizeof(struct udpiphdr);
|
m->m_data += sizeof(struct udpiphdr);
|
||||||
|
|
||||||
tp->tp_op = htons(TFTP_OACK);
|
tp->tp_op = htons(TFTP_OACK);
|
||||||
n += sprintf(tp->x.tp_buf + n, "%s", key) + 1;
|
n += snprintf((char *)tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s",
|
||||||
n += sprintf(tp->x.tp_buf + n, "%u", value) + 1;
|
key) + 1;
|
||||||
|
n += snprintf((char *)tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u",
|
||||||
|
value) + 1;
|
||||||
|
|
||||||
saddr.sin_addr = recv_tp->ip.ip_dst;
|
saddr.sin_addr = recv_tp->ip.ip_dst;
|
||||||
saddr.sin_port = recv_tp->udp.uh_dport;
|
saddr.sin_port = recv_tp->udp.uh_dport;
|
||||||
|
@ -189,7 +192,7 @@ static int tftp_send_error(struct tftp_session *spt,
|
||||||
|
|
||||||
tp->tp_op = htons(TFTP_ERROR);
|
tp->tp_op = htons(TFTP_ERROR);
|
||||||
tp->x.tp_error.tp_error_code = htons(errorcode);
|
tp->x.tp_error.tp_error_code = htons(errorcode);
|
||||||
strcpy(tp->x.tp_error.tp_msg, msg);
|
pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);
|
||||||
|
|
||||||
saddr.sin_addr = recv_tp->ip.ip_dst;
|
saddr.sin_addr = recv_tp->ip.ip_dst;
|
||||||
saddr.sin_port = recv_tp->udp.uh_dport;
|
saddr.sin_port = recv_tp->udp.uh_dport;
|
||||||
|
@ -324,8 +327,8 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
|
||||||
/* do sanity checks on the filename */
|
/* do sanity checks on the filename */
|
||||||
|
|
||||||
if ((spt->filename[0] != '/')
|
if ((spt->filename[0] != '/')
|
||||||
|| (spt->filename[strlen(spt->filename) - 1] == '/')
|
|| (spt->filename[strlen((char *)spt->filename) - 1] == '/')
|
||||||
|| strstr(spt->filename, "/../")) {
|
|| strstr((char *)spt->filename, "/../")) {
|
||||||
tftp_send_error(spt, 2, "Access violation", tp);
|
tftp_send_error(spt, 2, "Access violation", tp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +355,7 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
|
||||||
while (k < n) {
|
while (k < n) {
|
||||||
const char *key, *value;
|
const char *key, *value;
|
||||||
|
|
||||||
key = src + k;
|
key = (char *)src + k;
|
||||||
k += strlen(key) + 1;
|
k += strlen(key) + 1;
|
||||||
|
|
||||||
if (k >= n) {
|
if (k >= n) {
|
||||||
|
@ -360,7 +363,7 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = src + k;
|
value = (char *)src + k;
|
||||||
k += strlen(value) + 1;
|
k += strlen(value) + 1;
|
||||||
|
|
||||||
if (strcmp(key, "tsize") == 0) {
|
if (strcmp(key, "tsize") == 0) {
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -136,8 +132,7 @@ udp_input(m, iphlen)
|
||||||
* Checksum extended UDP header and data.
|
* Checksum extended UDP header and data.
|
||||||
*/
|
*/
|
||||||
if (UDPCKSUM && uh->uh_sum) {
|
if (UDPCKSUM && uh->uh_sum) {
|
||||||
((struct ipovly *)ip)->ih_next = 0;
|
memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr));
|
||||||
((struct ipovly *)ip)->ih_prev = 0;
|
|
||||||
((struct ipovly *)ip)->ih_x1 = 0;
|
((struct ipovly *)ip)->ih_x1 = 0;
|
||||||
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
|
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
|
||||||
/* keep uh_sum for ICMP reply
|
/* keep uh_sum for ICMP reply
|
||||||
|
@ -158,6 +153,9 @@ udp_input(m, iphlen)
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (slirp_restrict)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle TFTP
|
* handle TFTP
|
||||||
*/
|
*/
|
||||||
|
@ -280,7 +278,7 @@ int udp_output2(struct socket *so, struct mbuf *m,
|
||||||
* and addresses and length put into network format.
|
* and addresses and length put into network format.
|
||||||
*/
|
*/
|
||||||
ui = mtod(m, struct udpiphdr *);
|
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_x1 = 0;
|
ui->ui_x1 = 0;
|
||||||
ui->ui_pr = IPPROTO_UDP;
|
ui->ui_pr = IPPROTO_UDP;
|
||||||
ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
|
ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
|
||||||
|
@ -319,9 +317,11 @@ int udp_output(struct socket *so, struct mbuf *m,
|
||||||
|
|
||||||
saddr = *addr;
|
saddr = *addr;
|
||||||
if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
|
if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
|
||||||
saddr.sin_addr.s_addr = so->so_faddr.s_addr;
|
|
||||||
if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff))
|
if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff))
|
||||||
saddr.sin_addr.s_addr = alias_addr.s_addr;
|
saddr.sin_addr.s_addr = alias_addr.s_addr;
|
||||||
|
else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
|
||||||
|
(ntohl(so->so_faddr.s_addr) & 0xff) != CTL_ALIAS)
|
||||||
|
saddr.sin_addr.s_addr = so->so_faddr.s_addr;
|
||||||
}
|
}
|
||||||
daddr.sin_addr = so->so_laddr;
|
daddr.sin_addr = so->so_laddr;
|
||||||
daddr.sin_port = so->so_lport;
|
daddr.sin_port = so->so_lport;
|
||||||
|
@ -408,7 +408,7 @@ static void
|
||||||
udp_emu(struct socket *so, struct mbuf *m)
|
udp_emu(struct socket *so, struct mbuf *m)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int addrlen = sizeof(addr);
|
socklen_t addrlen = sizeof(addr);
|
||||||
#ifdef EMULATE_TALK
|
#ifdef EMULATE_TALK
|
||||||
CTL_MSG_OLD *omsg;
|
CTL_MSG_OLD *omsg;
|
||||||
CTL_MSG *nmsg;
|
CTL_MSG *nmsg;
|
||||||
|
@ -473,14 +473,14 @@ struct cu_header {
|
||||||
type = omsg->type;
|
type = omsg->type;
|
||||||
OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port;
|
OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port;
|
||||||
OTOSIN(omsg, ctl_addr)->sin_addr = our_addr;
|
OTOSIN(omsg, ctl_addr)->sin_addr = our_addr;
|
||||||
strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD);
|
pstrcpy(omsg->l_name, NAME_SIZE_OLD, getlogin());
|
||||||
} else { /* new talk */
|
} else { /* new talk */
|
||||||
omsg = (CTL_MSG_OLD *) buff;
|
omsg = (CTL_MSG_OLD *) buff;
|
||||||
nmsg = mtod(m, CTL_MSG *);
|
nmsg = mtod(m, CTL_MSG *);
|
||||||
type = nmsg->type;
|
type = nmsg->type;
|
||||||
OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port;
|
OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port;
|
||||||
OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr;
|
OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr;
|
||||||
strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD);
|
pstrcpy(nmsg->l_name, NAME_SIZE_OLD, getlogin());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == LOOK_UP)
|
if (type == LOOK_UP)
|
||||||
|
@ -639,7 +639,7 @@ udp_listen(port, laddr, lport, flags)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
int addrlen = sizeof(struct sockaddr_in), opt = 1;
|
socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1;
|
||||||
|
|
||||||
if ((so = socreate()) == NULL) {
|
if ((so = socreate()) == NULL) {
|
||||||
free(so);
|
free(so);
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
* 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
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
|
@ -60,8 +56,7 @@ struct udpiphdr {
|
||||||
struct ipovly ui_i; /* overlaid ip structure */
|
struct ipovly ui_i; /* overlaid ip structure */
|
||||||
struct udphdr ui_u; /* udp header */
|
struct udphdr ui_u; /* udp header */
|
||||||
};
|
};
|
||||||
#define ui_next ui_i.ih_next
|
#define ui_mbuf ui_i.ih_mbuf.mptr
|
||||||
#define ui_prev ui_i.ih_prev
|
|
||||||
#define ui_x1 ui_i.ih_x1
|
#define ui_x1 ui_i.ih_x1
|
||||||
#define ui_pr ui_i.ih_pr
|
#define ui_pr ui_i.ih_pr
|
||||||
#define ui_len ui_i.ih_len
|
#define ui_len ui_i.ih_len
|
||||||
|
|
Loading…
Reference in New Issue
Block a user