On Mon, 10 Sep 2001, Christopher Friesen wrote:
> Padraig Brady wrote:
> > I'm writing a network app (currently on linux 2.2.18,
> > but soon moving to 2.4) that needs to build up ip &
> > tcp packets manually. So my question is how do I determine
> > the source ip address to use for a given destination
> > ip address. I.E. take account of multiple interfaces/routes/
> > aliases/...
> How low in the protocol stack are you going? If you use an IP raw socket with
> IP_HDRINCL and just leave the sending address filled with zeros, then it will
> filled in with the default address for the link used to send to the
> address. See the man page on raw(4) for more details.
Looking in udp_sendmsg and raw_sendmsg() I don't see the
saddr argument in the route lookup call to depend on the IP_HDRINCL
option (which is an raw socket option only). The same mistake (as your
assumption) you can see in the (latest?) traceroute-1.4a12 where bind()
is surrounded in #ifndef IP_HDRINCL. As result bind() is not called and
the packets go to wrong route.
As for the question from Padraig: you have to create SOCK_DGRAM
socket, then to connect() it to the target address (any port), then to
get the generated source address from the kernel by calling getsockname().
Now you have the source that the kernel usually uses to talk with the
specified target. Then you have to create the actual data socket and to
call bind() for the source address from the previous step and then to
connect()/sendto() to the newly created socket. Without bind() your
data will not be routed considering the source address in the IP
header. Such routing problem is usually noticed when you have two or more
routes to the universe. If you send with different source addresses
from one socket then the handling will be more complex. May be then you
have to play with IP_PKTINFO. My man page is incorrect here, it claims that
ipi_spec_dst contains the destination address but raw_sendmsg uses it as
source address. The oif value is correctly used. The only problem may be
is that IP_PKTINFO should be called before sending each packet. So, may be
there is no way to specify different source address (for the routing call)
in sendmsg(). You have to change it with IP_PKTINFO call each time.
Julian Anastasov <ja@xxxxxx>