aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-07-25 00:44:40 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-07-25 00:44:40 +0200
commit44e7877ae8769df127426014c30672086328ddb9 (patch)
treed6e957e1d1a75158daa76e8af4443387a733db3d /src
parent2533bf21126a28f85e40fbfbbc9ba94fdb297530 (diff)
downloadslirp-44e7877ae8769df127426014c30672086328ddb9.zip
slirp-44e7877ae8769df127426014c30672086328ddb9.tar.gz
slirp-44e7877ae8769df127426014c30672086328ddb9.tar.bz2
Document functions
Diffstat (limited to 'src')
-rw-r--r--src/bootp.h1
-rw-r--r--src/dhcpv6.h1
-rw-r--r--src/if.c9
-rw-r--r--src/ip6.h9
-rw-r--r--src/ip6_icmp.h13
-rw-r--r--src/ip_icmp.c1
-rw-r--r--src/ip_icmp.h15
-rw-r--r--src/ip_input.c12
-rw-r--r--src/libslirp.h41
-rw-r--r--src/main.h5
-rw-r--r--src/mbuf.c11
-rw-r--r--src/mbuf.h39
-rw-r--r--src/misc.h19
-rw-r--r--src/sbuf.c11
-rw-r--r--src/sbuf.h19
-rw-r--r--src/slirp.h102
-rw-r--r--src/socket.c14
-rw-r--r--src/socket.h36
-rw-r--r--src/stream.h12
-rw-r--r--src/tcp_output.c3
-rw-r--r--src/tcp_subr.c37
-rw-r--r--src/tcp_timer.c3
-rw-r--r--src/tcp_timer.h3
-rw-r--r--src/tftp.h1
-rw-r--r--src/udp.h13
25 files changed, 315 insertions, 115 deletions
diff --git a/src/bootp.h b/src/bootp.h
index cf7797f..c510960 100644
--- a/src/bootp.h
+++ b/src/bootp.h
@@ -125,6 +125,7 @@ typedef struct {
#define NB_BOOTP_CLIENTS 16
+/* Process a bootp packet from the guest */
void bootp_input(struct mbuf *m);
#endif
diff --git a/src/dhcpv6.h b/src/dhcpv6.h
index d12c49b..c0b4a24 100644
--- a/src/dhcpv6.h
+++ b/src/dhcpv6.h
@@ -63,6 +63,7 @@
#define in6_dhcp_multicast(a) in6_equal(a, &(struct in6_addr)ALLDHCP_MULTICAST)
+/* Process a DHCPv6 packet from the guest */
void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf *m);
#endif
diff --git a/src/if.c b/src/if.c
index 741473d..6b365ce 100644
--- a/src/if.c
+++ b/src/if.c
@@ -131,15 +131,6 @@ diddit:
if_start(ifm->slirp);
}
-/*
- * Send one packet from each session.
- * If there are packets on the fastq, they are sent FIFO, before
- * everything else. Then we choose the first packet from each
- * batchq session (socket) and send it.
- * For example, if there are 3 ftp sessions fighting for bandwidth,
- * one packet will be sent from the first session, then one packet
- * from the second session, then one packet from the third.
- */
void if_start(Slirp *slirp)
{
uint64_t now = slirp->cb->clock_get_ns(slirp->opaque);
diff --git a/src/ip6.h b/src/ip6.h
index 96d3e2f..870e38b 100644
--- a/src/ip6.h
+++ b/src/ip6.h
@@ -98,11 +98,13 @@
} \
}
+/* Check that two IPv6 addresses are equal */
static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
{
return memcmp(a, b, sizeof(*a)) == 0;
}
+/* Check that two IPv6 addresses are equal in their network part */
static inline bool in6_equal_net(const struct in6_addr *a,
const struct in6_addr *b, int prefix_len)
{
@@ -118,6 +120,7 @@ static inline bool in6_equal_net(const struct in6_addr *a,
b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
}
+/* Check that two IPv6 addresses are equal in their machine part */
static inline bool in6_equal_mach(const struct in6_addr *a,
const struct in6_addr *b, int prefix_len)
{
@@ -136,24 +139,28 @@ static inline bool in6_equal_mach(const struct in6_addr *a,
(b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));
}
-
+/* Check that the IPv6 is equal to the virtual router */
#define in6_equal_router(a) \
((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \
in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len)) || \
(in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \
in6_equal_mach(a, &slirp->vhost_addr6, 64)))
+/* Check that the IPv6 is equal to the virtual DNS server */
#define in6_equal_dns(a) \
((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \
in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len)) || \
(in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \
in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
+/* Check that the IPv6 is equal to the host */
#define in6_equal_host(a) (in6_equal_router(a) || in6_equal_dns(a))
+/* Check that the IPv6 is within the sollicited node multicast network */
#define in6_solicitednode_multicast(a) \
(in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
+/* Check that the IPv6 is zero */
#define in6_zero(a) (in6_equal(a, &(struct in6_addr)ZERO_ADDR))
/* Compute emulated host MAC address from its ipv6 address */
diff --git a/src/ip6_icmp.h b/src/ip6_icmp.h
index 33a568d..572105a 100644
--- a/src/ip6_icmp.h
+++ b/src/ip6_icmp.h
@@ -214,12 +214,25 @@ struct ndpopt {
#define NDP_AdvPrefLifetime 14400
#define NDP_AdvAutonomousFlag 1
+/* Called from slirp_new, but after other initialization */
void icmp6_post_init(Slirp *slirp);
+
+/* Called from slirp_cleanup */
void icmp6_cleanup(Slirp *slirp);
+
+/* Process an ICMPv6 packet from the guest */
void icmp6_input(struct mbuf *);
+
+/* Send an ICMPv6 error related to the given packet, using the given ICMPv6 type and code, using the given source */
void icmp6_forward_error(struct mbuf *m, uint8_t type, uint8_t code, struct in6_addr *src);
+
+/* Similar to icmp6_forward_error, but use the link-local address as source */
void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code);
+
+/* Send a neighbour sollicitation, to resolve the given IPV6 address */
void ndp_send_ns(Slirp *slirp, struct in6_addr addr);
+
+/* Timer handler for router advertisement, to send it and reschedule the timer */
void ra_timer_handler(Slirp *slirp, void *unused);
#endif
diff --git a/src/ip_icmp.c b/src/ip_icmp.c
index 755fa3d..ffd2bc7 100644
--- a/src/ip_icmp.c
+++ b/src/ip_icmp.c
@@ -85,6 +85,7 @@ void icmp_cleanup(Slirp *slirp)
}
}
+/* Send ICMP packet to the Internet, and save it to so_m */
static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
{
Slirp *slirp = m->slirp;
diff --git a/src/ip_icmp.h b/src/ip_icmp.h
index 569a083..aad0416 100644
--- a/src/ip_icmp.h
+++ b/src/ip_icmp.h
@@ -154,15 +154,30 @@ struct icmp {
(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+/* Called from slirp_new */
void icmp_init(Slirp *slirp);
+
+/* Called from slirp_cleanup */
void icmp_cleanup(Slirp *slirp);
+
+/* Process an ICMP packet from the guest */
void icmp_input(struct mbuf *, int);
+
+/* Send an ICMP error related to the given packet, using the given ICMP type and code, appending the given message (if enabled at compilation), and using the given source. If minsize is sent, send only header + 8B of the given packet, otherwise send it all */
void icmp_forward_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
const char *message, struct in_addr *src);
+
+/* Similar to icmp_forward_error, but use the virtual host address as source */
void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
const char *message);
+
+/* Forward the ICMP packet to the guest (probably a ping reply) */
void icmp_reflect(struct mbuf *);
+
+/* Handle ICMP data from the ICMP socket, and forward it to the guest (using so_m as reference) */
void icmp_receive(struct socket *so);
+
+/* Forget about this pending ICMP request */
void icmp_detach(struct socket *so);
#endif
diff --git a/src/ip_input.c b/src/ip_input.c
index 4860e7a..5cf0946 100644
--- a/src/ip_input.c
+++ b/src/ip_input.c
@@ -413,11 +413,6 @@ static void ip_deq(register struct ipas *p)
((struct ipas *)(p->link.next))->link.prev = p->link.prev;
}
-/*
- * IP timer processing;
- * if a timer expires on a reassembly
- * queue, discard it.
- */
void ip_slowtimo(Slirp *slirp)
{
struct qlink *l;
@@ -438,13 +433,6 @@ void ip_slowtimo(Slirp *slirp)
}
}
-/*
- * Strip out IP options, at higher
- * level protocol in the kernel.
- * Second argument is buffer to which options
- * will be moved, and return value is their length.
- * (XXX) should be deleted; last arg currently ignored.
- */
void ip_stripoptions(register struct mbuf *m, struct mbuf *mopt)
{
register int i;
diff --git a/src/libslirp.h b/src/libslirp.h
index 9acdcee..09500b9 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -43,12 +43,18 @@ enum {
SLIRP_POLL_HUP = 1 << 4,
};
+/* Callback for application to get data from the guest */
typedef slirp_ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
+/* Callback for application to send data to the guest */
typedef slirp_ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+/* Timer callback */
typedef void (*SlirpTimerCb)(void *opaque);
+/* Callback for libslirp to register polling callbacks */
typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
+/* Callback for libslirp to get polling result */
typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
+/* For now libslirp creates only a timer for the IPv6 RA */
typedef enum SlirpTimerId {
SLIRP_TIMER_RA,
SLIRP_TIMER_NUM,
@@ -108,26 +114,46 @@ typedef struct SlirpConfig {
/*
* Fields introduced in SlirpConfig version 1 begin
*/
+ /* Whether to prevent the guest from accessing the Internet */
int restricted;
+ /* Whether IPv4 is enabled */
bool in_enabled;
+ /* Virtual network for the guest */
struct in_addr vnetwork;
+ /* Mask for the virtual network for the guest */
struct in_addr vnetmask;
+ /* Virtual address for the host exposed to the guest */
struct in_addr vhost;
+ /* Whether IPv6 is enabled */
bool in6_enabled;
+ /* Virtual IPv6 network for the guest */
struct in6_addr vprefix_addr6;
+ /* Len of the virtual IPv6 network for the guest */
uint8_t vprefix_len;
+ /* Virtual address for the host exposed to the guest */
struct in6_addr vhost6;
+ /* Hostname exposed to the guest in DHCP hostname option */
const char *vhostname;
+ /* Hostname exposed to the guest in the DHCP TFTP server name option */
const char *tftp_server_name;
+ /* Path of the files served by TFTP */
const char *tftp_path;
+ /* Boot file name exposed to the guest via DHCP */
const char *bootfile;
+ /* Start of the DHCP range */
struct in_addr vdhcp_start;
+ /* Virtual address for the DNS server exposed to the guest */
struct in_addr vnameserver;
+ /* Virtual IPv6 address for the DNS server exposed to the guest */
struct in6_addr vnameserver6;
+ /* DNS search names exposed to the guest via DHCP */
const char **vdnssearch;
+ /* Domain name exposed to the guest via DHCP */
const char *vdomainname;
+ /* MTU when sending packets to the guest */
/* Default: IF_MTU_DEFAULT */
size_t if_mtu;
+ /* MRU when receiving packets from the guest */
/* Default: IF_MRU_DEFAULT */
size_t if_mru;
/* Prohibit connecting to 127.0.0.1:* */
@@ -137,23 +163,32 @@ typedef struct SlirpConfig {
* recommended to enable it)
*/
bool enable_emu;
+
/*
* Fields introduced in SlirpConfig version 2 begin
*/
+ /* Address to be used when sending data to the Internet */
struct sockaddr_in *outbound_addr;
+ /* IPv6 Address to be used when sending data to the Internet */
struct sockaddr_in6 *outbound_addr6;
+
/*
* Fields introduced in SlirpConfig version 3 begin
*/
- bool disable_dns; /* slirp will not redirect/serve any DNS packet */
+ /* slirp will not redirect/serve any DNS packet */
+ bool disable_dns;
+
/*
* Fields introduced in SlirpConfig version 4 begin
*/
- bool disable_dhcp; /* slirp will not reply to any DHCP requests */
+ /* slirp will not reply to any DHCP requests */
+ bool disable_dhcp;
+
/*
* Fields introduced in SlirpConfig version 5 begin
*/
- uint32_t mfr_id; /* Manufacturer ID (IANA Private Enterprise number) */
+ /* Manufacturer ID (IANA Private Enterprise number) */
+ uint32_t mfr_id;
/*
* MAC address allocated for an out-of-band management controller, to be
* retrieved through NC-SI.
diff --git a/src/main.h b/src/main.h
index 2e7f21a..ca36277 100644
--- a/src/main.h
+++ b/src/main.h
@@ -8,11 +8,16 @@
#include "libslirp.h"
+/* The current guest virtual time */
extern unsigned curtime;
+/* Always equal to INADDR_LOOPBACK, in network order */
extern struct in_addr loopback_addr;
+/* Always equal to IN_CLASSA_NET, in network order */
extern unsigned long loopback_mask;
+/* Send a packet to the guest */
int if_encap(Slirp *slirp, struct mbuf *ifm);
+/* Send a frame to the guest. Flags are passed to the send() call */
slirp_ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
#endif
diff --git a/src/mbuf.c b/src/mbuf.c
index 6e390dc..6fa4065 100644
--- a/src/mbuf.c
+++ b/src/mbuf.c
@@ -199,11 +199,6 @@ int m_copy(struct mbuf *n, struct mbuf *m, int off, int len)
}
-/*
- * Given a pointer into an mbuf, return the mbuf
- * XXX This is a kludge, I should eliminate the need for it
- * Fortunately, it's not used often
- */
struct mbuf *dtom(Slirp *slirp, void *dat)
{
struct mbuf *m;
@@ -228,12 +223,6 @@ struct mbuf *dtom(Slirp *slirp, void *dat)
return (struct mbuf *)0;
}
-/*
- * Duplicate the mbuf
- *
- * copy_header specifies whether the bytes before m_data should also be copied.
- * header_size specifies how many bytes are to be reserved before m_data.
- */
struct mbuf *m_dup(Slirp *slirp, struct mbuf *m,
bool copy_header,
size_t header_size)
diff --git a/src/mbuf.h b/src/mbuf.h
index aedfc71..d73ce3f 100644
--- a/src/mbuf.h
+++ b/src/mbuf.h
@@ -116,19 +116,52 @@ struct mbuf {
0x08 /* when m_free is called on the mbuf, free() \
* it rather than putting it on the free list */
+/* Called by slirp_new */
void m_init(Slirp *);
+
+/* Called by slirp_cleanup */
void m_cleanup(Slirp *slirp);
+
+/* Allocate an mbuf */
struct mbuf *m_get(Slirp *);
+
+/* Release an mbuf (put possibly put it in allocation cache */
void m_free(struct mbuf *);
-void m_cat(register struct mbuf *, register struct mbuf *);
+
+/* Catenate the second buffer to the end of the first buffer, and release the second */
+void m_cat(struct mbuf *, struct mbuf *);
+
+/* Grow the mbuf to the given size */
void m_inc(struct mbuf *, int);
-void m_adj(struct mbuf *, int);
-int m_copy(struct mbuf *, struct mbuf *, int, int);
+
+/* If len is positive, trim that amount from the head of the mbuf. If it is negative, trim it from the tail of the mbuf */
+void m_adj(struct mbuf *, int len);
+
+/* Copy len bytes from the first buffer at the given offset, to the end of the second buffer */
+int m_copy(struct mbuf *, struct mbuf *, int off, int len);
+
+/*
+ * Duplicate the mbuf
+ *
+ * copy_header specifies whether the bytes before m_data should also be copied.
+ * header_size specifies how many bytes are to be reserved before m_data.
+ */
struct mbuf *m_dup(Slirp *slirp, struct mbuf *m, bool copy_header, size_t header_size);
+
+/*
+ * Given a pointer into an mbuf, return the mbuf
+ * XXX This is a kludge, I should eliminate the need for it
+ * Fortunately, it's not used often
+ */
struct mbuf *dtom(Slirp *, void *);
+
+/* Check that the mbuf contains at least len bytes, and return the data */
void *mtod_check(struct mbuf *, size_t len);
+
+/* Return the end of the data of the mbuf */
void *m_end(struct mbuf *);
+/* Initialize the ifs queue of the mbuf */
static inline void ifs_init(struct mbuf *ifm)
{
ifm->ifs_next = ifm->ifs_prev = ifm;
diff --git a/src/misc.h b/src/misc.h
index 81b370c..39fe367 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -51,22 +51,37 @@ struct slirp_quehead {
struct slirp_quehead *qh_rlink;
};
-void slirp_insque(void *, void *);
-void slirp_remque(void *);
+/* Insert element a into queue b */
+void slirp_insque(void *a, void *b);
+
+/* Remove element a from its queue */
+void slirp_remque(void *a);
+
+/* Run the given command in the background, and expose its output as a socket */
int fork_exec(struct socket *so, const char *ex);
+
+/* Create a Unix socket, and expose it as a socket */
int open_unix(struct socket *so, const char *unixsock);
+/* Add a guest forward on the given address and port, with guest data being
+ * forwarded by calling write_cb */
struct gfwd_list *add_guestfwd(struct gfwd_list **ex_ptr, SlirpWriteCb write_cb,
void *opaque, struct in_addr addr, int port);
+/* Run the given command in the backaground, and send its output to the guest on
+ * the given address and port */
struct gfwd_list *add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
struct in_addr addr, int port);
+/* Create a Unix socket, and expose it to the guest on the given address and
+ * port */
struct gfwd_list *add_unix(struct gfwd_list **ex_ptr, const char *unixsock,
struct in_addr addr, int port);
+/* Remove the guest forward bound to the given address and port */
int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port);
+/* Bind the socket to the outbound address specified in the slirp configuration */
int slirp_bind_outbound(struct socket *so, unsigned short af);
#endif
diff --git a/src/sbuf.c b/src/sbuf.c
index b357091..6126baa 100644
--- a/src/sbuf.c
+++ b/src/sbuf.c
@@ -39,12 +39,6 @@ void sbreserve(struct sbuf *sb, size_t size)
sb->sb_datalen = size;
}
-/*
- * Try and write() to the socket, whatever doesn't get written
- * append to the buffer... for a host with a fast net connection,
- * this prevents an unnecessary copy of the data
- * (the socket is non-blocking, so we won't hang)
- */
void sbappend(struct socket *so, struct mbuf *m)
{
int ret = 0;
@@ -138,11 +132,6 @@ static void sbappendsb(struct sbuf *sb, struct mbuf *m)
sb->sb_wptr -= sb->sb_datalen;
}
-/*
- * Copy data from sbuf to a normal, straight buffer
- * Don't update the sbuf rptr, this will be
- * done in sbdrop when the data is acked
- */
void sbcopy(struct sbuf *sb, size_t off, size_t len, char *to)
{
char *from;
diff --git a/src/sbuf.h b/src/sbuf.h
index 01886fb..a3eaf49 100644
--- a/src/sbuf.h
+++ b/src/sbuf.h
@@ -6,6 +6,7 @@
#ifndef SBUF_H
#define SBUF_H
+/* How many bytes are free in the sbuf */
#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc)
struct sbuf {
@@ -18,10 +19,28 @@ struct sbuf {
char *sb_data; /* Actual data */
};
+/* Release the sbuf */
void sbfree(struct sbuf *sb);
+
+/* Drop len bytes from the reading end of the sbuf */
bool sbdrop(struct sbuf *sb, size_t len);
+
+/* (re)Allocate sbuf buffer to store size bytes */
void sbreserve(struct sbuf *sb, size_t size);
+
+/*
+ * Try and write() to the socket, whatever doesn't get written
+ * append to the buffer... for a host with a fast net connection,
+ * this prevents an unnecessary copy of the data
+ * (the socket is non-blocking, so we won't hang)
+ */
void sbappend(struct socket *sb, struct mbuf *mb);
+
+/*
+ * Copy data from sbuf to a normal, straight buffer
+ * Don't update the sbuf rptr, this will be
+ * done in sbdrop when the data is acked
+ */
void sbcopy(struct sbuf *sb, size_t off, size_t len, char *p);
#endif
diff --git a/src/slirp.h b/src/slirp.h
index 1fe7293..8c329be 100644
--- a/src/slirp.h
+++ b/src/slirp.h
@@ -91,9 +91,11 @@ typedef struct ArpTable {
int next_victim;
} ArpTable;
+/* Add a new ARP entry for the given addresses */
void arp_table_add(Slirp *slirp, uint32_t ip_addr,
const uint8_t ethaddr[ETH_ALEN]);
+/* Look for an ARP entry for the given IP address */
bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
uint8_t out_ethaddr[ETH_ALEN]);
@@ -115,11 +117,15 @@ typedef struct NdpTable {
int next_victim;
} NdpTable;
+/* Add a new NDP entry for the given addresses */
void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
uint8_t ethaddr[ETH_ALEN]);
+
+/* Look for an NDP entry for the given IPv6 address */
bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
uint8_t out_ethaddr[ETH_ALEN]);
+/* Slirp configuration, specified by the application */
struct Slirp {
int cfg_version;
@@ -211,81 +217,173 @@ struct Slirp {
bool disable_dns; /* slirp will not redirect/serve any DNS packet */
};
+/*
+ * Send one packet from each session.
+ * If there are packets on the fastq, they are sent FIFO, before
+ * everything else. Then we choose the first packet from each
+ * batchq session (socket) and send it.
+ * For example, if there are 3 ftp sessions fighting for bandwidth,
+ * one packet will be sent from the first session, then one packet
+ * from the second session, then one packet from the third.
+ */
void if_start(Slirp *);
+/* Get the address of the DNS server on the host side */
int get_dns_addr(struct in_addr *pdns_addr);
+
+/* Get the IPv6 address of the DNS server on the host side */
int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
/* ncsi.c */
+
+/* Process NCSI packet coming from the guest */
void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
#ifndef _WIN32
#include <netdb.h>
#endif
-
+/* Whether we should send TCP keepalive packets */
extern bool slirp_do_keepalive;
#define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL)
/* dnssearch.c */
+/* Translate from vdnssearch in configuration, into Slirp */
int translate_dnssearch(Slirp *s, const char **names);
/* cksum.c */
+/* Compute the checksum of the mbuf */
int cksum(struct mbuf *m, int len);
+/* Compute the checksum of the mbuf which contains an IPv6 packet */
int ip6_cksum(struct mbuf *m);
/* if.c */
+/* Called from slirp_new */
void if_init(Slirp *);
+/* Queue packet into an output queue (fast or batch), for sending to the guest */
void if_output(struct socket *, struct mbuf *);
/* ip_input.c */
+/* Called from slirp_new */
void ip_init(Slirp *);
+/* Called from slirp_cleanup */
void ip_cleanup(Slirp *);
+/* Process IPv4 packet coming from the guest */
void ip_input(struct mbuf *);
+/*
+ * IP timer processing;
+ * if a timer expires on a reassembly
+ * queue, discard it.
+ */
void ip_slowtimo(Slirp *);
+/*
+ * Strip out IP options, at higher
+ * level protocol in the kernel.
+ * Second argument is buffer to which options
+ * will be moved, and return value is their length.
+ * (XXX) should be deleted; last arg currently ignored.
+ */
void ip_stripoptions(register struct mbuf *, struct mbuf *);
/* ip_output.c */
+/* Send IPv4 packet to the guest */
int ip_output(struct socket *, struct mbuf *);
/* ip6_input.c */
+/* Called from slirp_new, but after other initialization */
void ip6_post_init(Slirp *);
+/* Called from slirp_cleanup */
void ip6_cleanup(Slirp *);
+/* Process IPv6 packet coming from the guest */
void ip6_input(struct mbuf *);
/* ip6_output */
+/* Send IPv6 packet to the guest */
int ip6_output(struct socket *, struct mbuf *, int fast);
/* tcp_input.c */
+/* Process TCP datagram coming from the guest */
void tcp_input(register struct mbuf *, int, struct socket *, unsigned short af);
-int tcp_mss(register struct tcpcb *, unsigned);
+/* Determine a reasonable value for maxseg size */
+int tcp_mss(register struct tcpcb *, unsigned offer);
/* tcp_output.c */
+/* Send TCP datagram to the guest */
int tcp_output(register struct tcpcb *);
+/* Start/restart persistence timer */
void tcp_setpersist(register struct tcpcb *);
/* tcp_subr.c */
+/* Called from slirp_new */
void tcp_init(Slirp *);
+/* Called from slirp_cleanup */
void tcp_cleanup(Slirp *);
+/*
+ * Create template to be used to send tcp packets on a connection.
+ * Call after host entry created, fills
+ * in a skeletal tcp/ip header, minimizing the amount of work
+ * necessary when the connection is used.
+ */
void tcp_template(struct tcpcb *);
+/*
+ * Send a single message to the TCP at address specified by
+ * the given TCP/IP header.
+ */
void tcp_respond(struct tcpcb *, register struct tcpiphdr *,
register struct mbuf *, tcp_seq, tcp_seq, int, unsigned short);
+/*
+ * Create a new TCP control block, making an
+ * empty reassembly queue and hooking it to the argument
+ * protocol control block.
+ */
struct tcpcb *tcp_newtcpcb(struct socket *);
+/*
+ * Close a TCP control block:
+ * discard all space held by the tcp
+ * discard internet protocol block
+ * wake up any sleepers
+ */
struct tcpcb *tcp_close(register struct tcpcb *);
+/* The Internet socket got closed, tell the guest */
void tcp_sockclosed(struct tcpcb *);
+/*
+ * Connect to a host on the Internet
+ * Called by tcp_input
+ */
int tcp_fconnect(struct socket *, unsigned short af);
+/* Accept the connection from the Internet, and connect to the guest */
void tcp_connect(struct socket *);
+/* Attach a TCPCB to a socket */
void tcp_attach(struct socket *);
+/* * Return TOS according to the ports */
uint8_t tcp_tos(struct socket *);
+/*
+ * We received a packet from the guest.
+ *
+ * Emulate programs that try and connect to us
+ * This includes ftp (the data connection is
+ * initiated by the server) and IRC (DCC CHAT and
+ * DCC SEND) for now
+ */
int tcp_emu(struct socket *, struct mbuf *);
+/* Configure the socket, now that the guest completed accepting the connection */
int tcp_ctl(struct socket *);
+/*
+ * Drop a TCP connection, reporting
+ * the specified error. If connection is synchronized,
+ * then send a RST to peer.
+ */
struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
+/* Find the socket for the guest address and port */
struct socket *slirp_find_ctl_socket(Slirp *slirp, struct in_addr guest_addr,
int guest_port);
+/* Send a frame to the virtual Ethernet board, i.e. call the application send_packet callback */
void slirp_send_packet_all(Slirp *slirp, const void *buf, size_t len);
+
+/* Create a new timer, i.e. call the application timer_new callback */
void *slirp_timer_new(Slirp *slirp, SlirpTimerId id, void *cb_opaque);
#endif
diff --git a/src/socket.c b/src/socket.c
index fb9c019..ce716a9 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -769,10 +769,6 @@ int sosendto(struct socket *so, struct mbuf *m)
return 0;
}
-/*
- * Listen for incoming TCP connections
- * On failure errno contains the reason.
- */
struct socket *tcpx_listen(Slirp *slirp,
const struct sockaddr *haddr, socklen_t haddrlen,
const struct sockaddr *laddr, socklen_t laddrlen,
@@ -939,10 +935,6 @@ static void sofcantsendmore(struct socket *so)
}
}
-/*
- * Set write drain mode
- * Set CANTSENDMORE once all data has been write()n
- */
void sofwdrain(struct socket *so)
{
if (so->so_rcv.sb_cc)
@@ -993,9 +985,6 @@ static bool sotranslate_out6(Slirp *s, struct socket *so, struct sockaddr_in6 *s
}
-/*
- * Translate addr in host addr when it is a virtual address
- */
int sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
{
bool ok = true;
@@ -1053,9 +1042,6 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
}
}
-/*
- * Translate connections from localhost to the real hostname
- */
void sotranslate_accept(struct socket *so)
{
Slirp *slirp = so->slirp;
diff --git a/src/socket.h b/src/socket.h
index ca8c103..27d3b8a 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -117,6 +117,7 @@ struct socket {
0x2000 /* Connection was initiated by a host on the internet */
#define SS_HOSTFWD_V6ONLY 0x4000 /* Only bind on v6 addresses */
+/* Check that two addresses are equal */
static inline int sockaddr_equal(const struct sockaddr_storage *a,
const struct sockaddr_storage *b)
{
@@ -151,6 +152,7 @@ static inline int sockaddr_equal(const struct sockaddr_storage *a,
return 0;
}
+/* Get the size of an address */
static inline socklen_t sockaddr_size(const struct sockaddr_storage *a)
{
switch (a->ss_family) {
@@ -167,6 +169,7 @@ static inline socklen_t sockaddr_size(const struct sockaddr_storage *a)
}
}
+/* Copy an address */
static inline void sockaddr_copy(struct sockaddr *dst, socklen_t dstlen, const struct sockaddr *src, socklen_t srclen)
{
socklen_t len = sockaddr_size((const struct sockaddr_storage *) src);
@@ -175,32 +178,59 @@ static inline void sockaddr_copy(struct sockaddr *dst, socklen_t dstlen, const s
memcpy(dst, src, len);
}
-struct socket *solookup(struct socket **, struct socket *,
- struct sockaddr_storage *, struct sockaddr_storage *);
+/* Find the socket corresponding to lhost & fhost, trying last as a guess */
+struct socket *solookup(struct socket **last, struct socket *head,
+ struct sockaddr_storage *lhost, struct sockaddr_storage *fhost);
+/* Create a new socket */
struct socket *socreate(Slirp *, int);
+/* Release a socket */
void sofree(struct socket *);
+/* Receive the available data from the Internet socket and queue it on the sb */
int soread(struct socket *);
+/* Receive the available OOB data from the Internet socket and try to send it immediately */
int sorecvoob(struct socket *);
+/* Send OOB data to the Internet socket */
int sosendoob(struct socket *);
+/* Send data to the Internet socket */
int sowrite(struct socket *);
+/* Receive the available data from the Internet UDP socket, and send it to the guest */
void sorecvfrom(struct socket *);
+/* Send data to the Internet UDP socket */
int sosendto(struct socket *, struct mbuf *);
-struct socket *tcp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int);
+/* Listen for incoming TCPv4 connections on this haddr+hport */
+struct socket *tcp_listen(Slirp *, uint32_t haddr, unsigned hport, uint32_t laddr, unsigned lport, int flags);
+/*
+ * Listen for incoming TCP connections on this haddr
+ * On failure errno contains the reason.
+ */
struct socket *tcpx_listen(Slirp *slirp,
const struct sockaddr *haddr, socklen_t haddrlen,
const struct sockaddr *laddr, socklen_t laddrlen,
int flags);
+/* Note that the socket is connecting */
void soisfconnecting(register struct socket *);
+/* Note that the socket is connected */
void soisfconnected(register struct socket *);
+/*
+ * Set write drain mode
+ * Set CANTSENDMORE once all data has been write()n
+ */
void sofwdrain(struct socket *);
struct iovec; /* For win32 */
+/* Prepare iov for storing into the sb */
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np);
+/* Get data from the buffer and queue it on the sb */
int soreadbuf(struct socket *so, const char *buf, int size);
+/* Translate addr into host addr when it is a virtual address, before sending to the Internet */
int sotranslate_out(struct socket *, struct sockaddr_storage *);
+/* Translate addr into virtual address when it is host, before sending to the guest */
void sotranslate_in(struct socket *, struct sockaddr_storage *);
+/* Translate connections from localhost to the real hostname */
void sotranslate_accept(struct socket *);
+/* Drop num bytes from the reading end of the socket */
void sodrop(struct socket *, int num);
+/* Forwarding a connection to the guest, try to find the guest address to use, fill lhost with it */
int soassign_guest_addr_if_needed(struct socket *so);
#endif /* SLIRP_SOCKET_H */
diff --git a/src/stream.h b/src/stream.h
index 08bb5b6..4cdc236 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -14,22 +14,34 @@ typedef struct SlirpOStream {
void *opaque;
} SlirpOStream;
+/* Read exactly size bytes from stream, return 1 if all ok, 0 otherwise */
bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size);
+/* Write exactly size bytes to stream, return 1 if all ok, 0 otherwise */
bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size);
+/* Read exactly one byte from stream, return it, otherwise return 0 */
uint8_t slirp_istream_read_u8(SlirpIStream *f);
+/* Write exactly one byte to stream, return 1 if all ok, 0 otherwise */
bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b);
+/* Read exactly two bytes from big-endian stream, return it, otherwise return 0 */
uint16_t slirp_istream_read_u16(SlirpIStream *f);
+/* Write exactly two bytes to big-endian stream, return 1 if all ok, 0 otherwise */
bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b);
+/* Read exactly four bytes from big-endian stream, return it, otherwise return 0 */
uint32_t slirp_istream_read_u32(SlirpIStream *f);
+/* Write exactly four bytes to big-endian stream, return 1 if all ok, 0 otherwise */
bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b);
+/* Read exactly two bytes from big-endian stream (signed), return it, otherwise return 0 */
int16_t slirp_istream_read_i16(SlirpIStream *f);
+/* Write exactly two bytes to big-endian stream (signed), return 1 if all ok, 0 otherwise */
bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b);
+/* Read exactly four bytes from big-endian stream (signed), return it, otherwise return 0 */
int32_t slirp_istream_read_i32(SlirpIStream *f);
+/* Write exactly four bytes to big-endian stream (signed), return 1 if all ok, 0 otherwise */
bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b);
#endif /* STREAM_H_ */
diff --git a/src/tcp_output.c b/src/tcp_output.c
index 383fe31..77c1204 100644
--- a/src/tcp_output.c
+++ b/src/tcp_output.c
@@ -506,9 +506,6 @@ void tcp_setpersist(struct tcpcb *tp)
{
int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
- /*
- * Start/restart persistence timer.
- */
TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], t * tcp_backoff[tp->t_rxtshift],
TCPTV_PERSMIN, TCPTV_PERSMAX);
if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
diff --git a/src/tcp_subr.c b/src/tcp_subr.c
index 1276086..3cfe286 100644
--- a/src/tcp_subr.c
+++ b/src/tcp_subr.c
@@ -59,12 +59,6 @@ void tcp_cleanup(Slirp *slirp)
}
}
-/*
- * Create template to be used to send tcp packets on a connection.
- * Call after host entry created, fills
- * in a skeletal tcp/ip header, minimizing the amount of work
- * necessary when the connection is used.
- */
void tcp_template(struct tcpcb *tp)
{
struct socket *so = tp->t_socket;
@@ -246,11 +240,6 @@ void tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
}
}
-/*
- * Create a new TCP control block, making an
- * empty reassembly queue and hooking it to the argument
- * protocol control block.
- */
struct tcpcb *tcp_newtcpcb(struct socket *so)
{
register struct tcpcb *tp;
@@ -290,11 +279,6 @@ struct tcpcb *tcp_newtcpcb(struct socket *so)
return (tp);
}
-/*
- * Drop a TCP connection, reporting
- * the specified error. If connection is synchronized,
- * then send a RST to peer.
- */
struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
{
DEBUG_CALL("tcp_drop");
@@ -308,12 +292,6 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
return (tcp_close(tp));
}
-/*
- * Close a TCP control block:
- * discard all space held by the tcp
- * discard internet protocol block
- * wake up any sleepers
- */
struct tcpcb *tcp_close(struct tcpcb *tp)
{
register struct tcpiphdr *t;
@@ -389,8 +367,6 @@ void tcp_sockclosed(struct tcpcb *tp)
}
/*
- * Connect to a host on the Internet
- * Called by tcp_input
* Only do a connect, the tcp fields will be set in tcp_input
* return 0 if there's a result of the connect,
* else return -1 means we're still connecting
@@ -448,8 +424,6 @@ int tcp_fconnect(struct socket *so, unsigned short af)
}
/*
- * Accept the socket and connect to the local-host
- *
* We have a problem. The correct thing to do would be
* to first connect to the local-host, and only if the
* connection is accepted, then do an accept() here.
@@ -571,9 +545,6 @@ void tcp_connect(struct socket *inso)
tcp_output(tp);
}
-/*
- * Attach a TCPCB to a socket.
- */
void tcp_attach(struct socket *so)
{
so->so_tcpcb = tcp_newtcpcb(so);
@@ -598,9 +569,6 @@ static const struct tos_t tcptos[] = {
{ 0, 0, 0, 0 }
};
-/*
- * Return TOS according to the above table
- */
uint8_t tcp_tos(struct socket *so)
{
int i = 0;
@@ -618,11 +586,6 @@ uint8_t tcp_tos(struct socket *so)
}
/*
- * Emulate programs that try and connect to us
- * This includes ftp (the data connection is
- * initiated by the server) and IRC (DCC CHAT and
- * DCC SEND) for now
- *
* NOTE: It's possible to crash SLiRP by sending it
* unstandard strings to emulate... if this is a problem,
* more checks are needed here
diff --git a/src/tcp_timer.c b/src/tcp_timer.c
index bc4db2d..aeb610f 100644
--- a/src/tcp_timer.c
+++ b/src/tcp_timer.c
@@ -98,9 +98,6 @@ void tcp_slowtimo(Slirp *slirp)
slirp->tcp_now++; /* for timestamps */
}
-/*
- * Cancel all timers for TCP tp.
- */
void tcp_canceltimers(struct tcpcb *tp)
{
register int i;
diff --git a/src/tcp_timer.h b/src/tcp_timer.h
index 584a559..3a2e944 100644
--- a/src/tcp_timer.h
+++ b/src/tcp_timer.h
@@ -123,8 +123,11 @@ extern const int tcp_backoff[];
struct tcpcb;
+/* Process fast time-outs */
void tcp_fasttimo(Slirp *);
+/* Process slow time-outs */
void tcp_slowtimo(Slirp *);
+/* Cancel all timers for TCP tp */
void tcp_canceltimers(struct tcpcb *);
#endif
diff --git a/src/tftp.h b/src/tftp.h
index ccbe208..83cc903 100644
--- a/src/tftp.h
+++ b/src/tftp.h
@@ -55,6 +55,7 @@ struct tftp_session {
int timestamp;
};
+/* Process TFTP packet coming from the guest */
void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m);
#endif
diff --git a/src/udp.h b/src/udp.h
index 3883e87..b0514f1 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -75,20 +75,31 @@ struct udpiphdr {
struct mbuf;
+/* Called from slirp_init */
void udp_init(Slirp *);
+/* Called from slirp_cleanup */
void udp_cleanup(Slirp *);
+/* Process UDP datagram coming from the guest */
void udp_input(register struct mbuf *, int);
+/* Create a host UDP socket, bound to this socket */
int udp_attach(struct socket *, unsigned short af);
+/* Destroy socket */
void udp_detach(struct socket *);
-struct socket *udp_listen(Slirp *, uint32_t, unsigned, uint32_t, unsigned, int);
+
+/* Listen for incoming UDP datagrams on this haddr+hport */
+struct socket *udp_listen(Slirp *, uint32_t haddr, unsigned hport, uint32_t laddr, unsigned lport, int flags);
+/* Listen for incoming UDP datagrams on this haddr */
struct socket *udpx_listen(Slirp *,
const struct sockaddr *haddr, socklen_t haddrlen,
const struct sockaddr *laddr, socklen_t laddrlen,
int flags);
+/* Send UDP datagram to the guest */
int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr,
struct sockaddr_in *daddr, int iptos);
+/* Process UDPv6 datagram coming from the guest */
void udp6_input(register struct mbuf *);
+/* Send UDPv6 datagram to the guest */
int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr,
struct sockaddr_in6 *daddr);