Search code examples
c++linuxraw-sockets

raw socket error with sendto: no error code [was: raw socket error with sendto: no such device]


im stuck with sending a raw ethernet frame.

[edit]
I found some errors.
1. It has to be AF_PACKET in the socket call.
2. AF_PACKET doesnt have an option SOCK_PACKET, but SOCK_DGRAM and SOCK_RAW

With SOCK_DGRAM wireshark captures a malformed LLC packet.
But with SOCK_RAW no error message and no captured packet.

i dont find whats really going wrong.
[/edit]

the code:

if ((ethernet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
    cout << "Ethernet Socket: "<< strerror(errno) << endl;

struct sockaddr_ll socket_address;
socket_address.sll_family   = PF_PACKET;
socket_address.sll_protocol = htons(ETH_P_IP);
socket_address.sll_ifindex=if_nametoindex("eth0");
socket_address.sll_hatype   = 1; // ARPHRD_ETHER
socket_address.sll_pkttype  = PACKET_OTHERHOST;
socket_address.sll_halen    = ETH_ALEN;
memcpy(socket_address.sll_addr,dest_mac_addr,ETH_ALEN);

int send_result = 0;

char *opt=(char*)malloc(4*sizeof(char));
strcpy(opt,"eth0");

if(setsockopt(ethernet_socket, SOL_SOCKET, SO_BINDTODEVICE, opt, 4)==-1)
    cout << "Could not bind socket to device: " << strerror(errno) << endl;

if ((send_result  
= sendto(ethernet_socket, &buffer, sizeof(buffer), 0,  
    (struct sockaddr*)&socket_address, sizeof(socket_address)))==-1){
        cout << "sendto error: "<< strerror(errno) << endl;
        return send_result;
}

regards Ck


Solution

  • I found the solution how this works. i took a look at the source code of the Linux program PackEth.

    the following code works for me.

    if ((ethernet_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
        cout << "Ethernet Socket: "<< strerror(errno) << endl;  //errorhandling
    
    memset(&ifr, 0, sizeof(ifr));
    strncpy (ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
    ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
    
    
    if (ioctl(ethernet_socket, SIOCGIFINDEX, &ifr) == -1) {
        cout << "No such interface:"<< strerror(errno) << endl;
        close(ethernet_socket);
    }
    
    ioctl(ethernet_socket, SIOCGIFFLAGS, &ifr);
    if ( (ifr.ifr_flags & 0x1) == 0) {
        cout << "Interface is down: "<< strerror(errno) << endl;
        close(ethernet_socket);
    }
    
    ioctl(ethernet_socket, SIOCGIFINDEX, &ifr);
    
    
    memset(&socket_address, 0, sizeof (socket_address));
    socket_address.sll_family    = AF_PACKET;
    socket_address.sll_ifindex   = ifr.ifr_ifindex;
    socket_address.sll_protocol  = htons(ETH_P_ALL);
    
    if ((raw_send = sendto(ethernet_socket, buffer, size_payload+14,0,(struct     sockaddr*)     
                               &socket_address, sizeof(socket_address)))==-1){
        cout << "sendto error: "<< strerror(errno) << endl;
        return raw_send;
    }