SLIRP 0.10.1

64 Bits clean ?
This commit is contained in:
jvernet 2017-10-03 22:37:31 +02:00
parent 4682bb80a1
commit ef4725552e
35 changed files with 764 additions and 450 deletions

View File

@ -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

View File

@ -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;

View File

@ -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.
* *

View File

@ -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

View File

@ -37,4 +37,3 @@ extern int slirp_debug;
#endif #endif
void debug_init _P((char *, int)); void debug_init _P((char *, int));

View File

@ -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.
* *

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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);
} }
} }
} }

View File

@ -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.
* *

View File

@ -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
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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.
* *

View File

@ -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 */

View File

@ -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);

View File

@ -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);
} }
} }

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
} }

View File

@ -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_ */

View File

@ -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.
* *

View File

@ -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) {

View File

@ -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.
* *

View File

@ -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);

View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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.

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -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