帮我解读这六段代码,我是初学者,尽量详细并补充相关知识 #ifndef _ARP_RECV_H
#define _ARP_RECV_H
#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/if_ether.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
/* 以太网帧首部长度 /
#define ETHER_HEADER_LEN sizeof(struct ether_header)
/ 整个arp结构长度 /
#define ETHER_ARP_LEN sizeof(struct ether_arp)
/ 以太网 + 整个arp结构长度 /
#define ETHER_ARP_PACKET_LEN ETHER_HEADER_LEN + ETHER_ARP_LEN
/ IP地址长度 */
#define IP_ADDR_LEN 4
void err_exit(const char *err_msg);
#ifndef LOCAL
#define LOCAL static
#endif
#endif。。#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/if_ether.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include"arp_recv.h"
#include “nvmp_utils.h”
#include “nsd_common.h”
#include “libds.h”
#include “libdms.h”
#include “flashio.h”
#include “dms_tool.h”
LOCAL void err_exit(const char *err_msg)
{
perror(err_msg);
exit(1);
}
LOCAL void arp_recv_main()
{
struct ether_arp *arp_packet;
char buf[ETHER_ARP_PACKET_LEN];
int sock_raw_fd, ret_len, i;
if ((sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1) { err_exit(“socket()”); } while (1) { bzero(buf, ETHER_ARP_PACKET_LEN); ret_len = recv(sock_raw_fd, buf, ETHER_ARP_PACKET_LEN, 0); if (ret_len > 0) { /* 剥去以太头部 */ arp_packet = (struct ether_arp )(buf + ETHER_HEADER_LEN); / arp操作码为代表arp应答 */ if (ntohs(arp_packet->arp_op) == 2) { printf(“====ARP replay\n”); printf(“Sender IP address: “); for (i = 0; i < IP_ADDR_LEN; i++) { printf(”%u”, arp_packet->arp_spa[i]); if(i != (IP_ADDR_LEN-1)) { printf(“.”); } } printf(“\nSender MAC address: “); for (i = 0; i < ETH_ALEN; i++) { printf(”%02x”, arp_packet->arp_sha[i]); if(i != (ETH_ALEN-1)) { printf(“😊; } } printf(”\nTarget IP address: “); for (i = 0; i < IP_ADDR_LEN; i++) { printf(”%u", arp_packet->arp_tpa[i]); if(i != (IP_ADDR_LEN-1)) { printf(“.”); } } printf(“\nTarget MAC address: “); for (i = 0; i < ETH_ALEN; i++) { printf(”%02x”, arp_packet->arp_tha[i]); if(i != (ETH_ALEN-1)) { printf(“😊; } } printf(”\n"); } } } close(sock_raw_fd);
}
NSD_INIT(arp_recv_main);。。#ifndef _ARP_REQUEST_H
#define _ARP_REQUEST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <netpacket/packet.h>
/* 以太网帧首部长度 /
#define ETHER_HEADER_LEN sizeof(struct ether_header)
/ 整个arp结构长度 /
#define ETHER_ARP_LEN sizeof(struct ether_arp)
/ 以太网 + 整个arp结构长度 /
#define ETHER_ARP_PACKET_LEN ETHER_HEADER_LEN + ETHER_ARP_LEN
/ IP地址长度 /
#define IP_ADDR_LEN 4
/ 广播地址 */
#define BROADCAST_ADDR
void err_exit(const char *err_msg);
struct ether_arp *fill_arp_packet(const unsigned char *src_mac_addr, const char *src_ip, const char *dst_ip);
void arp_request(const char *if_name, const char *dst_ip);
#endif。。/* Copyright©
*
file arp_request.c
brief This is a work of sending arp request.
author Zhou Shijun
version 1.0.1
date 24Aug28
history
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include"arp_request.h"
void err_exit(const char *err_msg)
{
perror(err_msg);
exit(1);
}
/* 填充arp包 */
struct ether_arp *fill_arp_packet(const unsigned char *src_mac_addr, const char *src_ip, const char *dst_ip)
{
struct ether_arp *arp_packet;
struct in_addr src_in_addr, dst_in_addr;
unsigned char dst_mac_addr[ETH_ALEN] = BROADCAST_ADDR;
/* IP地址转换 / inet_pton(AF_INET, src_ip, &src_in_addr); inet_pton(AF_INET, dst_ip, &dst_in_addr); / 整个arp包 */ arp_packet = (struct ether_arp *)malloc(ETHER_ARP_LEN); arp_packet->arp_hrd = htons(ARPHRD_ETHER); arp_packet->arp_pro = htons(ETHERTYPE_IP); arp_packet->arp_hln = ETH_ALEN; arp_packet->arp_pln = IP_ADDR_LEN; arp_packet->arp_op = htons(ARPOP_REQUEST); memcpy(arp_packet->arp_sha, src_mac_addr, ETH_ALEN); memcpy(arp_packet->arp_tha, dst_mac_addr, ETH_ALEN); memcpy(arp_packet->arp_spa, &src_in_addr, IP_ADDR_LEN); memcpy(arp_packet->arp_tpa, &dst_in_addr, IP_ADDR_LEN); return arp_packet;
}
/* arp请求 */
void arp_request(const char *if_name, const char *dst_ip)
{
struct sockaddr_ll saddr_ll;
struct ether_header *eth_header;
struct ether_arp *arp_packet;
struct ifreq ifr;
char buf[ETHER_ARP_PACKET_LEN];
unsigned char src_mac_addr[ETH_ALEN];
unsigned char dst_mac_addr[ETH_ALEN] = BROADCAST_ADDR;
char *src_ip;
int sock_raw_fd, ret_len, i;
if ((sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1) { err_exit(“socket()”); } bzero(&saddr_ll, sizeof(struct sockaddr_ll)); bzero(&ifr, sizeof(struct ifreq)); /* 网卡接口名 / memcpy(ifr.ifr_name, if_name, strlen(if_name)); / 获取网卡接口索引 / if (ioctl(sock_raw_fd, SIOCGIFINDEX, &ifr) == -1) { err_exit(“ioctl() get ifindex”); } saddr_ll.sll_ifindex = ifr.ifr_ifindex; saddr_ll.sll_family = PF_PACKET; / 获取网卡接口IP */ if (ioctl(sock_raw_fd, SIOCGIFADDR, &ifr) == -1) { err_exit(“ioctl() get ip”); } src_ip = inet_ntoa(((struct sockaddr_in )&(ifr.ifr_addr))->sin_addr); printf(“local ip:%s\n”, src_ip); / 获取网卡接口MAC地址 / if (ioctl(sock_raw_fd, SIOCGIFHWADDR, &ifr)) { err_exit(“ioctl() get mac”); } memcpy(src_mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); printf(“local mac”); for (i = 0; i < ETH_ALEN; i++) { printf(“:%0x”, src_mac_addr[i]); } printf(“\n”); bzero(buf, ETHER_ARP_PACKET_LEN); / 填充以太首部 */ eth_header = (struct ether_header )buf; memcpy(eth_header->ether_shost, src_mac_addr, ETH_ALEN); memcpy(eth_header->ether_dhost, dst_mac_addr, ETH_ALEN); eth_header->ether_type = htons(ETHERTYPE_ARP); / arp包 / arp_packet = fill_arp_packet(src_mac_addr, src_ip, dst_ip); memcpy(buf + ETHER_HEADER_LEN, arp_packet, ETHER_ARP_LEN); / 发送请求 */ ret_len = sendto(sock_raw_fd, buf, ETHER_ARP_PACKET_LEN, 0, (struct sockaddr *)&saddr_ll, sizeof(struct sockaddr_ll)); if (ret_len > 0) { printf(“Send successfully!\n”); } close(sock_raw_fd);
}
LOCAL void arp_request_main(int argc, const char *argv[])
{
if (argc != 3)
{
printf(“usage:%s device_name dst_ip\n”, argv[0]);
exit(1);
}
arp_request(argv[1], argv[2]); return 0;
}
NSD_INIT(arp_request_main);。。#ifndef _ARP_SCAN_H
#define _ARP_SCAN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <time.h>
#include <pthread.h>
/* — 宏定义: 参数默认值 — /
#define ETHER_HEADER_LEN sizeof(struct ether_header)
#define ETHER_ARP_LEN sizeof(struct ether_arp)
#define ETHER_ARP_PACKET_LEN (ETHER_HEADER_LEN + ETHER_ARP_LEN)
#define BROADCAST_ADDR {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
#define IP_ADDR_LEN 4
#define MAX_ARP_ENTRIES 100
/ — 数据结构定义 — */
typedef struct
{
unsigned char mac[ETH_ALEN];
char ip[INET_ADDRSTRLEN];
time_t last_seen;
} arp_entry_t;
typedef struct
{
int enabled; /* 功能开关*/
int scan_interval; /* 扫描周期(秒)/
int entry_lifetime; / 有效期(秒)/
int packet_interval; / 发包间隔(毫秒)/
char start_ip[INET_ADDRSTRLEN];
char end_ip[INET_ADDRSTRLEN];
arp_entry_t arp_entries[MAX_ARP_ENTRIES];
int entry_count; / 当前ARP条目数量*/
pthread_mutex_t lock; /* 互斥锁*/
} arp_config_t;
arp_config_t arp_config = {
.enabled = 1, /* 功能开关开启*/
.scan_interval = 60, /* 扫描周期为60秒*/
.entry_lifetime = 300, /* 有效期为300秒*/
.packet_interval = 100, /* 发包间隔为100毫秒*/
.start_ip = “192.168.1.100”, /* 起始IP*/
.end_ip = “192.168.1.200”, /* 结束IP*/
.entry_count = 0 /初始化ARP条目数量/
};
/* — 函数定义 — */
void err_exit(const char *err_msg);
struct ether_arp *fill_arp_packet(const unsigned char *src_mac_addr, const char *src_ip, const char *dst_ip);
void add_arp_entry(const char *ip, const unsigned char *mac);
void cleanup_arp_entries();
void arp_scan(const char *if_name);
LOCAL int arp_scan_init();
LOCAL int arp_scan_check();
LOCAL int arp_scan_start();
LOCAL int arp_scan_reload(DS_MSG *msg);
LOCAL void arp_scan_main();
#ifndef LOCAL
#define LOCAL static
#endif
#endif。。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <time.h>
#include <pthread.h>
#include “arp_scan.h”
void err_exit(const char *err_msg)
{
perror(err_msg);
exit(1);
}
struct ether_arp *fill_arp_packet(const unsigned char *src_mac_addr, const char *src_ip, const char *dst_ip)
{
struct ether_arp *arp_packet = (struct ether_arp *)malloc(ETHER_ARP_LEN);
unsigned char dst_mac_addr[ETH_ALEN] = BROADCAST_ADDR;
struct in_addr src_in_addr, dst_in_addr;
inet_pton(AF_INET, src_ip, &src_in_addr); inet_pton(AF_INET, dst_ip, &dst_in_addr); arp_packet->arp_hrd = htons(ARPHRD_ETHER); arp_packet->arp_pro = htons(ETHERTYPE_IP); arp_packet->arp_hln = ETH_ALEN; arp_packet->arp_pln = IP_ADDR_LEN; arp_packet->arp_op = htons(ARPOP_REQUEST); memcpy(arp_packet->arp_sha, src_mac_addr, ETH_ALEN); memcpy(arp_packet->arp_tha, dst_mac_addr, ETH_ALEN); memcpy(arp_packet->arp_spa, &src_in_addr, IP_ADDR_LEN); memcpy(arp_packet->arp_tpa, &dst_in_addr, IP_ADDR_LEN); return arp_packet;
}
void add_arp_entry(const char *ip, const unsigned char *mac)
{
pthread_mutex_lock(&arp_config.lock);
if (arp_config.entry_count < MAX_ARP_ENTRIES)
{
strcpy(arp_config.arp_entries[arp_config.entry_count].ip, ip);
memcpy(arp_config.arp_entries[arp_config.entry_count].mac, mac, ETH_ALEN);
arp_config.arp_entries[arp_config.entry_count].last_seen = time(NULL);
arp_config.entry_count++;
}
pthread_mutex_unlock(&arp_config.lock);
}
void cleanup_arp_entries()
{
pthread_mutex_lock(&arp_config.lock);
time_t now = time(NULL);
for (int i = 0; i < arp_config.entry_count; i++)
{
if (now - arp_config.arp_entries[i].last_seen > arp_config.entry_lifetime)
{
// 删除过期条目
for (int j = i; j < arp_config.entry_count - 1; j++)
{
arp_config.arp_entries[j] = arp_config.arp_entries[j + 1];
}
arp_config.entry_count–;
i–; // 调整索引
}
}
pthread_mutex_unlock(&arp_config.lock);
}
void arp_scan(const char *if_name)
{
struct sockaddr_ll saddr_ll;
struct ether_header *eth_header;
struct ether_arp *arp_packet;
struct ifreq ifr;
char buf[ETHER_ARP_PACKET_LEN];
unsigned char src_mac_addr[ETH_ALEN];
char src_ip[INET_ADDRSTRLEN];
int sock_raw_fd;
if ((sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1) err_exit(“socket()”); memset(&saddr_ll, 0, sizeof(struct sockaddr_ll)); memset(&ifr, 0, sizeof(struct ifreq)); memcpy(ifr.ifr_name, “eth0”, strlen(“eth0”)); // 使用默认接口名 if (ioctl(sock_raw_fd, SIOCGIFINDEX, &ifr) == -1) err_exit(“ioctl() get ifindex”); saddr_ll.sll_ifindex = ifr.ifr_ifindex; saddr_ll.sll_family = PF_PACKET; if (ioctl(sock_raw_fd, SIOCGIFADDR, &ifr) == -1) err_exit(“ioctl() get ip”); strcpy(src_ip, inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr)); if (ioctl(sock_raw_fd, SIOCGIFHWADDR, &ifr) == -1) err_exit(“ioctl() get mac”); memcpy(src_mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); while (arp_config.enabled) { char target_ip[INET_ADDRSTRLEN]; for (int i = inet_addr(arp_config.start_ip); i <= inet_addr(arp_config.end_ip); i++) { struct in_addr addr; addr.s_addr = i; strcpy(target_ip, inet_ntoa(addr)); memset(buf, 0, ETHER_ARP_PACKET_LEN); eth_header = (struct ether_header *)buf; memcpy(eth_header->ether_shost, src_mac_addr, ETH_ALEN); memcpy(eth_header->ether_dhost, BROADCAST_ADDR, ETH_ALEN); eth_header->ether_type = htons(ETHERTYPE_ARP); arp_packet = fill_arp_packet(src_mac_addr, src_ip, target_ip); memcpy(buf + ETHER_HEADER_LEN, arp_packet, ETHER_ARP_LEN); sendto(sock_raw_fd, buf, ETHER_ARP_PACKET_LEN, 0, (struct sockaddr *)&saddr_ll, sizeof(struct sockaddr_ll)); free(arp_packet); printf(“ARP request sent to %s\n”, target_ip); usleep(arp_config.packet_interval * 1000); // 发包间隔 } cleanup_arp_entries(); // 清理过期的ARP条目 sleep(arp_config.scan_interval); // 等待下一次扫描 } close(sock_raw_fd);
}
LOCAL int arp_scan_init()
{
if (0 == ds_read(ARP_DATA_PATH, &arp_config_t, sizeof(arp_config_t)))
{
return SLP_ESYSTEM;
}
/* Initialize socket / if ((sockfd = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ARP))) < 0) { perror(“socket”); return ERROR; } / Initialize ip_mac_table */ U8 table_len = arp_config_t.end_ip[3] - arp_config_t.start_ip[3] + 1; ip_mac_table = (ARP_IPMAC_TABLE *)malloc(sizeof(ARP_IPMAC_TABLE) * table_len); struct timeval cur_time; gettimeofday(&cur_time, NULL); for (int i = 0; i < table_len; i++) { ip_mac_table[i].renew_time = cur_time; ip_mac_table[i].device_is_exist = 0; memset(ip_mac_table[i].mac, 0, ETH_ALEN); } msg_attach_handler(MSGID_DMS_CMD, arp_call_handle); return OK;
}
LOCAL int arp_scan_check()
{
if (arp_config_t.end_ip[2] != sender_ip[2] || arp_config_t.start_ip[2] != sender_ip[2] ||
arp_config_t.end_ip[3] <= arp_config_t.start_ip[3])
{
ARP_DEBUG(“Invalid IP address range, please check.\n”);
return ERROR;
}
return OK;
}
LOCAL int arp_scan_start()
{
/* Start address expiration check thread */
pthread_create(&time_tid, NULL, check_table_renew_time, NULL);
pthread_detach(time_tid);
/* Scan loop */ while (scanning_flag) { scan_once(); usleep(arpco.scan_interval); } return OK;
}
LOCAL int arp_scan_reload(DS_MSG msg)
{
/ Stop scanning */
scanning_flag = 0;
if (ds_path_id_exist(msg->id, msg->num, ARP_DATA_PATH)) { arp_config_t arp_data; memset(&arp_data, 0, sizeof(arp_config_t)); if (0 == ds_read(ARP_DATA_PATH, (U8 )&arp_data, sizeof(arp_config_t))) { ARP_ERROR(“Read arp data ERROR”); return ERROR; } / Reload params / memcpy(arp_config_t.start_ip, arp_data.start_ip, ARP_IPV4_LEN); memcpy(arp_config_t.end_ip, arp_data.end_ip, ARP_IPV4_LEN); arp_config_t.scan_interval = arp_data.scan_interval; arp_config_t.packet_interval = arp_data.packet_interval; arp_config_t.entry_lifetime = arp_data.entry_lifetime; / Cancel old checking thread / pthread_cancel(time_tid); / Realloc ip_mac_table */ U8 table_len = arp_config_t.end_ip[3] - arp_config_t.start_ip[3] + 1; ARP_IPMAC_TABLE *new_table; new_table = (ARP_IPMAC_TABLE )realloc(ip_mac_table, sizeof(ARP_IPMAC_TABLE) * table_len); if (NULL == new_table) { ARP_ERROR(“Realloc ipmac_table ERROR”); free(ip_mac_table); ip_mac_table = NULL; return ERROR; } ip_mac_table = new_table; struct timeval cur_time; gettimeofday(&cur_time, NULL); for (int i = 0; i < table_len; i++) { ip_mac_table[i].renew_time = cur_time; ip_mac_table[i].device_is_exist = 0; memset(ip_mac_table[i].mac, 0, ETH_ALEN); } / Restart checking thread / / Start scanning */ scanning_flag = 1; arp_scan_start(); return OK; }
}
LOCAL void arp_scan_main()
{
DS_OPT_DESC main_options[] =
{
DS_SWITCH_OPT(arp_config_t, enabled, OPT_FLAG_NORM),
DS_STR_OPT(arp_config_t, start_ip, OPT_FLAG_NORM),
DS_STR_OPT(arp_config_t, end_ip, OPT_FLAG_NORM),
DS_S32_OPT(arp_config_t, scan_interval, OPT_FLAG_NORM),
DS_S32_OPT(arp_config_t, packet_interval, OPT_FLAG_NORM),
DS_S32_OPT(arp_config_t, entry_lifetime, OPT_FLAG_NORM),
};
DS_SEG_DESC main_segments[] = { DS_STRUCT_SEG(“config”, SEG_LIM_RW, SEG_GROUP_ROOT, arp_config_t, main_options), }; DS_SECT_DESC arp_scan_sections[] = { DS_STRUCT_SECT(“config”, main_segments), }; DS_TBL_DESC arp_scan_tables[] = { DS_STRUCT_TBL(“arp_scan”, TBL_ATTR_STC, arp_scan_sections), }; DS_DAT_MON_DESC arp_data_monitor[] = { DS_DAT_MON(ARP_DATA_PATH, DATA_ATTRI_NOTIFY), }; DS_MOD_DESC arp_scan_module = DS_STRUCT_MOD(“arp_scan”, arp_scan_init, arp_scan_check, arp_scan_reload, arp_scan_start, arp_scan_tables, arp_data_monitor); MODULE *module_node = ds_register_module(“arp_scan”, &arp_module); NSD_ASSERT(NULL != module_node);
}
NSD_INIT(arp_scan_main);
最新发布