我给你我的代码,看是否正确。共六份。#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 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
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(c)
*
* 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);
最新发布