Search code examples
firewallfreebsdnat

How do I get the original destination IP of a redirected connection with pf on FreeBSD?


When I'm redirecting a connection with iptables on Linux with a -j REDIRECT rule, the program that receives the redirected connection can do getsockopt(sockfd, SOL_IP, SO_ORIGINAL_DST, &val, &len); to get the original, pre-redirection destination IP of the connection. How do I do the same thing when I'm redirecting a connection with pf on FreeBSD with an rdr rule?


Solution

  • Just solved this problem yesterday on MacOS, didn't test on FreeBSD, I think it's similar.

    you need pfioc_natlook struct from net/pfvar.h.

    General steps are:

    • initialize pfioc_natlook to pnl
    • fill pnl with client socket's ip & port(saddr,sxport), proxy server's bind ip & port(daddr, dxport)
    • open('/dev/pf'), get its fd
    • do ioctl(fd, C.DIOCNATLOOK, *pnl), then pnl's rdxport and rdaddr will be connection's original port & ip

    Anyone still interested in this problem can check this gist: https://gist.github.com/gkoyuncu/f8aad43f66815dac7769

    I did a mini POC program with golang(CGO wrapper), it works on MacOS: https://github.com/monsterxx03/pf_poc