数据结构

在 netinet/if_ether.h 中

struct  ether_arp {
        struct  arphdr ea_hdr;          /* fixed-size header */
        u_int8_t arp_sha[ETH_ALEN];     /* sender hardware address */
        u_int8_t arp_spa[4];            /* sender protocol address */
        u_int8_t arp_tha[ETH_ALEN];     /* target hardware address */
        u_int8_t arp_tpa[4];            /* target protocol address */
};

struct arphdr 在 net/if_arp.h 中

struct arphdr
  {
    unsigned short int ar_hrd;          /* Format of hardware address.  */
    unsigned short int ar_pro;          /* Format of protocol address.  */
    unsigned char ar_hln;               /* Length of hardware address.  */
    unsigned char ar_pln;               /* Length of protocol address.  */
    unsigned short int ar_op;           /* ARP opcode (command).  */
#if 0
    /* Ethernet looks like this : This bit is variable sized
       however...  */
    unsigned char __ar_sha[ETH_ALEN];   /* Sender hardware address.  */
    unsigned char __ar_sip[4];          /* Sender IP address.  */
    unsigned char __ar_tha[ETH_ALEN];   /* Target hardware address.  */
    unsigned char __ar_tip[4];          /* Target IP address.  */
#endif
  };

链路层的头部信息在 net/ethernet.h 中

struct ether_header
{ 
  u_int8_t  ether_dhost[ETH_ALEN];      /* destination eth addr */
  u_int8_t  ether_shost[ETH_ALEN];      /* source ether addr    */
  u_int16_t ether_type;                 /* packet type ID field */
} __attribute__ ((__packed__));
###注意字节对齐

链路层套接字地址结构 位于netpacket/packet.h头文件中

struct sockaddr_ll
  {
    unsigned short int sll_family;       // 总是AF_PACKET
    unsigned short int sll_protocol;  // 物理层协议
    int sll_ifindex;   // 接口号
    unsigned short int sll_hatype;    // 报文类型
    unsigned char sll_pkttype;    // 分组类型,用于区分广播、组播、单播
    unsigned char sll_halen;    //  地址长度
    unsigned char sll_addr[8];   // 物理层地址
  };

/* Packet types.  */

#define PACKET_HOST             0               /* To us.  */
#define PACKET_BROADCAST        1               /* To all.  */
#define PACKET_MULTICAST        2               /* To group.  */
#define PACKET_OTHERHOST        3               /* To someone else.  */
#define PACKET_OUTGOING         4               /* Originated by us . */
#define PACKET_LOOPBACK         5
#define PACKET_FASTROUTE        6

实现

  1. 定义arp结构体,包含ether头

  2. 创建原始套接字

    socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP))

  3. 对于原始套接字,需要创建struct sockaddr_ll地址结构, 特别注意

文档更新时间: 2021-02-04 21:59   作者:周国强