This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129ENCPDT: ARP protocol implementation using raw sockets in ethernet

Part Number: TM4C129ENCPDT
Other Parts Discussed in Thread: CC3100

Hi All,

I am using TI RTOS and tm4c129encpdt mnicrocontroller. I had a requirement where I wanted to find the mac address of a device using its ip address. As per this example,

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/845693/cc3200-gratuitous-arp-using-raw-socket/3132843#3132843

I have done it in wifi project which uses cc3100.

But now I have an ethernet project too and wanted to do the same thing there. I was trying but I am not able to make this work. I replaced the socket api calls with ethernet socket api. 

Let me know if someone can fix this. 

Attaching code for ethernet. (For wifi code, one ccan visit the above provided link as the whole code is working fine for cc3100).

void Wireless_Build_Arp_Packet(char* buf, unsigned char * src_mac, unsigned char *src_ip,
										  unsigned char * dest_mac, unsigned char *dest_ip)
{
    struct arp_hdr* arp1;
    struct arp_ethip* ethip;
    struct arp_eth_hdr* ethhdr1;

    unsigned char eth_type[2] = {0x08, 0x06}; // for arp
//    unsigned char eth_type[2] = {0x80, 0x35};  // for rarp

    ethhdr1 = (struct arp_eth_hdr*)buf;
    memcpy(ethhdr1->dst_mac, dest_mac, ETH_ADDR_LEN);
    memcpy(ethhdr1->src_mac, src_mac, ETH_ADDR_LEN);
    memcpy(ethhdr1->type, eth_type, 2);


    arp1 = (struct arp_hdr*)(buf+ ETH_HDR_LEN);
    arp1->ar_hrd = sl_Htons(ARP_HRD_ETH);
    arp1->ar_pro = sl_Htons(ARP_PRO_IP);
    arp1->ar_hln = ETH_ADDR_LEN;
    arp1->ar_pln = IP_ADDR_LEN;
    arp1->ar_op = sl_Htons(ARP_HRD_ETH);

    ethip = (struct arp_ethip*)(buf + ARP_HDR_LEN + ETH_HDR_LEN);
    memcpy(ethip->ar_sha, src_mac, ETH_ADDR_LEN);
    memcpy(ethip->ar_spa, src_ip, IP_ADDR_LEN);
    memcpy(ethip->ar_tha, dest_mac, ETH_ADDR_LEN);
    memcpy(ethip->ar_tpa, dest_ip, IP_ADDR_LEN);
}


void Wireless_Decode_Arp_Packet(char* buf){

    struct arp_hdr* arp1;
    struct arp_ethip* ethip;
    struct arp_eth_hdr* ethhdr1;

    ethhdr1 = (struct arp_eth_hdr*)buf;

    // Mac address we were trying to get..
    // Need to return this using pointers
	logAsHexStr("Dest Mac address------ %s", "", ethhdr1->src_mac,6);

    arp1 = (struct arp_hdr*)(buf+ ETH_HDR_LEN);
    ethip = (struct arp_ethip*)(buf + ARP_HDR_LEN + ETH_HDR_LEN);
 //   UART_PRINT("\n\rGot ARP response!\n\r");
 //   UART_PRINT("\n\rIP addr %i.%i.%i.%i ",ethip->ar_spa[0],ethip->ar_spa[1],ethip->ar_spa[2],ethip->ar_spa[3]);
 //   UART_PRINT("maps to MAC addr %x:%x:%x:%x:%x:%x!\n\r",ethip->ar_sha[0],ethip->ar_sha[1],ethip->ar_sha[2],ethip->ar_sha[3],ethip->ar_sha[4],ethip->ar_sha[5]);






//    struct arp_hdr* arp1;
//    struct arp_ethip* ethip;
//    struct arp_eth_hdr* ethhdr1;
//
//    char d_ipAdd[6] = {0};
//    char d_mac[8] = {0};
//
//    strncpy(buf+26, d_ipAdd, 4);
//
//
//
//   // ethhdr1 = (struct arp_ethip*)buf;
//    ethhdr1 = (struct arp_eth_hdr*)buf;
//
//
//    strncpy(ethhdr1->src_mac, d_mac, 6);
//
//	logAsHexStr("Dest Mac address------ %s", "", ethhdr1->src_mac, 6);
//	logStr("Dest IP add -------- %s", "", d_ipAdd);
//	logAsHexStr("Dest ip address in hex ------ %s", "", d_ipAdd, 4);
//
////
//
//
////
////	 ethip = (struct arp_ethip*)(buf+ ETH_HDR_LEN);
////	 arp1 = (struct arp_hdr*)(buf + ARP_HDR_LEN + ETH_HDR_LEN);
//
//    arp1 = (struct arp_hdr*)(buf+ ETH_HDR_LEN);
//    ethip = (struct arp_ethip*)(buf + ARP_HDR_LEN + ETH_HDR_LEN);
// //   UART_PRINT("\n\rGot ARP response!\n\r");
// //   UART_PRINT("\n\rIP addr %i.%i.%i.%i ",ethip->ar_spa[0],ethip->ar_spa[1],ethip->ar_spa[2],ethip->ar_spa[3]);
// //   UART_PRINT("maps to MAC addr %x:%x:%x:%x:%x:%x!\n\r",ethip->ar_sha[0],ethip->ar_sha[1],ethip->ar_sha[2],ethip->ar_sha[3],ethip->ar_sha[4],ethip->ar_sha[5]);
//

}
char buf4[200];
void arp_protocol( unsigned char *s_mac, unsigned char *s_ip, unsigned char  *d_mac, unsigned char *d_ip)
{
    int fd, ret, len;
    uint32_t header = 1;

    //SlTimeval_t tTimeout;
   // fd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); // working for wifi

    fd = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    Wireless_Build_Arp_Packet(buf4, s_mac, s_ip, d_mac, d_ip);
    len = ARP_HDR_LEN + ARP_ETHIP_LEN + ETH_HDR_LEN;
    ret = send(fd, buf4, len, 0);
	__delay_cycles(5000000000);

	logg("recv arp packet....", "");
    ret = recv(fd, buf4, 200,0);
	logg(" arp done... now decoding....", "");
    Wireless_Decode_Arp_Packet(buf4);
    close(fd);
}

