# Retrieving the destination port in an ipfw'ed UDP packet



## casdal (Feb 5, 2013)

I'm trying to get the destination port from a UDP packet that's been ipfw fwd'ed to my code. Getting the destination IP address works fine with *setsockopt(...,IP_RECVDSTADDR,...)* and then *recvfrom*, but there doesn't seem to be a way to get the port. 

For TCP I could just use getsockname(2) and getpeername(2) for all the IP address info but this only returns the locally bound address and port, not the actual destination.

Is there an elegant way to get the destination IP port from an ipfw fwd'ed packet?

Thanks


----------



## expl (Feb 6, 2013)

casdal said:
			
		

> I'm trying to get the destination port from a UDP packet that's been ipfw fwd'ed to my code. Getting the destination IP address works fine with *setsockopt(...,IP_RECVDSTADDR,...)* and then *recvfrom*, but there doesn't seem to be a way to get the port.
> 
> For TCP I could just use getsockname(2) and getpeername(2) for all the IP address info but this only returns the locally bound address and port, not the actual destination.
> 
> ...



Should not make a difference to your application if its forwarded by firewall or not. You also don't need IP_RECVDSTADDR sockoption, recvfrom() has argument struct sockaddr * restrict from that will contain both the address and port of sender, just need to cast it to struct sockaddr_in if on IPv4 or struct sockaddr_in6 for IPv6, very simple.


----------



## casdal (Feb 6, 2013)

Thanks for your reply. 

I agree that getting the sender address is as easy as you say, but I'm asking about getting the destination address and port. From what I can tell, the only way to get the destination address is via IP_RECVDSTADDR and I don't see how I can get the port.


----------



## expl (Feb 6, 2013)

casdal said:
			
		

> Thanks for your reply.
> 
> I agree that getting the sender address is as easy as you say, but I'm asking about getting the destination address and port. From what I can tell, the only way to get the destination address is via IP_RECVDSTADDR and I don't see how I can get the port.



Sorry I don't understand what the problem is, what is 'destination'? The addr/port of client that packet originated from  should be put in the struct sockaddr * from at recvfrom, local addr/port is the one you called bind(2) on.


----------



## kpa (Feb 6, 2013)

Don't you know the destination port already? Or do you have a not so specific NAT rule that translates many different destination ports to a single one?


----------



## casdal (Feb 6, 2013)

Apologies for not being clearer. The destination address is not the one I called bind() on as it was redirected to the local service using an ipfw forward. As such, my code runs bind() to localhost and the ipfw command looks like:
  ipfw fwd 127.0.0.1,1234 udp from $clienthosts to any in via $internal_interface

So my service running on 127.0.0.1:1234 receives the packet via recvfrom and now I need to process it before sending it on to the actual destination. As such, I need to retrieve the destination IP and port.


----------



## expl (Feb 6, 2013)

casdal said:
			
		

> Apologies for not being clearer. The destination address is not the one I called bind() on as it was redirected to the local service using an ipfw forward. As such, my code runs bind() to localhost and the ipfw command looks like:
> ipfw fwd 127.0.0.1,1234 udp from $clienthosts to any in via $internal_interface
> 
> So my service running on 127.0.0.1:1234 receives the packet via recvfrom and now I need to process it before sending it on to the actual destination. As such, I need to retrieve the destination IP and port.



You cant get the original destination because ipfw translates the packet headers before they reach your application level. You need to use ipfw 'divert' rule and a divert(4) socket for this kind of task.


----------



## casdal (Feb 6, 2013)

Thank you for this. I shall try find some sample code to work from.

In order to help my understanding, can you explain why I can get the true destination details for TCP using ipfw fwd but not UDP?


----------



## expl (Feb 6, 2013)

casdal said:
			
		

> Thank you for this. I shall try find some sample code to work from.
> 
> In order to help my understanding, can you explain why I can get the true destination details for TCP using ipfw fwd but not UDP?



Not really sure why, but in the scenario you described you should definitely use divert mechanism as its been implemented/optimized for precisely this purpose.


----------

