linux - arp request and reply using c socket programming

Linux - arp request and reply using c socket programming

To perform ARP request and reply handling using C socket programming on Linux, you'll typically interact with raw sockets and construct ARP packets manually. Here's a simplified example to demonstrate how you can send an ARP request and process ARP replies using C:

ARP Packet Structure

ARP (Address Resolution Protocol) packets consist of various fields, including Ethernet and ARP headers. Here's a basic structure of an ARP packet:

  • Ethernet Header:

    • Destination MAC Address (6 bytes)
    • Source MAC Address (6 bytes)
    • Ethernet Type (2 bytes, usually 0x0806 for ARP)
  • ARP Header:

    • Hardware Type (2 bytes, e.g., 0x0001 for Ethernet)
    • Protocol Type (2 bytes, e.g., 0x0800 for IPv4)
    • Hardware Address Length (1 byte, e.g., 6 for MAC addresses)
    • Protocol Address Length (1 byte, e.g., 4 for IPv4)
    • Opcode (2 bytes, 0x0001 for ARP request, 0x0002 for ARP reply)
    • Sender Hardware Address (6 bytes)
    • Sender Protocol Address (4 bytes)
    • Target Hardware Address (6 bytes, often zero in requests)
    • Target Protocol Address (4 bytes)

Example Code

Here's a simplified example to send an ARP request and handle the ARP reply using raw sockets in C:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <net/if.h> #include <net/ethernet.h> #include <sys/ioctl.h> #include <errno.h> // Ethernet header length: 14 bytes #define ETHER_HEADER_LEN 14 // ARP header length: 28 bytes #define ARP_HEADER_LEN 28 // ARP opcode for request and reply #define ARP_REQUEST 1 #define ARP_REPLY 2 // Structure for ARP header struct arp_header { unsigned short hardware_type; // Hardware type (e.g., Ethernet = 1) unsigned short protocol_type; // Protocol type (e.g., IPv4 = 0x0800) unsigned char hardware_len; // Hardware address length (e.g., 6 for MAC) unsigned char protocol_len; // Protocol address length (e.g., 4 for IPv4) unsigned short opcode; // ARP operation code (e.g., request = 1, reply = 2) unsigned char sender_mac[6]; // Sender MAC address unsigned char sender_ip[4]; // Sender IP address unsigned char target_mac[6]; // Target MAC address unsigned char target_ip[4]; // Target IP address }; // Function to create and send ARP request void send_arp_request(const char *interface, const char *target_ip) { int sock; struct ifreq ifr; struct sockaddr_ll socket_address; unsigned char src_mac[6]; struct arp_header arp_hdr; // Create a raw socket if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) < 0) { perror("Socket creation failed"); return; } // Get interface MAC address memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl() failed to get source MAC address"); close(sock); return; } memcpy(src_mac, ifr.ifr_hwaddr.sa_data, 6); // Construct ARP request memset(&arp_hdr, 0, sizeof(struct arp_header)); arp_hdr.hardware_type = htons(ARPHRD_ETHER); // Ethernet hardware type arp_hdr.protocol_type = htons(ETH_P_IP); // Protocol type (IPv4) arp_hdr.hardware_len = 6; // Ethernet MAC address length arp_hdr.protocol_len = 4; // IPv4 address length arp_hdr.opcode = htons(ARP_REQUEST); // ARP request // Sender MAC and IP address memcpy(arp_hdr.sender_mac, src_mac, 6); inet_pton(AF_INET, "192.168.1.1", arp_hdr.sender_ip); // Target MAC (not used in ARP request) memset(arp_hdr.target_mac, 0, 6); // Target IP address (ARP request target) inet_pton(AF_INET, target_ip, arp_hdr.target_ip); // Fill socket address struct memset(&socket_address, 0, sizeof(socket_address)); socket_address.sll_ifindex = if_nametoindex(interface); socket_address.sll_family = AF_PACKET; memcpy(socket_address.sll_addr, src_mac, 6); socket_address.sll_halen = htons(6); socket_address.sll_protocol = htons(ETH_P_ARP); // Send ARP request if (sendto(sock, &arp_hdr, ARP_HEADER_LEN, 0, (struct sockaddr*)&socket_address, sizeof(socket_address)) < 0) { perror("ARP request sendto failed"); } else { printf("ARP request sent.\n"); } close(sock); } int main() { send_arp_request("eth0", "192.168.1.2"); // Example interface and target IP return 0; } 

Explanation:

  • Socket Creation: Creates a raw socket (AF_PACKET, SOCK_RAW) specifically for ARP (ETH_P_ARP).
  • Interface and MAC Address Retrieval: Uses ioctl() with SIOCGIFHWADDR to retrieve the MAC address of the specified network interface (eth0 in this example).
  • ARP Packet Construction: Constructs an ARP packet (struct arp_header) with appropriate fields filled, including sender MAC and IP addresses, target IP address, and opcode (ARP_REQUEST).
  • Socket Address (sockaddr_ll): Sets up the socket address structure (sockaddr_ll) with interface index, MAC address, protocol, etc.
  • Sending ARP Request: Uses sendto() to send the constructed ARP request packet.

Notes:

  • Permissions: Running socket operations typically requires superuser (root) privileges due to raw socket usage.
  • Error Handling: Includes basic error handling using perror() for socket operations.
  • ARP Reply Handling: To handle ARP replies, you would typically set up a receive loop (recvfrom()) to capture incoming ARP packets and parse them accordingly.

This example demonstrates the basic concept of sending an ARP request using raw sockets in C on Linux. Adjustments may be needed based on your specific network configuration and requirements.

