PF PF divert-to Loop Problem

cArleone

New Member


Messages: 4

Hi,

I used ipfw before
My ipfw rule was like this :
ipfw -q add 11 divert 4444 udp from any to any dst-port 53 in via igb1


I move on pf now
My pf rule was like this :
Code:
pass in quick on igb1 proto udp from any to port { 53 } divert-to 127.0.0.1 port 4444


My Code :
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <unistd.h>


int main(int argc, char** argv) {
    printf("Start DIVERT \n");

    int ret, data_size;
    struct sockaddr_in bindPort, sin;
    socklen_t sinlen;

    unsigned char *packet = (unsigned char *)malloc(65536);

    if(argc!=2) {
        fprintf(stderr, "Usage: %s <port number>\n", argv[0]);
        exit(1);
    }

    int bind_socket;
    bind_socket = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT);

    if (bind_socket == -1) {
        perror("socket_bind_error");
        exit(1);
    }

    bindPort.sin_family=PF_INET;
    bindPort.sin_port=htons(atol(argv[1]));
    bindPort.sin_addr.s_addr=0;

    ret = bind(bind_socket, (struct sockaddr *)&bindPort, sizeof(struct sockaddr_in));
    if(ret!=0) {
        close(bind_socket);
        fprintf(stderr, "%s: Error bind(): %s",argv[0],strerror(ret));
        exit(2);
    }


    sinlen = sizeof(struct sockaddr_in);
    struct ip_header *hdr;

    while(1){
        data_size=recvfrom(bind_socket, packet, 65535, 0, (struct sockaddr *) &sin, &sinlen);
        if(data_size < 0){
            printf("Recvfrom Error, failed get packets \n");
            return 1;
        }

        printf("data_size : %d \n",data_size);

        data_size = sendto(bind_socket, packet, data_size ,0, (struct sockaddr *) &sin, sinlen);
    }
}


My code was working fine in ipfw. I was sending 1 dns request.
ipfw output :
Code:
Start DIVERT 
data_size : 52



pf output :
Code:
Start DIVERT 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
data_size : 52 
...



The dns request I send with pf loops and does not end.
Where is my problem.
Can you help

FreeBSD Version : 12.2
 

VladiBG

Daemon

Reaction score: 546
Messages: 1,183

When reinject the packet try to use "(struct sockaddr *) &bindPort" as you already reset the destination address for it with "bindPort.sin_addr.s_addr=0"

You can check the example of OpenBSD divert here:
 
Top