In https://docs.freebsd.org/en/books/handbook/firewalls/ it says:
"FreeBSD has three firewalls built into the base system: PF, IPFW, and IPFILTER, also known as IPF."
in section 33.4 it says:
"IPFW is included in the basic FreeBSD install as a kernel loadable module, meaning that a custom kernel is not needed in order to enable IPFW."
In section 33.4.4 it says:
"FreeBSD’s IPFW firewall has two implementations of NAT: the userland implementation natd(8), and the more recent in-kernel NAT implementation."
So, with all of that understood, how is it possible to dump the connection tracking table of IPFW, in-kernel NAT?
With pf, the author renamed it the "state table" (probably just because he dislikes Linux and wanted to cause trouble) and you dump it like this:
pfctl -s state
with natd it's named "lookup table" and to see it you you start natd with logging and a control socket "natd -n fxp0 -l -p /var/run/natd.sock"
then you can allegedly query the control socket and print the lookup table:
natd -s -p /var/run/natd.sock
Although I think this only prints the defined rules - to get the actual in-core state table I think you have to use the API, connect to the socket, and iterate through the in-core rules.
A quick program that AI hacked out of the natd source to do this is:
FWIW I haven't tried this to see if it would work. It's just an example of how to do it - since there's a socket you can query.
But, with the in-kernel version of libaliases, it appears you can't do squat. You can dump the rules:
ipfw list
you can dump any port forwarding with
ipfw nat show config
but you don't have any way of seeing the in-core state table/lookup table.
The docs talk about creating a logging interface in /etc/rc.conf
sysrc firewall_logif="YES"
Then dumping the log with:
tcpdump -t -n -i ipfw0
but this isn't looking at the state table, lookup table, connection tracking table, whatever you want to call it.
With the Linux iptables they also make it easy
cat /proc/net/nf_conntrack
dumps the connection tracking table.
Is this just a deliberately built restriction with in-kernel libaliases? I know that libaliases is supposed to be primitive and basic - and I know that the userland natd is discouraged because of the multiple copies that have to be made with a packet going from kernelspace to userspace, but it seems that in this regard at least, natd instance is slightly advanced. However, there is a TON of effort that appears to have gone into libaliases - and it seems that it would be TRIVIAL to add the same functionality that is in natd - provide a socket that we could query the kernel for the current state table.
"FreeBSD has three firewalls built into the base system: PF, IPFW, and IPFILTER, also known as IPF."
in section 33.4 it says:
"IPFW is included in the basic FreeBSD install as a kernel loadable module, meaning that a custom kernel is not needed in order to enable IPFW."
In section 33.4.4 it says:
"FreeBSD’s IPFW firewall has two implementations of NAT: the userland implementation natd(8), and the more recent in-kernel NAT implementation."
So, with all of that understood, how is it possible to dump the connection tracking table of IPFW, in-kernel NAT?
With pf, the author renamed it the "state table" (probably just because he dislikes Linux and wanted to cause trouble) and you dump it like this:
pfctl -s state
with natd it's named "lookup table" and to see it you you start natd with logging and a control socket "natd -n fxp0 -l -p /var/run/natd.sock"
then you can allegedly query the control socket and print the lookup table:
natd -s -p /var/run/natd.sock
Although I think this only prints the defined rules - to get the actual in-core state table I think you have to use the API, connect to the socket, and iterate through the in-core rules.
A quick program that AI hacked out of the natd source to do this is:
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define NATD_SOCKET "/var/run/natd.ctl"
#define CMD "show\n"
int main(void) {
int sock;
struct sockaddr_un addr;
char buffer[4096];
ssize_t n;
// Create UNIX domain socket
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, NATD_SOCKET, sizeof(addr.sun_path) - 1);
// Connect to natd control socket
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect");
close(sock);
exit(1);
}
// Send "show" command
if (write(sock, CMD, strlen(CMD)) < 0) {
perror("write");
close(sock);
exit(1);
}
// Read and print response
while ((n = read(sock, buffer, sizeof(buffer) - 1)) > 0) {
buffer[n] = '\0';
printf("%s", buffer);
}
if (n < 0) {
perror("read");
}
close(sock);
return 0;
}
But, with the in-kernel version of libaliases, it appears you can't do squat. You can dump the rules:
ipfw list
you can dump any port forwarding with
ipfw nat show config
but you don't have any way of seeing the in-core state table/lookup table.
The docs talk about creating a logging interface in /etc/rc.conf
sysrc firewall_logif="YES"
Then dumping the log with:
tcpdump -t -n -i ipfw0
but this isn't looking at the state table, lookup table, connection tracking table, whatever you want to call it.
With the Linux iptables they also make it easy
cat /proc/net/nf_conntrack
dumps the connection tracking table.
Is this just a deliberately built restriction with in-kernel libaliases? I know that libaliases is supposed to be primitive and basic - and I know that the userland natd is discouraged because of the multiple copies that have to be made with a packet going from kernelspace to userspace, but it seems that in this regard at least, natd instance is slightly advanced. However, there is a TON of effort that appears to have gone into libaliases - and it seems that it would be TRIVIAL to add the same functionality that is in natd - provide a socket that we could query the kernel for the current state table.