passt: Run in background, add message logging with severities
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
8bfcc9208c
commit
48ca38c606
6 changed files with 109 additions and 71 deletions
6
dhcp.c
6
dhcp.c
|
@ -198,16 +198,16 @@ int dhcp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts[53].c[0] == DHCPDISCOVER) {
|
if (opts[53].c[0] == DHCPDISCOVER) {
|
||||||
fprintf(stderr, "DHCP: offer to discover");
|
info("DHCP: offer to discover");
|
||||||
opts[53].s[0] = DHCPOFFER;
|
opts[53].s[0] = DHCPOFFER;
|
||||||
} else if (opts[53].c[0] == DHCPREQUEST) {
|
} else if (opts[53].c[0] == DHCPREQUEST) {
|
||||||
fprintf(stderr, "DHCP: ack to request");
|
info("DHCP: ack to request");
|
||||||
opts[53].s[0] = DHCPACK;
|
opts[53].s[0] = DHCPACK;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, " from %02x:%02x:%02x:%02x:%02x:%02x\n\n",
|
info(" from %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
m->chaddr[0], m->chaddr[1], m->chaddr[2],
|
m->chaddr[0], m->chaddr[1], m->chaddr[2],
|
||||||
m->chaddr[3], m->chaddr[4], m->chaddr[5]);
|
m->chaddr[3], m->chaddr[4], m->chaddr[5]);
|
||||||
|
|
||||||
|
|
4
ndp.c
4
ndp.c
|
@ -61,7 +61,7 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
ihr = (struct icmp6hdr *)(ip6hr + 1);
|
ihr = (struct icmp6hdr *)(ip6hr + 1);
|
||||||
|
|
||||||
if (ih->icmp6_type == NS) {
|
if (ih->icmp6_type == NS) {
|
||||||
fprintf(stderr, "NDP: received NS, sending NA\n");
|
info("NDP: received NS, sending NA");
|
||||||
ihr->icmp6_type = NA;
|
ihr->icmp6_type = NA;
|
||||||
ihr->icmp6_code = 0;
|
ihr->icmp6_code = 0;
|
||||||
ihr->icmp6_router = 1;
|
ihr->icmp6_router = 1;
|
||||||
|
@ -76,7 +76,7 @@ int ndp(struct ctx *c, struct ethhdr *eh, size_t len)
|
||||||
memcpy(p, c->mac, ETH_ALEN);
|
memcpy(p, c->mac, ETH_ALEN);
|
||||||
p += 6;
|
p += 6;
|
||||||
} else if (ih->icmp6_type == RS) {
|
} else if (ih->icmp6_type == RS) {
|
||||||
fprintf(stderr, "NDP: received RS, sending RA\n");
|
info("NDP: received RS, sending RA");
|
||||||
ihr->icmp6_type = RA;
|
ihr->icmp6_type = RA;
|
||||||
ihr->icmp6_code = 0;
|
ihr->icmp6_code = 0;
|
||||||
ihr->icmp6_rt_lifetime = htons(3600);
|
ihr->icmp6_rt_lifetime = htons(3600);
|
||||||
|
|
105
passt.c
105
passt.c
|
@ -40,6 +40,7 @@
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
#include "passt.h"
|
#include "passt.h"
|
||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
|
@ -185,7 +186,7 @@ out:
|
||||||
close(s);
|
close(s);
|
||||||
|
|
||||||
if (!(c->v4 || c->v6) || !*c->ifn) {
|
if (!(c->v4 || c->v6) || !*c->ifn) {
|
||||||
fprintf(stderr, "No routing information\n");
|
err("No routing information");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +257,7 @@ static void get_addrs(struct ctx *c)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
out:
|
out:
|
||||||
fprintf(stderr, "Couldn't get addresses for routable interface\n");
|
err("Couldn't get addresses for routable interface");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +289,7 @@ static void get_dns(struct ctx *c)
|
||||||
if (dns4 || dns6)
|
if (dns4 || dns6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(stderr, "Couldn't get any nameserver address\n");
|
err("Couldn't get any nameserver address");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +303,8 @@ static void tap4_handler(struct ctx *c, char *in, size_t len)
|
||||||
{
|
{
|
||||||
struct ethhdr *eh = (struct ethhdr *)in;
|
struct ethhdr *eh = (struct ethhdr *)in;
|
||||||
struct iphdr *iph = (struct iphdr *)(eh + 1);
|
struct iphdr *iph = (struct iphdr *)(eh + 1);
|
||||||
char buf_s[BUFSIZ], buf_d[BUFSIZ];
|
char buf_s[BUFSIZ] __attribute((__unused__));
|
||||||
|
char buf_d[BUFSIZ] __attribute((__unused__));
|
||||||
char *l4h;
|
char *l4h;
|
||||||
|
|
||||||
if (arp(c, eh, len) || dhcp(c, eh, len))
|
if (arp(c, eh, len) || dhcp(c, eh, len))
|
||||||
|
@ -315,7 +317,7 @@ static void tap4_handler(struct ctx *c, char *in, size_t len)
|
||||||
len -= (intptr_t)l4h - (intptr_t)eh;
|
len -= (intptr_t)l4h - (intptr_t)eh;
|
||||||
|
|
||||||
if (iph->protocol == IPPROTO_ICMP) {
|
if (iph->protocol == IPPROTO_ICMP) {
|
||||||
fprintf(stderr, "icmp from tap: %s -> %s\n",
|
debug("icmp from tap: %s -> %s",
|
||||||
inet_ntop(AF_INET, &iph->saddr, buf_s, sizeof(buf_s)),
|
inet_ntop(AF_INET, &iph->saddr, buf_s, sizeof(buf_s)),
|
||||||
inet_ntop(AF_INET, &iph->daddr, buf_d, sizeof(buf_d)));
|
inet_ntop(AF_INET, &iph->daddr, buf_d, sizeof(buf_d)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,7 +326,7 @@ static void tap4_handler(struct ctx *c, char *in, size_t len)
|
||||||
if (len < sizeof(*th) && len < sizeof(struct udphdr))
|
if (len < sizeof(*th) && len < sizeof(struct udphdr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(stderr, "%s from tap: %s:%i -> %s:%i\n",
|
debug("%s from tap: %s:%i -> %s:%i",
|
||||||
getprotobynumber(iph->protocol)->p_name,
|
getprotobynumber(iph->protocol)->p_name,
|
||||||
inet_ntop(AF_INET, &iph->saddr, buf_s, sizeof(buf_s)),
|
inet_ntop(AF_INET, &iph->saddr, buf_s, sizeof(buf_s)),
|
||||||
ntohs(th->source),
|
ntohs(th->source),
|
||||||
|
@ -350,7 +352,8 @@ static void tap6_handler(struct ctx *c, char *in, size_t len)
|
||||||
{
|
{
|
||||||
struct ethhdr *eh = (struct ethhdr *)in;
|
struct ethhdr *eh = (struct ethhdr *)in;
|
||||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)(eh + 1);
|
struct ipv6hdr *ip6h = (struct ipv6hdr *)(eh + 1);
|
||||||
char buf_s[BUFSIZ], buf_d[BUFSIZ];
|
char buf_s[BUFSIZ] __attribute((__unused__));
|
||||||
|
char buf_d[BUFSIZ] __attribute((__unused__));
|
||||||
uint8_t proto;
|
uint8_t proto;
|
||||||
char *l4h;
|
char *l4h;
|
||||||
|
|
||||||
|
@ -371,18 +374,16 @@ static void tap6_handler(struct ctx *c, char *in, size_t len)
|
||||||
len -= (intptr_t)l4h - (intptr_t)eh;
|
len -= (intptr_t)l4h - (intptr_t)eh;
|
||||||
|
|
||||||
if (proto == IPPROTO_ICMPV6) {
|
if (proto == IPPROTO_ICMPV6) {
|
||||||
fprintf(stderr, "icmpv6 from tap: %s ->\n\t%s\n",
|
debug("icmpv6 from tap: %s ->\n\t%s",
|
||||||
inet_ntop(AF_INET6, &ip6h->saddr, buf_s, sizeof(buf_s)),
|
inet_ntop(AF_INET6, &ip6h->saddr, buf_s, sizeof(buf_s)),
|
||||||
inet_ntop(AF_INET6, &ip6h->daddr, buf_d, sizeof(buf_d))
|
inet_ntop(AF_INET6, &ip6h->daddr, buf_d, sizeof(buf_d)));
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
struct tcphdr *th = (struct tcphdr *)l4h;
|
struct tcphdr *th = (struct tcphdr *)l4h;
|
||||||
|
|
||||||
if (len < sizeof(*th) && len < sizeof(struct udphdr))
|
if (len < sizeof(*th) && len < sizeof(struct udphdr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(stderr, "%s from tap: [%s]:%i\n"
|
debug("%s from tap: [%s]:%i\n\t-> [%s]:%i",
|
||||||
"\t-> [%s]:%i\n",
|
|
||||||
getprotobynumber(proto)->p_name,
|
getprotobynumber(proto)->p_name,
|
||||||
inet_ntop(AF_INET6, &ip6h->saddr, buf_s, sizeof(buf_s)),
|
inet_ntop(AF_INET6, &ip6h->saddr, buf_s, sizeof(buf_s)),
|
||||||
ntohs(th->source),
|
ntohs(th->source),
|
||||||
|
@ -457,8 +458,7 @@ static void sock_handler(struct ctx *c, int fd, uint32_t events)
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &so, &sl))
|
if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &so, &sl))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(stderr, "%s: packet from socket %i\n",
|
debug("%s: packet from socket %i", getprotobynumber(so)->p_name, fd);
|
||||||
getprotobynumber(so)->p_name, fd);
|
|
||||||
|
|
||||||
if (so == IPPROTO_ICMP || so == IPPROTO_ICMPV6)
|
if (so == IPPROTO_ICMP || so == IPPROTO_ICMPV6)
|
||||||
icmp_sock_handler(c, fd, events);
|
icmp_sock_handler(c, fd, events);
|
||||||
|
@ -517,32 +517,6 @@ int main(int argc, char **argv)
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
||||||
get_routes(&c);
|
|
||||||
get_addrs(&c);
|
|
||||||
get_dns(&c);
|
|
||||||
|
|
||||||
if (c.v4) {
|
|
||||||
fprintf(stderr, "ARP:\n");
|
|
||||||
fprintf(stderr, "\taddress: %02x:%02x:%02x:%02x:%02x:%02x "
|
|
||||||
"from %s\n", c.mac[0], c.mac[1], c.mac[2],
|
|
||||||
c.mac[3], c.mac[4], c.mac[5], c.ifn);
|
|
||||||
fprintf(stderr, "DHCP:\n");
|
|
||||||
fprintf(stderr, "\tassign:\t%s\n\tnmask:\t%s\n"
|
|
||||||
"\trouter:\t%s\n\tDNS:\t%s\n",
|
|
||||||
inet_ntop(AF_INET, &c.addr4, buf4[0], sizeof(buf4[0])),
|
|
||||||
inet_ntop(AF_INET, &c.mask4, buf4[1], sizeof(buf4[1])),
|
|
||||||
inet_ntop(AF_INET, &c.gw4, buf4[2], sizeof(buf4[2])),
|
|
||||||
inet_ntop(AF_INET, &c.dns4, buf4[3], sizeof(buf4[3])));
|
|
||||||
}
|
|
||||||
if (c.v6) {
|
|
||||||
fprintf(stderr, "NDP:\n");
|
|
||||||
fprintf(stderr, "\tassign:\t%s\n\trouter:\t%s\n\tDNS:\t%s\n",
|
|
||||||
inet_ntop(AF_INET6, &c.addr6, buf6[0], sizeof(buf6[0])),
|
|
||||||
inet_ntop(AF_INET6, &c.gw6, buf6[1], sizeof(buf6[1])),
|
|
||||||
inet_ntop(AF_INET6, &c.dns6, buf6[2], sizeof(buf6[2])));
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &last_time)) {
|
if (clock_gettime(CLOCK_MONOTONIC, &last_time)) {
|
||||||
perror("clock_gettime");
|
perror("clock_gettime");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -558,16 +532,51 @@ int main(int argc, char **argv)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
fd_unix = sock_unix();
|
fd_unix = sock_unix();
|
||||||
|
|
||||||
|
openlog("passt", 0, LOG_DAEMON);
|
||||||
|
if (daemon(0, 0)) {
|
||||||
|
fprintf(stderr, "Failed to fork into background\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_routes(&c);
|
||||||
|
get_addrs(&c);
|
||||||
|
get_dns(&c);
|
||||||
|
|
||||||
|
if (c.v4) {
|
||||||
|
info("ARP:");
|
||||||
|
info(" address: %02x:%02x:%02x:%02x:%02x:%02x from %s",
|
||||||
|
c.mac[0], c.mac[1], c.mac[2], c.mac[3], c.mac[4], c.mac[5],
|
||||||
|
c.ifn);
|
||||||
|
info("DHCP:");
|
||||||
|
info(" assign: %s",
|
||||||
|
inet_ntop(AF_INET, &c.addr4, buf4[0], sizeof(buf4[0])));
|
||||||
|
info(" mask: %s",
|
||||||
|
inet_ntop(AF_INET, &c.mask4, buf4[0], sizeof(buf4[0])));
|
||||||
|
info(" router: %s",
|
||||||
|
inet_ntop(AF_INET, &c.gw4, buf4[2], sizeof(buf4[2])));
|
||||||
|
info(" DNS: %s",
|
||||||
|
inet_ntop(AF_INET, &c.dns4, buf4[3], sizeof(buf4[3])));
|
||||||
|
}
|
||||||
|
if (c.v6) {
|
||||||
|
info("NDP:");
|
||||||
|
info(" assign: %s",
|
||||||
|
inet_ntop(AF_INET6, &c.addr6, buf6[0], sizeof(buf6[0])));
|
||||||
|
info(" router: %s",
|
||||||
|
inet_ntop(AF_INET6, &c.gw6, buf6[1], sizeof(buf6[1])));
|
||||||
|
info(" DNS: %s",
|
||||||
|
inet_ntop(AF_INET6, &c.dns6, buf6[2], sizeof(buf6[2])));
|
||||||
|
}
|
||||||
|
|
||||||
listen:
|
listen:
|
||||||
listen(fd_unix, 1);
|
listen(fd_unix, 1);
|
||||||
fprintf(stderr,
|
info("You can now start qrap:");
|
||||||
"You can now start qrap:\n\t"
|
info(" ./qrap 5 kvm ... -net socket,fd=5 -net nic,model=virtio");
|
||||||
"./qrap 5 kvm ... -net socket,fd=5 -net nic,model=virtio\n"
|
info("or directly qemu, patched with:");
|
||||||
"or directly qemu, patched with:\n\t"
|
info(" qemu/0001-net-Allow-also-UNIX-domain-sockets-to-be-used-as-net.patch");
|
||||||
"qemu/0001-net-Allow-also-UNIX-domain-sockets-to-be-used-as-net.patch\n"
|
info("as follows:");
|
||||||
"as follows:\n\t"
|
info("kvm ... -net socket,connect="
|
||||||
"kvm ... -net socket,connect="
|
UNIX_SOCK_PATH " -net nic,model=virtio");
|
||||||
UNIX_SOCK_PATH " -net nic,model=virtio\n\n");
|
|
||||||
|
|
||||||
c.fd_unix = accept(fd_unix, NULL, NULL);
|
c.fd_unix = accept(fd_unix, NULL, NULL);
|
||||||
ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLERR | EPOLLHUP;
|
ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLERR | EPOLLHUP;
|
||||||
|
|
5
tcp.c
5
tcp.c
|
@ -354,8 +354,9 @@ enum tcp_state {
|
||||||
FIN_WAIT_1,
|
FIN_WAIT_1,
|
||||||
FIN_WAIT_1_SOCK_FIN,
|
FIN_WAIT_1_SOCK_FIN,
|
||||||
};
|
};
|
||||||
|
#define TCP_STATE_STR_SIZE (FIN_WAIT_1_SOCK_FIN + 1)
|
||||||
|
|
||||||
static char *tcp_state_str[FIN_WAIT_1_SOCK_FIN + 1] = {
|
static char *tcp_state_str[TCP_STATE_STR_SIZE] __attribute((__unused__)) = {
|
||||||
"CLOSED", "TAP_SYN_SENT", "SOCK_SYN_SENT", "TAP_SYN_RCVD",
|
"CLOSED", "TAP_SYN_SENT", "SOCK_SYN_SENT", "TAP_SYN_RCVD",
|
||||||
"ESTABLISHED", "ESTABLISHED_SOCK_FIN", "CLOSE_WAIT", "LAST_ACK",
|
"ESTABLISHED", "ESTABLISHED_SOCK_FIN", "CLOSE_WAIT", "LAST_ACK",
|
||||||
"FIN_WAIT_1", "FIN_WAIT_1_SOCK_FIN",
|
"FIN_WAIT_1", "FIN_WAIT_1_SOCK_FIN",
|
||||||
|
@ -480,7 +481,7 @@ static void tcp_act_clear(int s)
|
||||||
*/
|
*/
|
||||||
static void tcp_set_state(int s, enum tcp_state state)
|
static void tcp_set_state(int s, enum tcp_state state)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "TCP: socket %i: %s -> %s\n", s,
|
debug("TCP: socket %i: %s -> %s", s,
|
||||||
tcp_state_str[tc[s].s], tcp_state_str[state]);
|
tcp_state_str[tc[s].s], tcp_state_str[state]);
|
||||||
tc[s].s = state;
|
tc[s].s = state;
|
||||||
}
|
}
|
||||||
|
|
18
util.c
18
util.c
|
@ -21,9 +21,27 @@
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "passt.h"
|
#include "passt.h"
|
||||||
|
|
||||||
|
#define logfn(name, level) \
|
||||||
|
void name(const char *format, ...) { \
|
||||||
|
va_list args; \
|
||||||
|
\
|
||||||
|
va_start(args, format); \
|
||||||
|
vsyslog(level, format, args); \
|
||||||
|
va_end(args); \
|
||||||
|
}
|
||||||
|
|
||||||
|
logfn(err, LOG_ERR)
|
||||||
|
logfn(warn, LOG_WARNING)
|
||||||
|
logfn(info, LOG_INFO)
|
||||||
|
#ifdef DEBUG
|
||||||
|
logfn(debug, LOG_DEBUG)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* csum_fold() - Fold long sum for IP and TCP checksum
|
* csum_fold() - Fold long sum for IP and TCP checksum
|
||||||
* @sum: Original long sum
|
* @sum: Original long sum
|
||||||
|
|
10
util.h
10
util.h
|
@ -1,3 +1,13 @@
|
||||||
|
void err(const char *format, ...);
|
||||||
|
void warn(const char *format, ...);
|
||||||
|
void info(const char *format, ...);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void debug(const char *format, ...);
|
||||||
|
#else
|
||||||
|
#define debug(...) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
uint16_t csum_fold(uint32_t sum);
|
uint16_t csum_fold(uint32_t sum);
|
||||||
uint16_t csum_ip4(void *buf, size_t len);
|
uint16_t csum_ip4(void *buf, size_t len);
|
||||||
void csum_tcp4(struct iphdr *iph);
|
void csum_tcp4(struct iphdr *iph);
|
||||||
|
|
Loading…
Reference in a new issue