aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--port_fwd.c55
1 files changed, 24 insertions, 31 deletions
diff --git a/port_fwd.c b/port_fwd.c
index 136a450..49b60b1 100644
--- a/port_fwd.c
+++ b/port_fwd.c
@@ -23,39 +23,28 @@
#include "passt.h"
#include "lineread.h"
+/* See enum in kernel's include/net/tcp_states.h */
+#define UDP_LISTEN 0x07
+#define TCP_LISTEN 0x0a
+
/**
* procfs_scan_listen() - Set bits for listening TCP or UDP sockets from procfs
- * @proto: IPPROTO_TCP or IPPROTO_UDP
- * @ip_version: IP version, V4 or V6
- * @ns: Use saved file descriptors for namespace if set
+ * @fd: Pointer to fd for relevant /proc/net file
+ * @path: Path to /proc/net file to open (if fd is -1)
+ * @lstate: Code for listening state to scan for
* @map: Bitmap where numbers of ports in listening state will be set
* @exclude: Bitmap of ports to exclude from setting (and clear)
*
* #syscalls:pasta lseek
* #syscalls:pasta ppc64le:_llseek ppc64:_llseek armv6l:_llseek armv7l:_llseek
*/
-static void procfs_scan_listen(struct ctx *c, uint8_t proto, int ip_version,
- int ns, uint8_t *map, const uint8_t *exclude)
+static void procfs_scan_listen(int *fd, const char *path, unsigned int lstate,
+ uint8_t *map, const uint8_t *exclude)
{
- char *path, *line;
struct lineread lr;
unsigned long port;
unsigned int state;
- int *fd;
-
- if (proto == IPPROTO_TCP) {
- fd = &c->proc_net_tcp[ip_version][ns];
- if (ip_version == V4)
- path = "/proc/net/tcp";
- else
- path = "/proc/net/tcp6";
- } else {
- fd = &c->proc_net_udp[ip_version][ns];
- if (ip_version == V4)
- path = "/proc/net/udp";
- else
- path = "/proc/net/udp6";
- }
+ char *line;
if (*fd != -1) {
if (lseek(*fd, 0, SEEK_SET)) {
@@ -73,9 +62,7 @@ static void procfs_scan_listen(struct ctx *c, uint8_t proto, int ip_version,
if (sscanf(line, "%*u: %*x:%lx %*x:%*x %x", &port, &state) != 2)
continue;
- /* See enum in kernel's include/net/tcp_states.h */
- if ((proto == IPPROTO_TCP && state != 0x0a) ||
- (proto == IPPROTO_UDP && state != 0x07))
+ if (state != lstate)
continue;
if (bitmap_isset(exclude, port))
@@ -109,15 +96,21 @@ void get_bound_ports(struct ctx *c, int ns, uint8_t proto)
if (proto == IPPROTO_UDP) {
memset(udp_map, 0, PORT_BITMAP_SIZE);
- procfs_scan_listen(c, IPPROTO_UDP, V4, ns, udp_map, udp_excl);
- procfs_scan_listen(c, IPPROTO_UDP, V6, ns, udp_map, udp_excl);
-
- procfs_scan_listen(c, IPPROTO_TCP, V4, ns, udp_map, udp_excl);
- procfs_scan_listen(c, IPPROTO_TCP, V6, ns, udp_map, udp_excl);
+ procfs_scan_listen(&c->proc_net_udp[V4][ns], "/proc/net/udp",
+ UDP_LISTEN, udp_map, udp_excl);
+ procfs_scan_listen(&c->proc_net_udp[V6][ns], "/proc/net/udp6",
+ UDP_LISTEN, udp_map, udp_excl);
+
+ procfs_scan_listen(&c->proc_net_tcp[V4][ns], "/proc/net/tcp",
+ TCP_LISTEN, udp_map, udp_excl);
+ procfs_scan_listen(&c->proc_net_tcp[V6][ns], "/proc/net/tcp6",
+ TCP_LISTEN, udp_map, udp_excl);
} else if (proto == IPPROTO_TCP) {
memset(tcp_map, 0, PORT_BITMAP_SIZE);
- procfs_scan_listen(c, IPPROTO_TCP, V4, ns, tcp_map, tcp_excl);
- procfs_scan_listen(c, IPPROTO_TCP, V6, ns, tcp_map, tcp_excl);
+ procfs_scan_listen(&c->proc_net_tcp[V4][ns], "/proc/net/tcp",
+ TCP_LISTEN, tcp_map, tcp_excl);
+ procfs_scan_listen(&c->proc_net_tcp[V6][ns], "/proc/net/tcp6",
+ TCP_LISTEN, tcp_map, tcp_excl);
}
}