[tproxy] UDP tproxy

Javier Govea javier@magma.ca
Thu, 14 Oct 2004 17:45:37 -0400 (EDT)


I've been googling for some information about using tproxy for UDP traffic but I am still
a bit confiused. I hope you guys can help me out.

I want to intercept, at the application layer with a C written program, all UDP traffic,
and then obtain the final destionation IP address and port. 

So, please correct me if I am wrong, I need two rules:

iptables -t nat -A PREROUTING -j DNAT --to-dest 
iptables -t tproxy -A PREROUTING -j TPROXY --on-port 1025

These two rules suppose to redirect all UDP traffic to my box ( to my C
program listening to port 1025, am i right?

Now, my C program needs to obtain the payload, original destination IP address and port is
below. However I receive no ancilliary data, in my program msgh.msg_controllen is always
equal to zero.

Any suggestions?? 

All ideas are very welcomed.

Thank you

PS. Here is the code:

int main() 
  int fd;
  struct sockaddr_in myAddr;
  struct sockaddr_in originalAddr;

  struct msghdr msgh;
  struct iovec v;
  unsigned char acilliarydatabuff[1000];

  unsigned char buffer[MAXBUFFSIZE];
  int bytes;

  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 
	return 0;

  memset((char *)&myAddr, 0x0, sizeof(struct sockaddr_in));
  myAddr.sin_family      = AF_INET;
  myAddr.sin_port        = htons(1025);
  myAddr.sin_addr.s_addr = htonl(INADDR_ANY);

  if (bind(fd, (struct sockaddr *)&myAddr, sizeof(struct sockaddr_in)) == -1) 
	return 0;

  /* QUESTION 1:
   *   Do I need to use getsockopt or setsockopt in here???
   *   If so, what exactly should I pass as paramenters to getsockopt or setsockopt
   *   Krisztian Kovacs, in a message posted in this list on 07 Jul 2004, mentions 
   *   that I need to use getsockopt, but I'm not sure about the 
   *   paramenters I need to pass, can somebody please clarify this point?  

  for(;;) {

    /* QUESTION 2:
     *   The same message posted by Krisztian Kovacs mentions that I need to use
     *   recvmsg and that the original destination IP address and port is the
     *   acilliary data. Is the following code correct??? Is that how I suppose to
     *   extract the payload, original destination IP address and port 
     *   from the ancilliary data?
    memset((char *)&originalAddr, 0x0, sizeof(struct sockaddr_in));
    memset(&msgh, 0, sizeof(msgh));
    msgh.msg_name       = &originalAddr;
    msgh.msg_namelen    = sizeof(struct sockaddr_in);
    v.iov_base          = buffer;
    v.iov_len           = MAXBUFFSIZE;
    msgh.msg_iov        = &v;
    msgh.msg_iovlen     = 1;
    msgh.msg_control    = acilliarydatabuff;
    msgh.msg_controllen = 1000;
    if ( (bytes = recvmsg(fd, &msgh, 0)) == -1 )

    // Get ancilliary data             
    struct cmsghdr *cmsg;
    if (msgh.msg_controllen > 0)
      for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg!=NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) 
     	/* QUESTION 3:
	 *   Is the payload suppose to be in cdata?
        void *cdata = CMSG_DATA(cmsg);
        /* QUESTION 4:
         *    The original destination IP address and port are in msgh.msg_name???
	sockaddr_in *originalDst = (sockaddr_in *)(msgh.msg_name);

	/* Original destination IP address in originalDst->sin_addr.s_addr and
         * original destination port in originalDst->sin_port 
         * Does any of this make any sense???