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