Examples

  1. Linux C socket programming ARP request example

    • Description: Implementing ARP request functionality in C on Linux using socket programming.
    • Code:
      #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <net/if.h> #include <netpacket/packet.h> #include <arpa/inet.h> #define ETHERTYPE_ARP 0x0806 int main() { int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (sock < 0) { perror("Socket creation failed"); return 1; } // Construct ARP request struct ether_header eth_header; struct ether_arp arp_packet; struct sockaddr_ll addr; unsigned char dest_mac[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Broadcast MAC address // Populate Ethernet header memset(&eth_header, 0, sizeof(eth_header)); memcpy(eth_header.ether_dhost, dest_mac, ETH_ALEN); eth_header.ether_type = htons(ETHERTYPE_ARP); // Populate ARP header arp_packet.arp_hrd = htons(ARPHRD_ETHER); arp_packet.arp_pro = htons(ETH_P_IP); arp_packet.arp_hln = ETH_ALEN; arp_packet.arp_pln = 4; arp_packet.arp_op = htons(ARPOP_REQUEST); memset(&arp_packet.arp_tha, 0, ETH_ALEN); // Target hardware address memcpy(&arp_packet.arp_sha, &eth_header.ether_shost, ETH_ALEN); // Sender hardware address inet_pton(AF_INET, "192.168.1.1", &arp_packet.arp_tpa); // Target IP address inet_pton(AF_INET, "192.168.1.2", &arp_packet.arp_spa); // Sender IP address // Populate socket address structure memset(&addr, 0, sizeof(addr)); addr.sll_family = AF_PACKET; addr.sll_ifindex = if_nametoindex("eth0"); // Interface index addr.sll_protocol = htons(ETH_P_ARP); addr.sll_halen = ETH_ALEN; memcpy(addr.sll_addr, dest_mac, ETH_ALEN); // Send ARP request if (sendto(sock, &arp_packet, sizeof(arp_packet), 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Send failed"); return 1; } printf("ARP request sent.\n"); close(sock); return 0; } 
  2. Linux C socket programming ARP reply example

    • Description: Implementing ARP reply functionality in C on Linux using socket programming.
    • Code:
      #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <net/if.h> #include <netpacket/packet.h> #include <arpa/inet.h> #define ETHERTYPE_ARP 0x0806 int main() { int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (sock < 0) { perror("Socket creation failed"); return 1; } // Construct ARP reply struct ether_header eth_header; struct ether_arp arp_packet; struct sockaddr_ll addr; unsigned char dest_mac[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Broadcast MAC address // Populate Ethernet header memset(&eth_header, 0, sizeof(eth_header)); memcpy(eth_header.ether_dhost, dest_mac, ETH_ALEN); eth_header.ether_type = htons(ETHERTYPE_ARP); // Populate ARP header arp_packet.arp_hrd = htons(ARPHRD_ETHER); arp_packet.arp_pro = htons(ETH_P_IP); arp_packet.arp_hln = ETH_ALEN; arp_packet.arp_pln = 4; arp_packet.arp_op = htons(ARPOP_REPLY); memcpy(&arp_packet.arp_tha, &eth_header.ether_dhost, ETH_ALEN); // Target hardware address memcpy(&arp_packet.arp_sha, &eth_header.ether_shost, ETH_ALEN); // Sender hardware address inet_pton(AF_INET, "192.168.1.2", &arp_packet.arp_tpa); // Target IP address inet_pton(AF_INET, "192.168.1.1", &arp_packet.arp_spa); // Sender IP address // Populate socket address structure memset(&addr, 0, sizeof(addr)); addr.sll_family = AF_PACKET; addr.sll_ifindex = if_nametoindex("eth0"); // Interface index addr.sll_protocol = htons(ETH_P_ARP); addr.sll_halen = ETH_ALEN; memcpy(addr.sll_addr, dest_mac, ETH_ALEN); // Send ARP reply if (sendto(sock, &arp_packet, sizeof(arp_packet), 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Send failed"); return 1; } printf("ARP reply sent.\n"); close(sock); return 0; } 
  3. Linux C socket programming receive ARP request

    • Description: Writing a C program on Linux to receive ARP requests using socket programming.
    • Code:
      #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <net/if.h> #include <netpacket/packet.h> #define ETHERTYPE_ARP 0x0806 int main() { int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (sock < 0) { perror("Socket creation failed"); return 1; } while (1) { struct ether_arp arp_packet; ssize_t len = recvfrom(sock, &arp_packet, sizeof(arp_packet), 0, NULL, NULL); if (len < 0) { perror("Receive failed"); continue; } if (ntohs(arp_packet.ea_hdr.ar_pro) == ETHERTYPE_ARP && ntohs(arp_packet.ea_hdr.ar_op) == ARPOP_REQUEST) { printf("Received ARP request:\n"); printf("Sender MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", arp_packet.arp_sha[0], arp_packet.arp_sha[1], arp_packet.arp_sha[2], arp_packet.arp_sha[3], arp_packet.arp_sha[4], arp_packet.arp_sha[5]); printf("Sender IP: %d.%d.%d.%d\n", arp_packet.arp_spa[0], arp_packet.arp_spa[1], arp_packet.arp_spa[2], arp_packet.arp_spa[3]); printf("Target IP: %d.%d.%d.%d\n", arp_packet.arp_tpa[0], arp_packet.arp_tpa[1], arp_packet.arp_tpa[2], arp_packet.arp_tpa[3]); } } close(sock); return 0; } 

More Tags

historian discount word-style flask spring-jms git-cherry-pick window-soft-input-mode ecmascript-temporal asp.net-mvc-controller pm2

More Programming Questions

More Auto Calculators

More Housing Building Calculators

More Other animals Calculators

More Geometry Calculators