aboutsummaryrefslogtreecommitdiffstats
path: root/slirp-android
diff options
context:
space:
mode:
authorrich cannings <richc@google.com>2011-02-16 13:43:44 -0800
committerrich cannings <richc@google.com>2011-02-16 16:18:33 -0800
commit7339b55944e97077e4f74c4be34cd956ae44198b (patch)
treefa4d61112a5144ac4932e90693b2b0b281787d69 /slirp-android
parentbdedc85ca0c7ae3dcb9771595d196e6f533f4492 (diff)
downloadexternal_qemu-7339b55944e97077e4f74c4be34cd956ae44198b.zip
external_qemu-7339b55944e97077e4f74c4be34cd956ae44198b.tar.gz
external_qemu-7339b55944e97077e4f74c4be34cd956ae44198b.tar.bz2
Add user mode networking restrictions: a firewall
Command line options added and code is supported for: QEMU_OPTION_drop_udp QEMU_OPTION_drop_tcp QEMU_OPTION_allow_tcp QEMU_OPTION_drop_log QEMU_OPTION_net_forward QEMU_OPTION_max_dns_conns QEMU_OPTION_allow_udp QEMU_OPTION_dns_log Also, this change makes the default max DNS connections unlimited. Change-Id: I887213149956dda155ef514418365bd80d8f1236
Diffstat (limited to 'slirp-android')
-rw-r--r--slirp-android/libslirp.h57
-rw-r--r--slirp-android/slirp.c300
-rw-r--r--slirp-android/socket.c21
-rw-r--r--slirp-android/tcp_subr.c169
-rw-r--r--slirp-android/udp.c51
-rw-r--r--slirp-android/udp.h4
6 files changed, 568 insertions, 34 deletions
diff --git a/slirp-android/libslirp.h b/slirp-android/libslirp.h
index 6086384..120e3d3 100644
--- a/slirp-android/libslirp.h
+++ b/slirp-android/libslirp.h
@@ -2,7 +2,9 @@
#define _LIBSLIRP_H
#include <stdint.h>
+#include <stdio.h>
#include "sockets.h"
+#include "slirp.h"
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# define socket_close winsock2_socket_close3
@@ -16,6 +18,8 @@
extern "C" {
#endif
+struct mbuf;
+
int inet_strtoip(const char* str, uint32_t *ip);
char* inet_iptostr(uint32_t ip);
@@ -32,6 +36,59 @@ void slirp_input(const uint8_t *pkt, int pkt_len);
int slirp_can_output(void);
void slirp_output(const uint8_t *pkt, int pkt_len);
+/* ---------------------------------------------------*/
+/* User mode network stack restrictions */
+void slirp_drop_udp();
+void slirp_drop_tcp();
+void slirp_add_allow(unsigned long dst_addr, int dst_lport,
+ int dst_hport, u_int8_t proto);
+void slirp_drop_log_fd(FILE* fd);
+int slirp_should_drop(unsigned long dst_addr,
+ int dst_port,
+ u_int8_t proto);
+int slirp_drop_log(const char* format, ...);
+
+/* for network forwards */
+void slirp_add_net_forward(unsigned long dest_ip, unsigned long dest_mask,
+ int dest_lport, int dest_hport,
+ unsigned long redirect_ip, int redirect_port);
+
+int slirp_should_net_forward(unsigned long remote_ip, int remote_port,
+ unsigned long *redirect_ip, int *redirect_port);
+/* ---------------------------------------------------*/
+
+/**
+ * Additional network stack modifications, aiming to detect and log
+ * any network activity initiated by any binary outisde the context of
+ * the running browser.
+ */
+
+void slirp_dns_log_fd(FILE* fd);
+/** Logs the DNS name in DNS query issued by the VM. */
+int slirp_log_dns(struct mbuf* m, int dropped);
+/** IP packet dump of DNS queris and responses. */
+int slirp_dump_dns(struct mbuf* m);
+/** Sets an upper limit for the number of allowed DNS requests from
+ * the VM.
+ */
+void slirp_set_max_dns_conns(int max_dns_conns);
+/* Returns the max number of allowed DNS requests.*/
+int slirp_get_max_dns_conns();
+
+/**
+ * Modifications for implementing "-net-forward-tcp2sink' option.
+ */
+
+void slirp_forward_dropped_tcp2sink(unsigned long sink_ip, int sink_port);
+int slirp_should_forward_dropped_tcp2sink();
+unsigned long slirp_get_tcp_sink_ip();
+int slirp_get_tcp_sink_port();
+
+
+
+
+/* ---------------------------------------------------*/
+
void slirp_redir_loop(void (*func)(void *opaque, int is_udp,
const SockAddress *laddr,
const SockAddress *faddr),
diff --git a/slirp-android/slirp.c b/slirp-android/slirp.c
index e3c4c42..683bef5 100644
--- a/slirp-android/slirp.c
+++ b/slirp-android/slirp.c
@@ -32,6 +32,12 @@
#include "android/android.h"
#include "sockets.h"
+#include <sys/queue.h>
+
+/* proto types */
+static void slirp_net_forward_init(void);
+
+
#define D(...) VERBOSE_PRINT(slirp,__VA_ARGS__)
#define DN(...) do { if (VERBOSE_CHECK(slirp)) dprintn(__VA_ARGS__); } while (0)
@@ -259,6 +265,8 @@ void slirp_init(int restricted, const char *special_ip)
alias_addr_ip = special_addr_ip | CTL_ALIAS;
getouraddr();
register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
+
+ slirp_net_forward_init();
}
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
@@ -819,6 +827,298 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
}
}
+
+/*---------------------------------------------------*/
+/* User mode network stack restrictions */
+struct fw_allow_entry {
+ struct fw_allow_entry* next;
+ unsigned long dst_addr; /* host byte order */
+ /* Allowed port range. dst_lport should be the same as dst_hport for a
+ * single port. */
+ unsigned short dst_lport; /* host byte order */
+ unsigned short dst_hport; /* host byte order */
+};
+
+static int drop_udp = 0;
+static int drop_tcp = 0;
+static struct fw_allow_entry* allow_tcp_entries = NULL;
+static struct fw_allow_entry* allow_udp_entries = NULL;
+static FILE* drop_log_fd = NULL;
+static FILE* dns_log_fd = NULL;
+static int max_dns_conns = -1; /* unlimited max DNS connections by default */
+static int slirp_net_forward_inited = 0;
+
+void slirp_drop_udp() {
+ drop_udp = 1;
+}
+
+void slirp_drop_tcp() {
+ drop_tcp = 1;
+}
+
+/* TCP traffic forwarding to a sink - If enabled, all TCP traffic to any
+ * ip/port that is not explicitly forwared using '-net-forward', and which would
+ * otherwise be dropped if '-drop-tcp' has been specified, is redirected to the
+ * specified ip:port
+ */
+int forward_dropped_tcp2sink = 0;
+static unsigned long tcp_sink_ip;
+int tcp_sink_port;
+
+void slirp_forward_dropped_tcp2sink(unsigned long sink_ip, int sink_port) {
+ tcp_sink_ip = sink_ip;
+ tcp_sink_port = sink_port;
+ forward_dropped_tcp2sink = 1;
+}
+
+int slirp_should_forward_dropped_tcp2sink() {
+ return forward_dropped_tcp2sink;
+}
+
+unsigned long slirp_get_tcp_sink_ip() {
+ return tcp_sink_ip;
+}
+int slirp_get_tcp_sink_port() {
+ return tcp_sink_port;
+}
+
+/* Fill in the firewall rules. dst_lport and dst_hport are in host byte order */
+void slirp_add_allow(unsigned long dst_addr,
+ int dst_lport, int dst_hport,
+ u_int8_t proto) {
+
+ struct fw_allow_entry** ate;
+ switch (proto) {
+ case IPPROTO_TCP:
+ ate = &allow_tcp_entries;
+ break;
+ case IPPROTO_UDP:
+ ate = &allow_udp_entries;
+ break;
+ default:
+ return; // unknown protocol for the FW
+ }
+
+ while(*ate != NULL)
+ ate = &(*ate)->next;
+
+ *ate = malloc(sizeof(**ate));
+ if (*ate == NULL) {
+ DEBUG_MISC((dfd,
+ "Unable to create new firewall record, malloc failed\n"));
+ exit(-1);
+ }
+
+ (*ate)->next = NULL;
+ (*ate)->dst_addr = dst_addr;
+ (*ate)->dst_lport = dst_lport;
+ (*ate)->dst_hport = dst_hport;
+}
+
+void slirp_drop_log_fd(FILE* fd) {
+ drop_log_fd = fd;
+}
+
+void slirp_dns_log_fd(FILE* fd) {
+ dns_log_fd = fd;
+}
+
+/* Address and ports are in host byte order */
+int slirp_should_drop(unsigned long dst_addr,
+ int dst_port,
+ u_int8_t proto) {
+
+ struct fw_allow_entry* ate;
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ if (drop_tcp != 0)
+ ate = allow_tcp_entries;
+ else
+ return 0;
+ break;
+ case IPPROTO_UDP:
+ if (drop_udp != 0)
+ ate = allow_udp_entries;
+ else
+ return 0;
+ break;
+ default:
+ return 1; // unknown protocol for the FW
+ }
+
+ while(ate) {
+ if ((ate->dst_lport <= dst_port) && (dst_port <= ate->dst_hport)) {
+ // allow any destination if 0
+ if (ate->dst_addr == 0 || ate->dst_addr == dst_addr)
+ return 0;
+ }
+ ate = ate->next;
+ }
+
+ return 1;
+}
+
+/*
+ * log DNS requests in a separate log
+ */
+int
+slirp_log_dns(struct mbuf* m, int dropped) {
+ char dns_query[256]; // max allowable dns name size
+ int c = 0;
+ int i= 0;
+ int index = 0;
+ int offset = 40 + 1; // udp/ip headers length + 1;
+ int trim_bytes = 4;
+
+ if (!dns_log_fd)
+ return -1;
+
+ /* We assume one DNS name per query: 300 = 255 (max dns name length)
+ * + 40 (udp/ip hdr) + 1 byte DNS peamble + 4 bytes DNS suffix
+ */
+ if (m->m_len < offset || m->m_len > 300) {
+ DEBUG_MISC((dfd,"Malformed DNS qeury, length %d \n", (int)m->m_len));
+ return -1;
+ }
+ for (i = offset; i < m->m_len - trim_bytes && index < sizeof(dns_query); i++, index++) {
+ c = m->m_data[i];
+ if (c < ' ' || c > '~')
+ c = '.';
+
+ dns_query[index] = (char)c;
+ }
+ dns_query[index] = '\0';
+ if (!dropped) {
+ fprintf(dns_log_fd, "Sent DNS query for, %s\n" , dns_query);
+ } else {
+ fprintf(dns_log_fd, "Dropped DNS query for, %s\n" , dns_query);
+ }
+ fflush(dns_log_fd);
+ return 1;
+}
+
+/*
+ * log DNS requests in a separate log
+ */
+int
+slirp_dump_dns(struct mbuf* m) {
+
+ if (!dns_log_fd)
+ return 0;
+ // first we write the length of the record then the record (IP packet)
+ if (!fwrite(&(m->m_len), sizeof(int), 1, dns_log_fd) ||
+ !fwrite(m->m_data, m->m_len, 1, dns_log_fd)) {
+ return 0;
+ }
+
+ fflush(dns_log_fd);
+ return 1;
+}
+
+/* Log dropped/accepted packet info */
+int slirp_drop_log(const char* format, ...) {
+ va_list args;
+
+ if (!drop_log_fd)
+ return 0;
+
+ va_start(args, format);
+ vfprintf(drop_log_fd, format, args);
+ va_end(args);
+
+ fflush(drop_log_fd);
+
+ return 1;
+}
+
+
+/* Set max DNS requests allowed to be issued from the VM */
+void slirp_set_max_dns_conns(int num_conns) {
+ max_dns_conns = num_conns;
+}
+
+int slirp_get_max_dns_conns() {
+ return max_dns_conns;
+}
+
+/* generic guest network redirection functionality for ipv4 */
+struct net_forward_entry {
+ QTAILQ_ENTRY(net_forward_entry) next;
+ /* ip addresses are also in host byte order */
+ unsigned long dest_ip; /* the destination address they try to contact */
+ unsigned long dest_mask; /* the mask to apply to the address for matching */
+ /* Range of ports they were trying to contact. In case of a single port,
+ * dest_lport should be the same as dest_hport */
+ int dest_lport; /* Host byte order */
+ int dest_hport; /* Host byte order */
+
+ unsigned long redirect_ip;
+ int redirect_port; /* Host byte order */
+};
+
+static QTAILQ_HEAD(net_forwardq, net_forward_entry) net_forwards;
+
+static void slirp_net_forward_init(void)
+{
+ if (!slirp_net_forward_inited) {
+ QTAILQ_INIT(&net_forwards);
+ slirp_net_forward_inited = 1;
+ }
+}
+
+/* all addresses and ports ae in host byte order */
+void slirp_add_net_forward(unsigned long dest_ip, unsigned long dest_mask,
+ int dest_lport, int dest_hport,
+ unsigned long redirect_ip, int redirect_port)
+{
+ slirp_net_forward_init();
+
+ struct net_forward_entry *entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ DEBUG_MISC((dfd, "Unable to create new forwarding entry, malloc failed\n"));
+ exit(-1);
+ }
+
+ entry->dest_ip = dest_ip;
+ entry->dest_mask = dest_mask;
+ entry->dest_lport = dest_lport;
+ entry->dest_hport = dest_hport;
+ entry->redirect_ip = redirect_ip;
+ entry->redirect_port = redirect_port;
+
+ QTAILQ_INSERT_TAIL(&net_forwards, entry, next);
+}
+
+/* remote_port and redir_port arguments
+ * are in network byte order (tcp_subr.c) */
+int slirp_should_net_forward(unsigned long remote_ip, int remote_port,
+ unsigned long *redirect_ip, int *redirect_port)
+{
+ struct net_forward_entry *entry;
+
+ for (entry = net_forwards.tqh_first;
+ entry != NULL; entry = entry->next.tqe_next) {
+
+ if ((entry->dest_lport <= remote_port)
+ && (remote_port <= entry->dest_hport)) {
+ if ((entry->dest_ip & entry->dest_mask)
+ == (remote_ip & entry->dest_mask)) {
+ *redirect_ip = entry->redirect_ip;
+ *redirect_port = entry->redirect_port;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*---------------------------------------------------*/
+
+
+
+
static void _slirp_redir_loop(void (*func)(void *opaque, int is_udp,
const SockAddress *laddr,
const SockAddress *faddr),
diff --git a/slirp-android/socket.c b/slirp-android/socket.c
index 44640a8..285a8ef 100644
--- a/slirp-android/socket.c
+++ b/slirp-android/socket.c
@@ -570,6 +570,26 @@ sosendto(struct socket *so, struct mbuf *m)
addr_port = so->so_faddr_port;
+ /*
+ * test for generic forwarding; this function replaces the arguments
+ * only on success
+ */
+ unsigned long faddr = addr_ip;
+ int fport = addr_port;
+
+ if (slirp_should_net_forward(faddr, fport, &faddr, &fport)) {
+ slirp_drop_log(
+ "Redirected UDP: src: 0x%08lx:0x%04x org dst: 0x%08lx:0x%04x "
+ "new dst: 0x%08lx:0x%04x\n",
+ so->so_laddr_ip, so->so_laddr_port,
+ addr_ip, addr_port,
+ faddr, fport
+ );
+ }
+ addr_ip = faddr;
+ addr_port = fport;
+
+
sock_address_init_inet(&addr, addr_ip, addr_port);
DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%08x\n", addr_port, addr_ip));
@@ -779,4 +799,3 @@ sofwdrain(struct socket *so)
else
sofcantsendmore(so);
}
-
diff --git a/slirp-android/tcp_subr.c b/slirp-android/tcp_subr.c
index b8b680c..0550d4b 100644
--- a/slirp-android/tcp_subr.c
+++ b/slirp-android/tcp_subr.c
@@ -377,6 +377,29 @@ tcp_proxy_event( struct socket* so,
tcp_input(NULL, sizeof(struct ip), so);
}
+
+/* Tests if an IP address corresponds to a special Qemu service (eg, the DNS
+ * server or the gateway - see ctl.h) and if so, rewrites it with the real
+ * address of the service.
+ */
+int is_qemu_special_address(unsigned long dst_addr, unsigned long *redir_addr)
+{
+ if ((dst_addr & htonl(0xffffff00)) == special_addr_ip) {
+ /* It's an alias */
+
+ int last_byte = dst_addr & 0xff;
+
+ if (CTL_IS_DNS(last_byte))
+ *redir_addr = dns_addr[last_byte - CTL_DNS];
+ else
+ *redir_addr = loopback_addr_ip;
+
+ return 1;
+ }
+ return 0;
+}
+
+
/*
* Connect to a host on the Internet
* Called by tcp_input
@@ -390,41 +413,56 @@ tcp_proxy_event( struct socket* so,
int tcp_fconnect(struct socket *so)
{
int ret=0;
- int try_proxy = 1;
SockAddress sockaddr;
- uint32_t sock_ip;
- uint16_t sock_port;
+ unsigned long sock_ip;
+ int sock_port;
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %lx", (long )so);
- sock_ip = so->so_faddr_ip;
- sock_port = so->so_faddr_port;
-
- if ((sock_ip & 0xffffff00) == special_addr_ip) {
- /* It's an alias */
- int last_byte = sock_ip & 0xff;
-
- if (CTL_IS_DNS(last_byte))
- sock_ip = dns_addr[last_byte - CTL_DNS];
- else
- sock_ip = loopback_addr_ip;
- try_proxy = 0;
- }
-
- sock_address_init_inet( &sockaddr, sock_ip, sock_port );
-
- DEBUG_MISC((dfd, " connect()ing, addr=%s, proxy=%d\n",
- sock_address_to_string(&sockaddr), try_proxy));
-
- if (try_proxy) {
- if (!proxy_manager_add(&sockaddr, SOCKET_STREAM, (ProxyEventFunc) tcp_proxy_event, so)) {
- soisfconnecting(so);
- so->s = -1;
- so->so_state |= SS_PROXIFIED;
- return 0;
- }
+ /* when true, a connection that otherwise would be dropped will instead be
+ * redirected to the sink ('-net-forward-tcp2sink') */
+ int forward_dropped_to_sink = 0;
+
+
+ /*-------------------------------------------------------------*/
+ /* User mode network stack restrictions */
+ if (slirp_should_drop(so->so_faddr_ip, so->so_faddr_port, IPPROTO_TCP)) {
+
+ /* If forwarding to sink is enabled, don't actually drop it */
+ if (slirp_should_forward_dropped_tcp2sink()) {
+ slirp_drop_log(
+ "About to be dropped TCP forwarded to sink: "
+ "src: 0x%08lx:0x%04x dst: 0x%08lx:0x%04x\n",
+ so->so_laddr_ip,
+ so->so_laddr_port,
+ so->so_faddr_ip,
+ so->so_faddr_port
+ );
+ forward_dropped_to_sink = 1;
+ }
+ else {
+ slirp_drop_log(
+ "Dropped TCP: src: 0x%08lx:0x%04x dst: 0x%08lx:0x%04x\n",
+ so->so_laddr_ip,
+ so->so_laddr_port,
+ so->so_faddr_ip,
+ so->so_faddr_port
+ );
+ //errno = ENETUNREACH;
+ errno = ECONNREFUSED;
+ return -1;
+ }
+ } else {
+ slirp_drop_log(
+ "Allowed TCP: src: 0x%08lx:0x%04x dst: 0x%08lx:0x%04x\n",
+ so->so_laddr_ip,
+ so->so_laddr_port,
+ so->so_faddr_ip,
+ so->so_faddr_port
+ );
}
+ /*-------------------------------------------------------------*/
if ((ret=so->s=socket_create_inet(SOCKET_STREAM)) >= 0)
{
@@ -434,6 +472,79 @@ int tcp_fconnect(struct socket *so)
socket_set_xreuseaddr(s);
socket_set_oobinline(s);
+
+ if (forward_dropped_to_sink) {
+
+ /* This connection would normally be dropped, but since forwarding of
+ * dropped connections is enabled, redirect it to the sink */
+ sock_ip = slirp_get_tcp_sink_ip();
+ sock_port= slirp_get_tcp_sink_port();
+ slirp_drop_log(
+ "Redirected would-be dropped TCP to sink: "
+ "src: 0x%08lx:0x%04x org dst: 0x%08lx:0x%04x "
+ "new dst: 0x%08lx:0x%04x\n",
+ so->so_laddr_ip, so->so_laddr_port,
+ so->so_faddr_ip, so->so_faddr_port,
+ sock_ip, sock_port
+ );
+ }
+ else { /* An allowed connection */
+
+ unsigned long faddr;
+ int fport;
+
+ /* Determine if the connection should be redirected
+ * due to a -net-forward rule */
+ /* faddr and fport are modified only on success */
+ if (slirp_should_net_forward(so->so_faddr_ip, so->so_faddr_port,
+ &faddr, &fport)) {
+ slirp_drop_log(
+ "Redirected TCP: src: 0x%08lx:0x%04x org dst: 0x%08lx:0x%04x "
+ "new dst: 0x%08lx:0x%04x\n",
+ so->so_laddr_ip, so->so_laddr_port,
+ so->so_faddr_ip, so->so_faddr_port,
+ faddr, fport
+ );
+ sock_ip = faddr; /* forced dst addr */
+ sock_port= fport; /* forced dst port */
+ }
+ /* Determine if this is a connection to a special qemu service,
+ * and change the destination address accordingly.
+ * 'faddr' is modified only onsuccess */
+ else if (is_qemu_special_address(so->so_faddr_ip, &faddr)) {
+
+ /* We keep the original destination port. If a special service
+ * listens on a different port than the standard, then appropriate
+ * forwarding should be set up using -net-forward, e.g., as it is
+ * the case with Mawler's DNS traffic, which is redirected to the
+ * special DNS port:
+ * -net-forward 0.0.0.0:0.0.0.0:53:127.0.0.1:21737 */
+
+ sock_ip = faddr; /* real DNS/gateway addr */
+ sock_port= so->so_faddr_port;/* original dst port */
+
+ }
+ /* A normal connection - keep the original destination addr/port */
+ else {
+
+ if (!proxy_manager_add(&sockaddr, SOCKET_STREAM,
+ (ProxyEventFunc) tcp_proxy_event, so)) {
+ soisfconnecting(so);
+ so->s = -1;
+ so->so_state |= SS_PROXIFIED;
+ return 0;
+ }
+
+ sock_ip = so->so_faddr_ip; /* original dst addr */
+ sock_port= so->so_faddr_port; /* original dst port */
+ }
+ }
+
+ DEBUG_MISC((dfd, " connect()ing, addr=%s, proxy=%d\n",
+ sock_address_to_string(&sockaddr), try_proxy));
+
+ sock_address_init_inet( &sockaddr, sock_ip, sock_port );
+
/* We don't care what port we get */
socket_connect(s, &sockaddr);
diff --git a/slirp-android/udp.c b/slirp-android/udp.c
index 9091505..a9c9a82 100644
--- a/slirp-android/udp.c
+++ b/slirp-android/udp.c
@@ -47,6 +47,10 @@
struct udpstat udpstat;
#endif
+/* Keeps track of the number of DNS requests. Used to implement the firewall
+ * option that restricts the number of DNS requests (-max_dns_conns). */
+u_int dns_num_conns;
+
struct socket udb;
static u_int8_t udp_tos(struct socket *so);
@@ -68,6 +72,7 @@ void
udp_init(void)
{
udb.so_next = udb.so_prev = &udb;
+ dns_num_conns = 0;
}
/* m->m_data points at ip packet header
* m->m_len length ip packet
@@ -121,6 +126,33 @@ udp_input(register struct mbuf *m, int iphlen)
ip->ip_len = len;
}
+ /* ------------------------------------------------------*/
+ /* User mode network stack restrictions */
+ /* slirp_should_drop requires host byte ordering in arguments */
+ if (slirp_should_drop(ntohl(ip->ip_dst.addr), ntohs(uh->uh_dport.port),
+ IPPROTO_UDP)) {
+ slirp_drop_log(
+ "Dropped UDP: src: 0x%08lx:0x%04x dst: 0x%08lx:0x%04x\n",
+ ip->ip_src.addr,
+ uh->uh_sport.port,
+ ip->ip_dst.addr,
+ uh->uh_dport.port
+ );
+ goto bad; /* drop the packet */
+ }
+ else {
+ slirp_drop_log(
+ "Allowed UDP: src: 0x%08lx:0x%04x dst: 0x%08lx:0x%04x\n",
+ ip->ip_src.addr,
+ uh->uh_sport.port,
+ ip->ip_dst.addr,
+ uh->uh_dport.port
+ );
+ }
+ /* ------------------------------------------------------*/
+
+
+
/*
* Save a copy of the IP header in case we want restore it
* for sending an ICMP error message in response.
@@ -164,6 +196,18 @@ udp_input(register struct mbuf *m, int iphlen)
goto bad;
}
+ // DNS logging and FW rules
+ if (ntohs(uh->uh_dport.port) == 53) {
+ if (!slirp_dump_dns(m)) {
+ DEBUG_MISC((dfd,"Error logging DNS packet"));
+ }
+ dns_num_conns++;
+ if (slirp_get_max_dns_conns() != -1 &&
+ dns_num_conns > slirp_get_max_dns_conns())
+ goto bad;
+ }
+
+
/*
* Locate pcb for datagram.
*/
@@ -309,6 +353,13 @@ int udp_output2_(struct socket *so, struct mbuf *m,
STAT(udpstat.udps_opackets++);
+ // DNS logging
+ if (so != NULL && so->so_faddr_port == htons(53)) {
+ if (!slirp_dump_dns(m)) {
+ DEBUG_MISC((dfd,"Error logging DNS packet"));
+ }
+ }
+
error = ip_output(so, m);
return (error);
diff --git a/slirp-android/udp.h b/slirp-android/udp.h
index 4350ec3..2224181 100644
--- a/slirp-android/udp.h
+++ b/slirp-android/udp.h
@@ -69,7 +69,6 @@ struct udpiphdr {
#define ui_ulen ui_u.uh_ulen
#define ui_sum ui_u.uh_sum
-#ifdef LOG_ENABLED
struct udpstat {
/* input statistics: */
u_long udps_ipackets; /* total input packets */
@@ -83,7 +82,6 @@ struct udpstat {
/* output statistics: */
u_long udps_opackets; /* total output packets */
};
-#endif
/*
* Names for UDP sysctl objects
@@ -91,9 +89,7 @@ struct udpstat {
#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
#define UDPCTL_MAXID 2
-#ifdef LOG_ENABLED
extern struct udpstat udpstat;
-#endif
extern struct socket udb;
struct mbuf;