Need help! Raw ethernet socket question

Discussion in 'Linux Networking' started by Michael Mueller, Oct 7, 2003.

  1. Hi Stefanus,
    Use the if_nametoindex() function declared in <net/if.h> to obtain the
    index for a given interface name. The index is not hardcoded by the
    interface name but depends on the initialization order.


    Michael
     
    Michael Mueller, Oct 7, 2003
    #1
    1. Advertisements

  2. Hi,

    I am writing a code to send/recv custom ethernet frames on Linux over
    wireless ad hoc network. The function to receive frames seems to work as
    it can receive packets sent by ping, however the send function doesnt work.

    1. I use struct sockaddr_ll to specify destination address, but whenever
    I set the field sockaddr_ll.sll_ifindex = 0 to use eth0, the sendto()
    function failed to sent and returns -1. And if I set it to 1 to use
    eth1, sendto() seems to work fine and return the number of bytes sent. I
    looked up the man page for packet(7) and it said that sll_ifindex = 0 is
    used to match any interface and only legal for binding. Then how do you
    set sockaddr_ll to use eth0? I tried to set ifindex = 0 anyway and bind
    it with the socket descriptor, but sendto() also failed. Can anybody
    enlighten me?

    2. When I use eth1, sendto() seems to send the frame succesfully, but
    the other device waiting for the frame never receives it. However when I
    use ping, it receives the frame, which means the receive function is
    working. Does anybody know why it couldn't receive the frame sent by
    sendto()?

    I include the code for sending the frame.
    Thank you so much for your help and your time.

    -Stefanus


    Here's the code for sending the frame, in main() I initialized
    s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

    void initSocketAddress(struct sockaddr_ll* socket_address){
    struct ifreq ifr;
    int i;

    /*prepare sockaddr_ll*/
    /*RAW communication*/
    socket_address->sll_family = AF_PACKET;
    socket_address->sll_protocol = 0;
    socket_address->sll_ifindex = 0; /*ifindex = 0 only legal for
    binding?*/
    socket_address->sll_hatype = 0;
    socket_address->sll_pkttype = 0;
    /*address length*/
    socket_address->sll_halen = ETH_ALEN;

    /*MAC*/
    for(i = 0; i < 6; i++){
    socket_address->sll_addr = dest_mac;
    }
    socket_address->sll_addr[6] = 0x00;/*not used*/
    socket_address->sll_addr[7] = 0x00;/*not used*/

    /*Get source MAC*/
    memset(&ifr, 0x00, sizeof(ifr));
    strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
    if(ioctl(s, SIOCGIFHWADDR, &ifr) < 0){
    printf("Fail to get hw addr\n");
    exit(0);
    }

    for(i = 0; i < 6; i++){
    src_mac = (unsigned char)ifr.ifr_hwaddr.sa_data;
    }

    /*bind socket with socket_address*/
    /*
    if(bind(s, (struct sockaddr*)socket_address, sizeof(struct
    sockaddr_ll))<0){
    printf("Binding error\n");
    exit(0);
    }
    */
    }

    /* Send a RAW ethernet frame */
    int sendFrame(){
    int result = 0;
    struct sockaddr_ll socket_address;

    /*pointer to ethernet header*/
    unsigned char* etherhead = buffer;
    /*another pointer to ethernet header*/
    struct ethhdr *eh = (struct ethhdr *)etherhead;
    /*userdata in ethernet frame*/
    unsigned char* data = etherhead + ETH_HLEN;
    /*test string*/
    char* testStr = "Hello world";

    initSocketAddress(&socket_address);

    /*set the frame header*/
    memcpy((void*)eh->h_dest, (void*)dest_mac, ETH_ALEN);
    memcpy((void*)eh->h_source, (void*)src_mac, ETH_ALEN);
    eh->h_proto = 0x00;
    /*fill the frame with some data*/
    memcpy((void*)data, (void*)testStr, strlen(testStr));

    /*send the packet*/
    result = sendto(s, buffer, ETH_FRAME_LEN, 0,
    (struct sockaddr*)&socket_address, sizeof(socket_address));
    if (result == -1){
    printf("Sending packet failed!\n");
    }

    #ifdef DEBUG
    printf("Sent %d bytes\n", result);
    #endif

    return 0;
    }
     
    Stefanus Johny, Oct 7, 2003
    #2
    1. Advertisements

  3. That really helps!!!
    Now everything works.
    Thanks a lot Mike.
     
    Stefanus Johny, Oct 7, 2003
    #3
    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.