Seems like this is not working because in this line- in above code,

    fd = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

we don't have proper macros. (Please take reference from the above link).

Thanks

  • Hi,

    i'm not an TI-RTOS NDK expert. Is arp_protocol() a task created by another task? I wonder if the problem is due to missing autoOpenCloseFD=true in the .cfg file. If you don't have autoOpenCloseFD=true then you must insert the call to fdPpenSession() and fdCloseSession() to open and close the socket session. Please see the details in the API user's guide.  Go to section 3.1.2.1 for details. Also see the below note in the screenshot. autoOpenCloseFD only works for dynamically created tasks from another running task. 

    http://software-dl.ti.com/simplelink/esd/simplelink_msp432e4_sdk/2.30.00.14/docs/ndk/NDK_API_Reference.html

  • Hi Charles, 

    The arp_protocol() is a function being called when I wanted to do arp.

    My main concern is how to implement ARP protocol in ethernet? For cc3100, it is all working fine. 

    In cc3100, if you see the code and the link, it uses the raw sockets mainly. We ourselves are creating the whole packet structure for the arp protocol and then sending this packet.

    The same thing I wanted to do in the ethernet but it is not working. 

    Can you please try this code in ethernet? Or, do you have any example of ARP protocol in ethernet?

    Thanks

    AKhiG

  • In cc3100, if you see the code and the link, it uses the raw sockets mainly. We ourselves are creating the whole packet structure for the arp protocol and then sending this packet.

    For TM4C129 you are creating the whole packet structure for the arp protocol. Is this the same packet structure for cc3100?

    I'm really not an ARP protocol expert. What I will suggest is that you take a working Ethernet example like the tcpEcho example. There are a few Ethernet example that you can download from Resource Explorer. 

    Normally, the examples will handle ARP automatically. Use the wireshark to look at how the ARP packet is constructed. Next run your own code and see how your ARP packet differs from the working example in wireshark.

      Sorry for lack of guidance as my knowledge on ARP is limited. 

  • Hi

    For TM4C129 you are creating the whole packet structure for the arp protocol. Is this the same packet structure for cc3100?

    Yes.

    My point is- if we are able to create and send the raw packet ( arp packet sending and receiving all good) using cc3100, it should work in ethernet too? 

    But in ethernet, it is not working. 

    This arp thing is completly different from normal http or echo we do. Here the whole packet is created by us.

    Can you try this at your end too?

    Thanks

  • Here is one article showing how ARP works. I'm also learning as I speak. Why don't you show your wireshark capture of the ARP packet you send? You can check if it is matching the format as explained in this article. Also is the IP address you are sending the ARP packet to is on the same network or a different network?

    https://www.practicalnetworking.net/series/arp/traditional-arp/

    Also check what to expect on the wireshark for a ARP packet. 

    https://wiki.wireshark.org/AddressResolutionProtocol