T02Scanner

本文介绍了一个简单的Java程序,该程序利用Scanner类从名为data.txt的文件中读取数学运算表达式,并根据读取的运算符执行加法或减法操作。程序通过循环读取文件中的每一项,直到文件内容被完全处理。

package qsy;

import java.io.File;
import java.util.Scanner;
public class T02Scanner {
 public static void main(String args[]) throws Exception {

  String filename = "data.txt";
  int op1,op2,result=0;
  String operator ="";
  // create a scanner from the data file
  Scanner scanner = new Scanner(new File(filename));

  // 重复从文件中读取数据
  while (scanner.hasNext()) {
  
   operator = scanner.next();
   op1 = scanner.nextInt();
   op2 = scanner.nextInt();
   
   if (operator.equals("+"))
    result = op1 + op2;
   else if (operator.equals("-"))
    result = op1 - op2;
   System.out.println("result is " + result);
  }
  scanner.close(); // also closes the File
 }
}

#ifndef __ARP_SCANNER_H__ #define __ARP_SCANNER_H__ #include "nsd_common.h" #include <net/if.h> #include <netinet/if_ether.h> #include <pthread.h> #define MAX_ARP_ENTRIES 1024 #define MAX_IP_LEN 16 #define MAX_MAC_LEN 18 typedef struct { uint32_t ip; char mac[MAX_MAC_LEN]; time_t last_seen; time_t first_seen; } arp_entry_t; typedef struct { BOOL enabled; uint32_t scan_interval; uint32_t validity_period; uint32_t packet_interval; uint32_t start_ip; uint32_t end_ip; char interface[IFNAMSIZ]; } arp_config_t; typedef struct { pthread_t scan_thread; pthread_mutex_t lock; BOOL scanning; BOOL stop_requested; arp_config_t config; arp_entry_t entries[MAX_ARP_ENTRIES]; int entry_count; time_t last_scan_time; int raw_socket; } arp_scanner_t; // ARP报文结构 typedef struct { struct ethhdr eth_header; struct arphdr arp_header; unsigned char sender_mac[6]; unsigned char sender_ip[4]; unsigned char target_mac[6]; unsigned char target_ip[4]; } arp_packet_t; // 函数声明 int arp_scanner_init(arp_scanner_t *scanner); int arp_scanner_start(arp_scanner_t *scanner); int arp_scanner_stop(arp_scanner_t *scanner); int arp_scanner_cleanup(arp_scanner_t *scanner); int arp_scanner_scan(arp_scanner_t *scanner); int arp_scanner_send_arp_request(arp_scanner_t *scanner, uint32_t target_ip); int arp_scanner_process_reply(arp_scanner_t *scanner); void arp_scanner_clean_old_entries(arp_scanner_t *scanner); void arp_scanner_print_results(arp_scanner_t *scanner); int arp_scanner_add_entry(arp_scanner_t *scanner, uint32_t ip, const char *mac); int arp_scanner_remove_entry(arp_scanner_t *scanner, uint32_t ip); // 工具函数 uint32_t ip_to_int(const char *ip); void int_to_ip(uint32_t ip_int, char *ip_str); void mac_to_string(const unsigned char *mac, char *mac_str); #endif #include "arp_scanner.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <sys/ioctl.h> #include <linux/if_packet.h> #include <time.h> #include <errno.h> S32 arp_scanner_init(arp_scanner_t *scanner) { if (!scanner) return -1; memset(scanner, 0, sizeof(arp_scanner_t)); // 创建原始套接字 scanner->raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (scanner->raw_socket < 0) { perror("socket"); return -1; } // 初始化互斥锁 if (pthread_mutex_init(&scanner->lock, NULL) != 0) { close(scanner->raw_socket); return -1; } // 默认配置 strcpy(scanner->config.interface, "eth0"); scanner->config.scan_interval = 60; scanner->config.validity_period = 300; scanner->config.packet_interval = 100; return 0; } S32 arp_scanner_start(arp_scanner_t *scanner) { if (!scanner || !scanner->config.enabled) return -1; pthread_mutex_lock(&scanner->lock); scanner->scanning = TRUE; scanner->stop_requested = FALSE; pthread_mutex_unlock(&scanner->lock); return 0; } int arp_scanner_stop(arp_scanner_t *scanner) { if (!scanner) return -1; pthread_mutex_lock(&scanner->lock); scanner->stop_requested = TRUE; pthread_mutex_unlock(&scanner->lock); return 0; } int arp_scanner_cleanup(arp_scanner_t *scanner) { if (!scanner) return -1; arp_scanner_stop(scanner); if (scanner->raw_socket >= 0) { close(scanner->raw_socket); } pthread_mutex_destroy(&scanner->lock); return 0; } void *scan_thread_func(void *arg) { arp_scanner_t *scanner = (arp_scanner_t *)arg; while (!scanner->stop_requested) { arp_scanner_scan(scanner); // 等待扫描间隔 sleep(scanner->config.scan_interval); } pthread_mutex_lock(&scanner->lock); scanner->scanning = FALSE; pthread_mutex_unlock(&scanner->lock); return NULL; } int arp_scanner_scan(arp_scanner_t *scanner) { if (!scanner || !scanner->config.enabled) return -1; struct ifreq ifr; strcpy(ifr.ifr_name, scanner->config.interface); // 获取接口索引 if (ioctl(scanner->raw_socket, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl"); return -1; } // 绑定到接口 struct sockaddr_ll saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sll_family = AF_PACKET; saddr.sll_ifindex = ifr.ifr_ifindex; saddr.sll_protocol = htons(ETH_P_ARP); if (bind(scanner->raw_socket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); return -1; } // 发送ARP请求 for (uint32_t ip = scanner->config.start_ip; ip <= scanner->config.end_ip && !scanner->stop_requested; ip++) { arp_scanner_send_arp_request(scanner, ip); usleep(scanner->config.packet_interval * 1000); } // 处理ARP回复 arp_scanner_process_reply(scanner); // 清理过期条目 arp_scanner_clean_old_entries(scanner); scanner->last_scan_time = time(NULL); return 0; } int arp_scanner_send_arp_request(arp_scanner_t *scanner, uint32_t target_ip) { struct ifreq ifr; strcpy(ifr.ifr_name, scanner->config.interface); // 获取接口MAC地址 if (ioctl(scanner->raw_socket, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl"); return -1; } unsigned char *src_mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; // 获取接口IP地址 if (ioctl(scanner->raw_socket, SIOCGIFADDR, &ifr) < 0) { perror("ioctl"); return -1; } struct sockaddr_in *ipaddr = (struct sockaddr_in *)&ifr.ifr_addr; uint32_t src_ip = ipaddr->sin_addr.s_addr; // 构建ARP请求包 arp_packet_t packet; // 以太网头部 memset(packet.eth_header.h_dest, 0xFF, 6); // 广播地址 memcpy(packet.eth_header.h_source, src_mac, 6); packet.eth_header.h_proto = htons(ETH_P_ARP); // ARP头部 packet.arp_header.ar_hrd = htons(ARPHRD_ETHER); packet.arp_header.ar_pro = htons(ETH_P_IP); packet.arp_header.ar_hln = 6; packet.arp_header.ar_pln = 4; packet.arp_header.ar_op = htons(ARPOP_REQUEST); memcpy(packet.sender_mac, src_mac, 6); memcpy(packet.sender_ip, &src_ip, 4); memset(packet.target_mac, 0, 6); memcpy(packet.target_ip, &target_ip, 4); // 发送包 struct sockaddr_ll dest; memset(&dest, 0, sizeof(dest)); dest.sll_family = AF_PACKET; dest.sll_ifindex = ifr.ifr_ifindex; dest.sll_halen = ETH_ALEN; memset(dest.sll_addr, 0xFF, ETH_ALEN); ssize_t sent = sendto(scanner->raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&dest, sizeof(dest)); return (sent == sizeof(packet)) ? 0 : -1; } int arp_scanner_process_reply(arp_scanner_t *scanner) { if (!scanner) { return -1; } fd_set readfds; struct timeval tv; int ret; int max_fd = scanner->raw_socket; // 设置超时时间为2秒,用于等待ARP回复 tv.tv_sec = 2; tv.tv_usec = 0; // 循环处理所有可用的ARP回复 while (1) { FD_ZERO(&readfds); FD_SET(scanner->raw_socket, &readfds); ret = select(max_fd + 1, &readfds, NULL, NULL, &tv); if (ret < 0) { if (errno == EINTR) { // 被信号中断,继续等待 continue; } perror("select"); break; } else if (ret == 0) { // 超时,没有更多数据 break; } if (FD_ISSET(scanner->raw_socket, &readfds)) { arp_packet_t packet; struct sockaddr_ll saddr; socklen_t saddr_len = sizeof(saddr); // 接收ARP数据包 ssize_t received = recvfrom(scanner->raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&saddr, &saddr_len); if (received < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { continue; } perror("recvfrom"); continue; } // 检查接收到的数据包长度 if (received < (ssize_t)(sizeof(struct ethhdr) + sizeof(struct arphdr))) { // 数据包太短,不是有效的ARP包 continue; } // 验证以太网类型是否为ARP if (ntohs(packet.eth_header.h_proto) != ETH_P_ARP) { continue; } // 验证ARP硬件类型为以太网 if (ntohs(packet.arp_header.ar_hrd) != ARPHRD_ETHER) { continue; } // 验证ARP协议类型为IP if (ntohs(packet.arp_header.ar_pro) != ETH_P_IP) { continue; } // 检查是否是ARP回复 if (ntohs(packet.arp_header.ar_op) == ARPOP_REPLY) { // 提取发送者IP和MAC地址 uint32_t sender_ip; memcpy(&sender_ip, packet.sender_ip, 4); char mac_str[MAX_MAC_LEN]; mac_to_string(packet.sender_mac, mac_str); // 检查IP是否在扫描范围内 if (sender_ip >= scanner->config.start_ip && sender_ip <= scanner->config.end_ip) { // 添加到ARP条目表 arp_scanner_add_entry(scanner, sender_ip, mac_str); // 打印调试信息 char ip_str[MAX_IP_LEN]; int_to_ip(sender_ip, ip_str); printf("Received ARP reply from %s [%s]\n", ip_str, mac_str); } } } } return 0; } int arp_scanner_add_entry(arp_scanner_t *scanner, uint32_t ip, const char *mac) { if (!scanner || !mac) { return -1; } pthread_mutex_lock(&scanner->lock); time_t now = time(NULL); int found_index = -1; BOOL is_new_host = FALSE; // 检查是否已存在该IP的条目 for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 更新现有条目 strncpy(scanner->entries[found_index].mac, mac, MAX_MAC_LEN - 1); scanner->entries[found_index].mac[MAX_MAC_LEN - 1] = '\0'; scanner->entries[found_index].last_seen = now; } else { // 添加新条目 if (scanner->entry_count < MAX_ARP_ENTRIES) { arp_entry_t *entry = &scanner->entries[scanner->entry_count]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; scanner->entry_count++; is_new_host = TRUE; } else { // ARP表已满,找到最旧的条目替换 time_t oldest_time = now; int oldest_index = 0; for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].last_seen < oldest_time) { oldest_time = scanner->entries[i].last_seen; oldest_index = i; } } // 替换最旧的条目 arp_entry_t *entry = &scanner->entries[oldest_index]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; is_new_host = TRUE; } } pthread_mutex_unlock(&scanner->lock); // 如果是新发现的主机,打印到串口 if (is_new_host) { char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("NEW HOST: IP=%s, MAC=%s\n", ip_str, mac); } return 0; } void arp_scanner_clean_old_entries(arp_scanner_t *scanner) { if (!scanner) { return; } pthread_mutex_lock(&scanner->lock); time_t now = time(NULL); int write_index = 0; for (int read_index = 0; read_index < scanner->entry_count; read_index++) { if (now - scanner->entries[read_index].last_seen <= scanner->config.validity_period) { // 条目未过期,保留 if (write_index != read_index) { scanner->entries[write_index] = scanner->entries[read_index]; } write_index++; } else { // 条目过期,打印日志 char ip_str[MAX_IP_LEN]; int_to_ip(scanner->entries[read_index].ip, ip_str); printf("EXPIRED: IP=%s, MAC=%s\n", ip_str, scanner->entries[read_index].mac); } } // 更新条目计数 int expired_count = scanner->entry_count - write_index; scanner->entry_count = write_index; pthread_mutex_unlock(&scanner->lock); if (expired_count > 0) { printf("Cleaned %d expired ARP entries\n", expired_count); } } void arp_scanner_print_results(arp_scanner_t *scanner) { if (!scanner) { return; } pthread_mutex_lock(&scanner->lock); printf("\n=== ARP Scan Results ===\n"); printf("Total hosts: %d\n", scanner->entry_count); printf("Last scan: %s", ctime(&scanner->last_scan_time)); printf("-----------------------------------------------\n"); printf("IP Address\t\tMAC Address\t\tFirst Seen\t\tLast Seen\n"); printf("-----------------------------------------------\n"); for (int i = 0; i < scanner->entry_count; i++) { char ip_str[MAX_IP_LEN]; int_to_ip(scanner->entries[i].ip, ip_str); char first_seen_str[64]; char last_seen_str[64]; struct tm *tm_info; tm_info = localtime(&scanner->entries[i].first_seen); strftime(first_seen_str, sizeof(first_seen_str), "%Y-%m-%d %H:%M:%S", tm_info); tm_info = localtime(&scanner->entries[i].last_seen); strftime(last_seen_str, sizeof(last_seen_str), "%Y-%m-%d %H:%M:%S", tm_info); printf("%-15s\t%s\t%s\t%s\n", ip_str, scanner->entries[i].mac, first_seen_str, last_seen_str); } printf("-----------------------------------------------\n"); pthread_mutex_unlock(&scanner->lock); } int arp_scanner_remove_entry(arp_scanner_t *scanner, uint32_t ip) { if (!scanner) { return -1; } pthread_mutex_lock(&scanner->lock); int found_index = -1; // 查找要删除的条目 for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 移动后续条目覆盖要删除的条目 for (int i = found_index; i < scanner->entry_count - 1; i++) { scanner->entries[i] = scanner->entries[i + 1]; } scanner->entry_count--; char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("Removed ARP entry: %s\n", ip_str); } pthread_mutex_unlock(&scanner->lock); return (found_index >= 0) ? 0 : -1; } // 工具函数 uint32_t ip_to_int(const char *ip) { if (!ip) { return 0; } struct in_addr addr; if (inet_pton(AF_INET, ip, &addr) != 1) { fprintf(stderr, "Invalid IP address: %s\n", ip); return 0; } return addr.s_addr; } void int_to_ip(uint32_t ip_int, char *ip_str) { if (!ip_str) { return; } struct in_addr addr; addr.s_addr = ip_int; inet_ntop(AF_INET, &addr, ip_str, MAX_IP_LEN); } void mac_to_string(const unsigned char *mac, char *mac_str) { if (!mac || !mac_str) { return; } snprintf(mac_str, MAX_MAC_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } 重写一下这两个文件,要求从/./files/etc/default/arpd/arpd_conf中读取配置信息{ "arpd": { "enabled": "FALSE", "scan_interval": "60", "validity_period": "300", "packet_interval": "100", "start_ip": "192.168.1.100", "end_ip": "192.168.1.200" } },要求用ds_read()函数读取
08-28
#include "arp_scanner.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <sys/ioctl.h> #include <linux/if_packet.h> #include <time.h> #include <errno.h> #include "json_api.h" // 从二进制文件加载配置 int load_config(arp_config_t *config) { if (config == NULL) { fprintf(stderr, "错误: 配置指针为空\n"); return -1; } // 使用ds_read读取配置 ds_read(ARPD_CONFIG_PATH, config, sizeof(arp_config_t)); return 0; } S32 arp_scanner_init() { memset(&g_scanner, 0, sizeof(arp_scanner_t)); // 创建原始套接字 g_scanner.raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (g_scanner.raw_socket < 0) { perror("socket"); return -1; } // 初始化互斥锁 if (pthread_mutex_init(&g_scanner.lock, NULL) != 0) { close(&g_scanner.raw_socket); return -1; } // 从配置文件加载配置 if (load_config(&g_scanner.config) != 0) { // 加载失败时使用默认值 gscanner.config.enabled = FALSE; gscanner.config.scan_interval = 60; gscanner.config.validity_period = 300; gscanner.config.packet_interval = 100; gscanner.config.start_ip = ip_to_int("192.168.1.100"); gscanner.config.end_ip = ip_to_int("192.168.1.200"); // 默认网络接口 strcpy(gscanner.config.interface, "eth0"); fprintf(stderr, "Using default configuration\n"); } return 0; } S32 arp_scanner_start(void) { pthread_mutex_lock(&g_scanner.lock); g_scanner.scanning = TRUE; g_scanner.stop_requested = FALSE; pthread_mutex_unlock(&g_scanner.lock); // 创建扫描线程 pthread_t scan_thread; if (pthread_create(&scan_thread, NULL, scan_thread_func, NULL) != 0) { perror("pthread_create"); return -1; } return 0; } int arp_scanner_stop(arp_scanner_t *scanner) { if (!scanner) return -1; pthread_mutex_lock(&scanner->lock); scanner->stop_requested = TRUE; pthread_mutex_unlock(&scanner->lock); return 0; } int arp_scanner_cleanup(arp_scanner_t *scanner) { if (!scanner) return -1; arp_scanner_stop(scanner); if (scanner->raw_socket >= 0) { close(scanner->raw_socket); } pthread_mutex_destroy(&scanner->lock); return 0; } void *scan_thread_func(void *arg) { arp_scanner_t *scanner = (arp_scanner_t *)arg; while (!scanner->stop_requested) { arp_scanner_scan(scanner); // 等待扫描间隔 sleep(scanner->config.scan_interval); } pthread_mutex_lock(&scanner->lock); scanner->scanning = FALSE; pthread_mutex_unlock(&scanner->lock); return NULL; } int arp_scanner_scan(arp_scanner_t *scanner) { if (!scanner || !scanner->config.enabled) return -1; struct ifreq ifr; strcpy(ifr.ifr_name, scanner->config.interface); // 获取接口索引 if (ioctl(scanner->raw_socket, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl"); return -1; } // 绑定到接口 struct sockaddr_ll saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sll_family = AF_PACKET; saddr.sll_ifindex = ifr.ifr_ifindex; saddr.sll_protocol = htons(ETH_P_ARP); if (bind(scanner->raw_socket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); return -1; } // 发送ARP请求 for (uint32_t ip = scanner->config.start_ip; ip <= scanner->config.end_ip && !scanner->stop_requested; ip++) { arp_scanner_send_arp_request(scanner, ip); usleep(scanner->config.packet_interval * 1000); } // 处理ARP回复 arp_scanner_process_reply(scanner); // 清理过期条目 arp_scanner_clean_old_entries(scanner); scanner->last_scan_time = time(NULL); return 0; } int arp_scanner_send_arp_request(arp_scanner_t *scanner, uint32_t target_ip) { struct ifreq ifr; strcpy(ifr.ifr_name, scanner->config.interface); // 获取接口MAC地址 if (ioctl(scanner->raw_socket, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl"); return -1; } unsigned char *src_mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; // 获取接口IP地址 if (ioctl(scanner->raw_socket, SIOCGIFADDR, &ifr) < 0) { perror("ioctl"); return -1; } struct sockaddr_in *ipaddr = (struct sockaddr_in *)&ifr.ifr_addr; uint32_t src_ip = ipaddr->sin_addr.s_addr; // 构建ARP请求包 arp_packet_t packet; // 以太网头部 memset(packet.eth_header.h_dest, 0xFF, 6); // 广播地址 memcpy(packet.eth_header.h_source, src_mac, 6); packet.eth_header.h_proto = htons(ETH_P_ARP); // ARP头部 packet.arp_header.ar_hrd = htons(ARPHRD_ETHER); packet.arp_header.ar_pro = htons(ETH_P_IP); packet.arp_header.ar_hln = 6; packet.arp_header.ar_pln = 4; packet.arp_header.ar_op = htons(ARPOP_REQUEST); memcpy(packet.sender_mac, src_mac, 6); memcpy(packet.sender_ip, &src_ip, 4); memset(packet.target_mac, 0, 6); memcpy(packet.target_ip, &target_ip, 4); // 发送包 struct sockaddr_ll dest; memset(&dest, 0, sizeof(dest)); dest.sll_family = AF_PACKET; dest.sll_ifindex = ifr.ifr_ifindex; dest.sll_halen = ETH_ALEN; memset(dest.sll_addr, 0xFF, ETH_ALEN); ssize_t sent = sendto(scanner->raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&dest, sizeof(dest)); return (sent == sizeof(packet)) ? 0 : -1; } int arp_scanner_process_reply(arp_scanner_t *scanner) { if (!scanner) { return -1; } fd_set readfds; struct timeval tv; int ret; int max_fd = scanner->raw_socket; // 设置超时时间为2秒,用于等待ARP回复 tv.tv_sec = 2; tv.tv_usec = 0; // 循环处理所有可用的ARP回复 while (1) { FD_ZERO(&readfds); FD_SET(scanner->raw_socket, &readfds); ret = select(max_fd + 1, &readfds, NULL, NULL, &tv); if (ret < 0) { if (errno == EINTR) { // 被信号中断,继续等待 continue; } perror("select"); break; } else if (ret == 0) { // 超时,没有更多数据 break; } if (FD_ISSET(scanner->raw_socket, &readfds)) { arp_packet_t packet; struct sockaddr_ll saddr; socklen_t saddr_len = sizeof(saddr); // 接收ARP数据包 ssize_t received = recvfrom(scanner->raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&saddr, &saddr_len); if (received < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { continue; } perror("recvfrom"); continue; } // 检查接收到的数据包长度 if (received < (ssize_t)(sizeof(struct ethhdr) + sizeof(struct arphdr))) { // 数据包太短,不是有效的ARP包 continue; } // 验证以太网类型是否为ARP if (ntohs(packet.eth_header.h_proto) != ETH_P_ARP) { continue; } // 验证ARP硬件类型为以太网 if (ntohs(packet.arp_header.ar_hrd) != ARPHRD_ETHER) { continue; } // 验证ARP协议类型为IP if (ntohs(packet.arp_header.ar_pro) != ETH_P_IP) { continue; } // 检查是否是ARP回复 if (ntohs(packet.arp_header.ar_op) == ARPOP_REPLY) { // 提取发送者IP和MAC地址 uint32_t sender_ip; memcpy(&sender_ip, packet.sender_ip, 4); char mac_str[MAX_MAC_LEN]; mac_to_string(packet.sender_mac, mac_str); // 检查IP是否在扫描范围内 if (sender_ip >= scanner->config.start_ip && sender_ip <= scanner->config.end_ip) { // 添加到ARP条目表 arp_scanner_add_entry(scanner, sender_ip, mac_str); // 打印调试信息 char ip_str[MAX_IP_LEN]; int_to_ip(sender_ip, ip_str); printf("Received ARP reply from %s [%s]\n", ip_str, mac_str); } } } } return 0; } int arp_scanner_add_entry(arp_scanner_t *scanner, uint32_t ip, const char *mac) { if (!scanner || !mac) { return -1; } pthread_mutex_lock(&scanner->lock); time_t now = time(NULL); int found_index = -1; BOOL is_new_host = FALSE; // 检查是否已存在该IP的条目 for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 更新现有条目 strncpy(scanner->entries[found_index].mac, mac, MAX_MAC_LEN - 1); scanner->entries[found_index].mac[MAX_MAC_LEN - 1] = '\0'; scanner->entries[found_index].last_seen = now; } else { // 添加新条目 if (scanner->entry_count < MAX_ARP_ENTRIES) { arp_entry_t *entry = &scanner->entries[scanner->entry_count]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; scanner->entry_count++; is_new_host = TRUE; } else { // ARP表已满,找到最旧的条目替换 time_t oldest_time = now; int oldest_index = 0; for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].last_seen < oldest_time) { oldest_time = scanner->entries[i].last_seen; oldest_index = i; } } // 替换最旧的条目 arp_entry_t *entry = &scanner->entries[oldest_index]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; is_new_host = TRUE; } } pthread_mutex_unlock(&scanner->lock); // 如果是新发现的主机,打印到串口 if (is_new_host) { char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("NEW HOST: IP=%s, MAC=%s\n", ip_str, mac); } return 0; } void arp_scanner_clean_old_entries(arp_scanner_t *scanner) { if (!scanner) { return; } pthread_mutex_lock(&scanner->lock); time_t now = time(NULL); int write_index = 0; for (int read_index = 0; read_index < scanner->entry_count; read_index++) { if (now - scanner->entries[read_index].last_seen <= scanner->config.validity_period) { // 条目未过期,保留 if (write_index != read_index) { scanner->entries[write_index] = scanner->entries[read_index]; } write_index++; } else { // 条目过期,打印日志 char ip_str[MAX_IP_LEN]; int_to_ip(scanner->entries[read_index].ip, ip_str); printf("EXPIRED: IP=%s, MAC=%s\n", ip_str, scanner->entries[read_index].mac); } } // 更新条目计数 int expired_count = scanner->entry_count - write_index; scanner->entry_count = write_index; pthread_mutex_unlock(&scanner->lock); if (expired_count > 0) { printf("Cleaned %d expired ARP entries\n", expired_count); } } void arp_scanner_print_results(arp_scanner_t *scanner) { if (!scanner) { return; } pthread_mutex_lock(&scanner->lock); printf("\n=== ARP Scan Results ===\n"); printf("Total hosts: %d\n", scanner->entry_count); printf("Last scan: %s", ctime(&scanner->last_scan_time)); printf("-----------------------------------------------\n"); printf("IP Address\t\tMAC Address\t\tFirst Seen\t\tLast Seen\n"); printf("-----------------------------------------------\n"); for (int i = 0; i < scanner->entry_count; i++) { char ip_str[MAX_IP_LEN]; int_to_ip(scanner->entries[i].ip, ip_str); char first_seen_str[64]; char last_seen_str[64]; struct tm *tm_info; tm_info = localtime(&scanner->entries[i].first_seen); strftime(first_seen_str, sizeof(first_seen_str), "%Y-%m-%d %H:%M:%S", tm_info); tm_info = localtime(&scanner->entries[i].last_seen); strftime(last_seen_str, sizeof(last_seen_str), "%Y-%m-%d %H:%M:%S", tm_info); printf("%-15s\t%s\t%s\t%s\n", ip_str, scanner->entries[i].mac, first_seen_str, last_seen_str); } printf("-----------------------------------------------\n"); pthread_mutex_unlock(&scanner->lock); } int arp_scanner_remove_entry(arp_scanner_t *scanner, uint32_t ip) { if (!scanner) { return -1; } pthread_mutex_lock(&scanner->lock); int found_index = -1; // 查找要删除的条目 for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 移动后续条目覆盖要删除的条目 for (int i = found_index; i < scanner->entry_count - 1; i++) { scanner->entries[i] = scanner->entries[i + 1]; } scanner->entry_count--; char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("Removed ARP entry: %s\n", ip_str); } pthread_mutex_unlock(&scanner->lock); return (found_index >= 0) ? 0 : -1; } // 工具函数 uint32_t ip_to_int(const char *ip) { if (!ip) { return 0; } struct in_addr addr; if (inet_pton(AF_INET, ip, &addr) != 1) { fprintf(stderr, "Invalid IP address: %s\n", ip); return 0; } return addr.s_addr; } void int_to_ip(uint32_t ip_int, char *ip_str) { if (!ip_str) { return; } struct in_addr addr; addr.s_addr = ip_int; inet_ntop(AF_INET, &addr, ip_str, MAX_IP_LEN); } void mac_to_string(const unsigned char *mac, char *mac_str) { if (!mac || !mac_str) { return; } snprintf(mac_str, MAX_MAC_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } 把所有函数都统一成全局变量模式,并且整个应用是单线程循环而不是多线程的应用
08-28
#include "arp_scanner.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <sys/ioctl.h> #include <linux/if_packet.h> #include <time.h> #include <errno.h> #include "json_api.h" // 加载配置 int load_config(arp_config_t *config) { if (config == NULL) { fprintf(stderr, "错误: 配置指针为空\n"); return -1; } // 使用ds_read读取配置 ds_read(ARPD_CONFIG_PATH, config, sizeof(arp_config_t)); return 0; } S32 arp_scanner_init() { memset(&g_scanner, 0, sizeof(arp_scanner_t)); // 创建原始套接字 g_scanner.raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (g_scanner.raw_socket < 0) { perror("socket"); return -1; } // 初始化互斥锁 if (pthread_mutex_init(&g_scanner.lock, NULL) != 0) { close(g_scanner.raw_socket); return -1; } // 从配置文件加载配置 if (load_config(&g_scanner.config) != 0) { // 加载失败时使用默认值 g_scanner.config.enabled = FALSE; g_scanner.config.scan_interval = 60; g_scanner.config.validity_period = 300; g_scanner.config.packet_interval = 100; g_scanner.config.start_ip = ip_to_int("192.168.1.100"); g_scanner.config.end_ip = ip_to_int("192.168.1.200"); // 默认网络接口 strcpy(g_scanner.config.interface, "eth0"); fprintf(stderr, "Using default configuration\n"); } return 0; } S32 arp_scanner_start(void) { pthread_mutex_lock(&g_scanner.lock); g_scanner.scanning = TRUE; g_scanner.stop_requested = FALSE; pthread_mutex_unlock(&g_scanner.lock); return 0; } int arp_scanner_stop(void) { pthread_mutex_lock(&g_scanner.lock); g_scanner.stop_requested = TRUE; pthread_mutex_unlock(&g_scanner.lock); return 0; } int arp_scanner_cleanup(void) { arp_scanner_stop(); if (g_scanner.raw_socket >= 0) { close(g_scanner.raw_socket); } pthread_mutex_destroy(&g_scanner.lock); return 0; } int arp_scanner_scan(void) { if (!g_scanner.config.enabled) return -1; struct ifreq ifr; strcpy(ifr.ifr_name, g_scanner.config.interface); // 获取接口索引 if (ioctl(g_scanner.raw_socket, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl"); return -1; } // 绑定到接口 struct sockaddr_ll saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sll_family = AF_PACKET; saddr.sll_ifindex = ifr.ifr_ifindex; saddr.sll_protocol = htons(ETH_P_ARP); if (bind(g_scanner.raw_socket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); return -1; } // 发送ARP请求 for (uint32_t ip = g_scanner.config.start_ip; ip <= g_scanner.config.end_ip && !g_scanner.stop_requested; ip++) { arp_scanner_send_arp_request(ip); usleep(g_scanner.config.packet_interval * 1000); } // 处理ARP回复 arp_scanner_process_reply(); // 清理过期条目 arp_scanner_clean_old_entries(); g_scanner.last_scan_time = time(NULL); return 0; } int arp_scanner_send_arp_request(uint32_t target_ip) { struct ifreq ifr; strcpy(ifr.ifr_name, g_scanner.config.interface); // 获取接口MAC地址 if (ioctl(g_scanner.raw_socket, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl"); return -1; } unsigned char *src_mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; // 获取接口IP地址 if (ioctl(g_scanner.raw_socket, SIOCGIFADDR, &ifr) < 0) { perror("ioctl"); return -1; } struct sockaddr_in *ipaddr = (struct sockaddr_in *)&ifr.ifr_addr; uint32_t src_ip = ipaddr->sin_addr.s_addr; // 构建ARP请求包 arp_packet_t packet; // 以太网头部 memset(packet.eth_header.h_dest, 0xFF, 6); // 广播地址 memcpy(packet.eth_header.h_source, src_mac, 6); packet.eth_header.h_proto = htons(ETH_P_ARP); // ARP头部 packet.arp_header.ar_hrd = htons(ARPHRD_ETHER); packet.arp_header.ar_pro = htons(ETH_P_IP); packet.arp_header.ar_hln = 6; packet.arp_header.ar_pln = 4; packet.arp_header.ar_op = htons(ARPOP_REQUEST); memcpy(packet.sender_mac, src_mac, 6); memcpy(packet.sender_ip, &src_ip, 4); memset(packet.target_mac, 0, 6); memcpy(packet.target_ip, &target_ip, 4); // 发送包 struct sockaddr_ll dest; memset(&dest, 0, sizeof(dest)); dest.sll_family = AF_PACKET; dest.sll_ifindex = ifr.ifr_ifindex; dest.sll_halen = ETH_ALEN; memset(dest.sll_addr, 0xFF, ETH_ALEN); ssize_t sent = sendto(g_scanner.raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&dest, sizeof(dest)); return (sent == sizeof(packet)) ? 0 : -1; } int arp_scanner_process_reply(void) { fd_set readfds; struct timeval tv; int ret; int max_fd = g_scanner.raw_socket; // 设置超时时间为2秒,用于等待ARP回复 tv.tv_sec = 2; tv.tv_usec = 0; // 循环处理所有可用的ARP回复 while (1) { FD_ZERO(&readfds); FD_SET(g_scanner.raw_socket, &readfds); ret = select(max_fd + 1, &readfds, NULL, NULL, &tv); if (ret < 0) { if (errno == EINTR) { // 被信号中断,继续等待 continue; } perror("select"); break; } else if (ret == 0) { // 超时,没有更多数据 break; } if (FD_ISSET(g_scanner.raw_socket, &readfds)) { arp_packet_t packet; struct sockaddr_ll saddr; socklen_t saddr_len = sizeof(saddr); // 接收ARP数据包 ssize_t received = recvfrom(g_scanner.raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&saddr, &saddr_len); if (received < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { continue; } perror("recvfrom"); continue; } // 检查接收到的数据包长度 if (received < (ssize_t)(sizeof(struct ethhdr) + sizeof(struct arphdr))) { // 数据包太短,不是有效的ARP包 continue; } // 验证以太网类型是否为ARP if (ntohs(packet.eth_header.h_proto) != ETH_P_ARP) { continue; } // 验证ARP硬件类型为以太网 if (ntohs(packet.arp_header.ar_hrd) != ARPHRD_ETHER) { continue; } // 验证ARP协议类型为IP if (ntohs(packet.arp_header.ar_pro) != ETH_P_IP) { continue; } // 检查是否是ARP回复 if (ntohs(packet.arp_header.ar_op) == ARPOP_REPLY) { // 提取发送者IP和MAC地址 uint32_t sender_ip; memcpy(&sender_ip, packet.sender_ip, 4); char mac_str[MAX_MAC_LEN]; mac_to_string(packet.sender_mac, mac_str); // 检查IP是否在扫描范围内 if (sender_ip >= g_scanner.config.start_ip && sender_ip <= g_scanner.config.end_ip) { // 添加到ARP条目表 arp_scanner_add_entry(sender_ip, mac_str); // 打印调试信息 char ip_str[MAX_IP_LEN]; int_to_ip(sender_ip, ip_str); printf("Received ARP reply from %s [%s]\n", ip_str, mac_str); } } } } return 0; } int arp_scanner_add_entry(uint32_t ip, const char *mac) { if (!mac) { return -1; } pthread_mutex_lock(&g_scanner.lock); time_t now = time(NULL); int found_index = -1; BOOL is_new_host = FALSE; // 检查是否已存在该IP的条目 for (int i = 0; i < g_scanner.entry_count; i++) { if (g_scanner.entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 更新现有条目 strncpy(g_scanner.entries[found_index].mac, mac, MAX_MAC_LEN - 1); g_scanner.entries[found_index].mac[MAX_MAC_LEN - 1] = '\0'; g_scanner.entries[found_index].last_seen = now; } else { // 添加新条目 if (g_scanner.entry_count < MAX_ARP_ENTRIES) { arp_entry_t *entry = &g_scanner.entries[g_scanner.entry_count]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; g_scanner.entry_count++; is_new_host = TRUE; } else { // ARP表已满,找到最旧的条目替换 time_t oldest_time = now; int oldest_index = 0; for (int i = 0; i < g_scanner.entry_count; i++) { if (g_scanner.entries[i].last_seen < oldest_time) { oldest_time = g_scanner.entries[i].last_seen; oldest_index = i; } } // 替换最旧的条目 arp_entry_t *entry = &g_scanner.entries[oldest_index]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; is_new_host = TRUE; } } pthread_mutex_unlock(&g_scanner.lock); // 如果是新发现的主机,打印到串口 if (is_new_host) { char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("NEW HOST: IP=%s, MAC=%s\n", ip_str, mac); } return 0; } void arp_scanner_clean_old_entries(void) { pthread_mutex_lock(&g_scanner.lock); time_t now = time(NULL); int write_index = 0; for (int read_index = 0; read_index < g_scanner.entry_count; read_index++) { if (now - g_scanner.entries[read_index].last_seen <= g_scanner.config.validity_period) { // 条目未过期,保留 if (write_index != read_index) { g_scanner.entries[write_index] = g_scanner.entries[read_index]; } write_index++; } else { // 条目过期,打印日志 char ip_str[MAX_IP_LEN]; int_to_ip(g_scanner.entries[read_index].ip, ip_str); printf("EXPIRED: IP=%s, MAC=%s\n", ip_str, g_scanner.entries[read_index].mac); } } // 更新条目计数 int expired_count = g_scanner.entry_count - write_index; g_scanner.entry_count = write_index; pthread_mutex_unlock(&g_scanner.lock); if (expired_count > 0) { printf("Cleaned %d expired ARP entries\n", expired_count); } } int arp_scanner_remove_entry(uint32_t ip) { pthread_mutex_lock(&g_scanner.lock); int found_index = -1; // 查找要删除的条目 for (int i = 0; i < g_scanner.entry_count; i++) { if (g_scanner.entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 移动后续条目覆盖要删除的条目 for (int i = found_index; i < g_scanner.entry_count - 1; i++) { g_scanner.entries[i] = g_scanner.entries[i + 1]; } g_scanner.entry_count--; char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("Removed ARP entry: %s\n", ip_str); } pthread_mutex_unlock(&g_scanner.lock); return (found_index >= 0) ? 0 : -1; } // 工具函数 uint32_t ip_to_int(const char *ip) { if (!ip) { return 0; } struct in_addr addr; if (inet_pton(AF_INET, ip, &addr) != 1) { fprintf(stderr, "Invalid IP address: %s\n", ip); return 0; } return addr.s_addr; } void int_to_ip(uint32_t ip_int, char *ip_str) { if (!ip_str) { return; } struct in_addr addr; addr.s_addr = ip_int; inet_ntop(AF_INET, &addr, ip_str, MAX_IP_LEN); } void mac_to_string(const unsigned char *mac, char *mac_str) { if (!mac || !mac_str) { return; } snprintf(mac_str, MAX_MAC_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } 将上述文件的函数封装到int arpd_start_scan(struct _DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { // 创建响应JSON对象 context->res_obj = jso_new_obj(); if (NULL == context->res_obj) { DS_ERROR("Create new json object failed."); context->error_code = SLP_ESYSTEM; return ERROR; } // 关键修改:启动前先执行初始化 int init_result = arp_scanner_init(); if (init_result != 0) { jso_add_string(context->res_obj, "status", "error"); jso_add_string(context->res_obj, "message", "Scanner initialization failed"); return ERROR; } // 启动扫描 int start_result = arp_scanner_start(); if (start_result == 0) { jso_add_string(context->res_obj, "status", "success"); jso_add_string(context->res_obj, "message", "Scan started successfully"); // 添加扫描配置信息 pthread_mutex_lock(&g_scanner.lock); jso_add_bool(context->res_obj, "enabled", g_scanner.config.enabled); jso_add_int(context->res_obj, "scan_interval", g_scanner.config.scan_interval); jso_add_int(context->res_obj, "validity_period", g_scanner.config.validity_period); char start_ip_str[MAX_IP_LEN], end_ip_str[MAX_IP_LEN]; int_to_ip(g_scanner.config.start_ip, start_ip_str); int_to_ip(g_scanner.config.end_ip, end_ip_str); jso_add_string(context->res_obj, "start_ip", start_ip_str); jso_add_string(context->res_obj, "end_ip", end_ip_str); jso_add_string(context->res_obj, "interface", g_scanner.config.interface); pthread_mutex_unlock(&g_scanner.lock); } else { jso_add_string(context->res_obj, "status", "error"); jso_add_string(context->res_obj, "message", "Failed to start scan"); } return start_result; } // 停止扫描 // 停止扫描 int arpd_stop_scan(struct _DS_HANDLE_CONTEXT *context, JSON_OBJPTR param) { // 创建响应JSON对象 context->res_obj = jso_new_obj(); if (NULL == context->res_obj) { DS_ERROR("Create new json object failed."); context->error_code = SLP_ESYSTEM; return ERROR; } // 获取当前扫描状态 pthread_mutex_lock(&g_scanner.lock); BOOL was_scanning = g_scanner.scanning; int entry_count = g_scanner.entry_count; time_t last_scan_time = g_scanner.last_scan_time; pthread_mutex_unlock(&g_scanner.lock); // 执行停止操作 int stop_result = arp_scanner_stop(); // 构建响应 if (stop_result == 0) { jso_add_string(context->res_obj, "status", "success"); jso_add_string(context->res_obj, "action", was_scanning ? "Scan stopped" : "No active scan to stop"); // 添加扫描结果统计 jso_add_bool(context->res_obj, "was_scanning", was_scanning); jso_add_int(context->res_obj, "entry_count", entry_count); // 添加时间信息 char last_scan_str[32]; if (last_scan_time > 0) { format_timestamp(last_scan_time, last_scan_str); jso_add_string(context->res_obj, "last_scan_time", last_scan_str); } else { jso_add_string(context->res_obj, "last_scan_time", "Never scanned"); } // 添加配置信息 pthread_mutex_lock(&g_scanner.lock); jso_add_bool(context->res_obj, "enabled", g_scanner.config.enabled); jso_add_int(context->res_obj, "scan_interval", g_scanner.config.scan_interval); pthread_mutex_unlock(&g_scanner.lock); } else { jso_add_string(context->res_obj, "status", "error"); jso_add_string(context->res_obj, "message", "Failed to stop scan"); jso_add_int(context->res_obj, "error_code", stop_result); } return stop_result; }中,arpd_start_scan需要真正实现启动扫描并扫描的过程
08-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值