Sending raw ip on multihomed host

Discussion in 'Linux Networking' started by Robin, Feb 10, 2004.

  1. Robin

    Robin Guest

    This is a "getlocaladdr" problem.

    I've implemented a "virtual applikation server" that will take packets and
    send them to another host based on port numbers, thus working as both
    client and server to make a session work (like a man in the middle)..

    The problem is to support this funktionality on a multihomed host (a host
    with more than one network card).. since I don't know what source address
    to use when sending packets.

    I'm using a raw socket like this for sending:
    m_sock = socket(PF_INET, SOCK_RAW, htons(IPPROTO_RAW));
    // -------------> Also tried AF_INET
    const int on = 1;
    setsockopt(m_sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));

    According to man page the following holds for raw sockets with IP_HDRINCL
    +------------------------------------------------------------------+
    |IP Header fields modified on sending when IP_HDRINCL is specified |
    +------------------------------------------------------------------+
    | Sending fragments with IP_HDRINCL is not supported currently. |
    +--------------------------+---------------------------------------+
    |IP Checksum |Always filled in. |
    +--------------------------+---------------------------------------+
    |Source Address |Filled in when zero. |
    +--------------------------+---------------------------------------+
    |Packet Id |Filled in when passed as 0. |
    +--------------------------+---------------------------------------+
    |Total Length |Always filled in. |
    +--------------------------+---------------------------------------+

    But the kernel don't fill in the source when i zero it out in the header.
    I'm using the following sendto.

    sockaddr_in toAddr = packet.getDestinationHost();
    toAddr.sin_family = AF_INET;
    return sendto(m_sock,
    (void *) packet.getBuffer(), /* "const void* msg" */
    packet.get_ip_len(),
    0,
    (sockaddr *) &toAddr,
    sizeof(struct sockaddr_in)); /* "socklen_t tolen" */

    It works fine when I specify the correct source address in the packet so I
    must be doing atleast some of it right..

    I zero it out like this...

    in_addr sourceAddr;
    bzero(&sourceAddr, sizeof(in_addr));
    _packet.set_ip_src(sourceAddr);

    but the address wont be filled in after send... I guess that I actually send
    a packet with source address = 0.0.0.0

    I would be so very happy if someone could point out what I'm doing wrong or
    help me in some other way to dynamicly find out the correct source IP based
    on the destination address..
    I've considered to just send the packet out on all networks just to be safe
    but that just doesn't seem right.

    I'm using Mandrake 9.0: Kernel 2.4.19(Patched with IPDIVERT); Glibc 2.2.5

    Thanks
     
    Robin, Feb 10, 2004
    #1
    1. Advertisements

  2. Robin

    Cameron Kerr Guest

    You know about the Linux Virtual Server component of 2.6 kernels?
    Follow this psuedocode:

    for every network device that is UP:
    create a socket for this device
    store the devices source address
    add it to a list of sockets to select on.
    select on all of the sockets waiting for readablity
    use the stored address for the source address.

    Alternatively, you may be able to use recvmsg and sendmsg, but I don't
    know if that would work with raw IP
     
    Cameron Kerr, Feb 11, 2004
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.