arp数据包结构

struct arp_packet {
    // DLC header
    uint8_t mac_target[ETHER_ADDR_LEN];
    uint8_t mac_source[ETHER_ADDR_LEN];
    uint16_t ether_type;

    // arp header
    uint16_t hw_type;    // 硬件类型
    uint16_t proto_type;  // 协议类型
    uint8_t mac_addr_len;  // 硬件地址长度
    uint8_t ip_addr_len;   // 协议地址长度
    uint16_t opcode;    // 操作码
    uint8_t mac_sender[ETHER_ADDR_LEN];  // 发送端mac地址
    uint8_t ip_sender[4];   // 发送端ip地址
    uint8_t mac_receiver[ETHER_ADDR_LEN];  // 接收端mac地址
    uint8_t ip_receiver[4];   // 接收端ip地址

   /*padding字节 用于构造最小的以太网数据包60字节, 实现发现没有什么作用*/
   uint8_t padding[18]; // 做padding
};

核心主流程

int main(int argc, char **argv) {
    char ifname[IF_NAMESIZE];
    char dstaddr[IF_NAMESIZE];
    struct ifi_rinfo *rinfo;
    struct sockaddr_ll peer_addr;
    int sockfd;
    // 解析参数
    if (arp_get_options(argc, argv, ifname, dstaddr) < 0) {
        return ARP_ERROR;
    }
    // 获取接口信息
    if ((rinfo=get_ifi_rinfo(ifname)) == NULL) {
        return ARP_ERROR;
    }
    // 检查接口是否支持arp包
    if (check_flags(rinfo) < 0) {
        return ARP_ERROR;
    }
    // 创建AF_PACKET套接字
    if( (sockfd = sockraw(0)) < 0) {
        return ARP_ERROR;
    }
    // 初始化发送信息
    memset(&peer_addr, 0, sizeof(struct sockaddr_ll));
    peer_addr.sll_family = AF_PACKET;
    peer_addr.sll_ifindex = rinfo->ifindex;

    ARP_BEGIN(dstaddr, rinfo->ipaddr_str, ifname);
    // 发送arp报文
    arp_send(sockfd, rinfo, dstaddr, &peer_addr);
    // 接收arp报文
    arp_recv(sockfd, rinfo, dstaddr);
    // 关闭套接字
    free(rinfo);
    close(sockfd);
    return 0;
}
文档更新时间: 2021-02-04 19:10   作者:周国强