aboutgitcodebugslistschat
path: root/passt.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-03-17 10:57:44 +0100
committerStefano Brivio <sbrivio@redhat.com>2021-03-18 12:58:03 +0100
commit1d807fc720bda7ec446c683bbc1a5e32897ca04e (patch)
tree7dc59149a94817fa5eddc6aa6e132fa1a7335f19 /passt.c
parentd32edee60a938c3ffdb227a94e1f3afac0e40177 (diff)
downloadpasst-1d807fc720bda7ec446c683bbc1a5e32897ca04e.tar
passt-1d807fc720bda7ec446c683bbc1a5e32897ca04e.tar.gz
passt-1d807fc720bda7ec446c683bbc1a5e32897ca04e.tar.bz2
passt-1d807fc720bda7ec446c683bbc1a5e32897ca04e.tar.lz
passt-1d807fc720bda7ec446c683bbc1a5e32897ca04e.tar.xz
passt-1d807fc720bda7ec446c683bbc1a5e32897ca04e.tar.zst
passt-1d807fc720bda7ec446c683bbc1a5e32897ca04e.zip
passt: Introduce ICMP echo proxy
It's nice to be able to confirm connectivity using ICMP or ICMPv6 echo requests, and "ping" sockets on Linux (IPPROTO_ICMP datagram) allow us to do that without any special capability. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'passt.c')
-rw-r--r--passt.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/passt.c b/passt.c
index c37b445..98576a6 100644
--- a/passt.c
+++ b/passt.c
@@ -46,6 +46,7 @@
#include "dhcp.h"
#include "ndp.h"
#include "util.h"
+#include "icmp.h"
#include "tcp.h"
#include "udp.h"
@@ -335,6 +336,8 @@ static void tap4_handler(struct ctx *c, char *in, size_t len)
tcp_tap_handler(c, AF_INET, &iph->daddr, l4h, len);
else if (iph->protocol == IPPROTO_UDP)
udp_tap_handler(c, AF_INET, &iph->daddr, l4h, len);
+ else if (iph->protocol == IPPROTO_ICMP)
+ icmp_tap_handler(c, AF_INET, &iph->daddr, l4h, len);
}
/**
@@ -391,6 +394,8 @@ static void tap6_handler(struct ctx *c, char *in, size_t len)
tcp_tap_handler(c, AF_INET6, &ip6h->daddr, l4h, len);
else if (proto == IPPROTO_UDP)
udp_tap_handler(c, AF_INET6, &ip6h->daddr, l4h, len);
+ else if (proto == IPPROTO_ICMPV6)
+ icmp_tap_handler(c, AF_INET6, &ip6h->daddr, l4h, len);
}
/**
@@ -449,15 +454,18 @@ static void sock_handler(struct ctx *c, int fd, uint32_t events)
sl = sizeof(so);
- if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &so, &sl) ||
- so == SOCK_STREAM) {
- fprintf(stderr, "TCP: packet from socket %i\n", fd);
+ if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &so, &sl))
+ return;
+
+ fprintf(stderr, "%s: packet from socket %i\n",
+ getprotobynumber(so)->p_name, fd);
+
+ if (so == IPPROTO_ICMP || so == IPPROTO_ICMPV6)
+ icmp_sock_handler(c, fd, events);
+ else if (so == IPPROTO_TCP)
tcp_sock_handler(c, fd, events);
- }
- else if (so == SOCK_DGRAM) {
+ else if (so == IPPROTO_UDP)
udp_sock_handler(c, fd, events);
- fprintf(stderr, "UDP: packet from socket %i\n", fd);
- }
}
/**
@@ -546,7 +554,7 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
- if (tcp_sock_init(&c) || udp_sock_init(&c))
+ if (icmp_sock_init(&c) || tcp_sock_init(&c) || udp_sock_init(&c))
exit(EXIT_FAILURE);
fd_unix = sock_unix();