|
||||||||
|
|
|||||||
![]() |
|
|
Thread Tools | Display Modes |
|
#1
|
|
Hi Stefanus,
you wrote: > 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? 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 -- Linux@TekXpress http://www-users.rwth-aachen.de/Mich...kxp/tekxp.html Michael Mueller |
|
#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[i] = dest_mac[i]; } 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[i] = (unsigned char)ifr.ifr_hwaddr.sa_data[i]; } /*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; } |
|
#3
|
|||
|
|||
|
That really helps!!!
Now everything works. Thanks a lot Mike. |
![]() |
| Tags |
| ethernet, question, raw, socket |
| Thread Tools | |
| Display Modes | |
|
|