#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include "common_ifaddrs.h"
#include "prod_common_wan.h"
#define FAILURE -1
#define SUCCESS 0
#define IP_LENGTH 4
#define MAC_LENGTH 6
#define ARP_DELAY 20*10000
static unsigned char g_arp_src_ip[IP_LENGTH] = {0}; //要检测的主机IP地址
static unsigned char g_arp_src_mac[MAC_LENGTH] = {0}; //要检测的主机的MAC地址
static unsigned char g_arp_dst_ip[IP_LENGTH] = {0}; //目标IP地址
static unsigned char g_arp_dst_mac[MAC_LENGTH] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; //ARP广播地址
static char *g_Network_card_name = NULL;
static struct tar_arp_packet
{
struct ether_header eh;
struct ether_arp arp;
};
static int send_arp(int sockfd, struct sockaddr_ll *peer_addr);
static int recv_arp(int sockfd, struct sockaddr_ll *peer_addr);
/***************************************
函数名:get_wan_ip
描述 : 获取IP地址并转换为unsigned char 型数据
参数:
[in] 无
返回值
0:SUCCESS
-1:FAILURE
说明:
无
*******************************************/
int get_wan_ip()
{
int i = 0,j = 0;
char *str = NULL;
unsigned char num[4]={0};
char tmp[3];
int n = 0,value=0;
WAN_ID_NUM_ENUM wan_id = 0;
WAN_IP_INFO_STRU ip_info;
memset(&ip_info,0x0,sizeof(ip_info));
if(currently_lte_working_mode())
{
wan_id = LTE_WANID;
}
else
{
wan_id = ETH_WANID;
}
file_wan_ip_info_get(wan_id, &ip_info);
if(0 == strlen(ip_info.wan_ip))
{
printf("plaese check internet connection\n");
return -1;
}
//将字符串形式的IP转化为 unsigned char 型
str = ip_info.wan_ip;
for(i=0;i<4;i++)
{
// 每次最多转化3位字符
for( j = 0;j<3;j++)
{
if((*str == '.') || (*str == '\0'))
break;
tmp[j] = *str;
value = value * 10 + tmp[j] - '0';
str += 1;
}
num[n] = value;
value = 0;
if(*str == '\0')
{
break;
}
else
{
str += 1;
n += 1;
}
};
for( i = 0;i<IP_LENGTH;i++)
{
g_arp_src_ip[i] = num[i];
}
return 0;
}
/********************************
函数名:get_wan_mac
描述 : 获取MAC地址
参数:
[in] 无
返回值
0:SUCCESS
-1:FAILURE
说明:
无
*********************************/
int get_wan_mac()
{
int i = 0 ;
int ret = 0;
int wanid = 0;
unsigned char wan_mac[MAC_LENGTH] = {0};
char mac_str[32] = {0};
int sysmode = UGW_SYS_MODE_GW;
UGW_WAN_CONNECT_TYPE_ENUM wantype;
memset(&wantype,0x0,sizeof(wantype));
if(currently_lte_working_mode())
{
wanid = LTE_WANID;
}
else
{
wanid = ETH_WANID;
}
wantype = getWanConnType(wanid);
g_Network_card_name = ifaddrs_get_wan_ifname(wanid, sysmode, wantype);
if(NULL == g_Network_card_name)
{
return -1;
}
printf("MAC:Network_card_name:%s\n",g_Network_card_name);
ret = ifaddrs_get_if_netmac("eth1", wan_mac);
if(ret < 0)
{
return -1;
}
snprintf(mac_str, sizeof(mac_str), "%02X:%02X:%02X:%02X:%02X:%02X",
wan_mac[0], wan_mac[1], wan_mac[2], wan_mac[3], wan_mac[4], wan_mac[5]);
for( i = 0;i<MAC_LENGTH;i++)
{
g_arp_src_mac[i] = wan_mac[i];
}
return 0;
}
/************************************************
函数名:get_wan_ip
描述 : 获取IP地址并转换为unsigned char 型数据
参数:
[in] 无
返回值
无
说明:
无
**************************************************/
int send_arp(int sockfd, struct sockaddr_ll *peer_addr)
{
int rtval = 0 ;
struct tar_arp_packet frame;
memset(&frame, 0x0, sizeof(struct tar_arp_packet));
//填充以太网头部
memcpy(frame.eh.ether_dhost, g_arp_dst_mac, MAC_LENGTH); //目的MAC地址
memcpy(frame.eh.ether_shost, g_arp_src_mac, MAC_LENGTH); //源MAC地址
frame.eh.ether_type = htons(ETHERTYPE_ARP); //协议
//填充ARP报文头部
frame.arp.ea_hdr.ar_hrd = htons(ARPHRD_ETHER); //硬件类型
frame.arp.ea_hdr.ar_pro = htons(ETHERTYPE_IP); //协议类型 ETHERTYPE_IP | ETH_P_IP
frame.arp.ea_hdr.ar_hln = 6; //硬件地址长度
frame.arp.ea_hdr.ar_pln = 4; //协议地址长度
frame.arp.ea_hdr.ar_op = htons(ARPOP_REQUEST); //ARP请求操作
memcpy(frame.arp.arp_sha, g_arp_src_mac, MAC_LENGTH); //源MAC地址
memcpy(frame.arp.arp_spa, g_arp_src_ip, IP_LENGTH); //源IP地址
memcpy(frame.arp.arp_tha, g_arp_dst_mac, MAC_LENGTH); //目的MAC地址
memcpy(frame.arp.arp_tpa, g_arp_dst_ip, IP_LENGTH); //目的IP地址
rtval = sendto(sockfd, &frame, sizeof(struct tar_arp_packet), 0,
(struct sockaddr*)peer_addr, sizeof(struct sockaddr_ll));
if (rtval < 0)
{
return FAILURE;
}
else
{
return SUCCESS;
}
}
/********************************************************
函数名: recv_arp
描述 : 接收ARP回复数据报文并判断是不是对免费ARP的回复。
参数:
[in] sockfd -- 创建的socket描述符;
[in] peer_addr -- 对端的IP信息
返回值:
成功: SUCCESS, 失败: FAILURE;
********************************************************/
int recv_arp(int sockfd, struct sockaddr_ll *peer_addr)
{
int rtval = 0;
static int i = 0;
char arp_tpa_buf[32] = {0};
char src_ip_buf[32] = {0};
struct tar_arp_packet frame;
memset(&frame, 0, sizeof(struct tar_arp_packet));
rtval = recvfrom(sockfd, &frame, sizeof(frame), 0,
NULL, NULL);
u_short etherType = ntohs(frame.arp.ea_hdr.ar_op);
sprintf(src_ip_buf,"%d.%d.%d.%d",g_arp_src_ip[0],g_arp_src_ip[1],g_arp_src_ip[2],g_arp_src_ip[3]);
sprintf(arp_tpa_buf,"%d.%d.%d.%d",frame.arp.arp_tpa[0],frame.arp.arp_tpa[1],
frame.arp.arp_tpa[2],frame.arp.arp_tpa[3]);
if(2 == etherType)
{
if (0 == strcmp(arp_tpa_buf,src_ip_buf))
{
printf("[%d]Target IP:%d.%d.%d.%d\t\tTarget Mac:%02x:%02x:%02x:%02x:%02x:%02x\n", i,frame.arp.arp_spa[0],frame.arp.arp_spa[1],
frame.arp.arp_spa[2],frame.arp.arp_spa[3],frame.arp.arp_sha[0],frame.arp.arp_sha[1],
frame.arp.arp_sha[2],frame.arp.arp_sha[3],frame.arp.arp_sha[4],frame.arp.arp_sha[5]);
i++;
}
}
if (rtval < 0)
{
return FAILURE;
}
else
{
return SUCCESS;
}
}
int main(int argc,char *argv[])
{
int rtval = 0;
int i = 0;
int times = 0;
int sockfd = 0;
struct sockaddr_ll peer_addr;
//1, 创建一个UDP套接字 SOCK_DGRAM ==> UDP套接字
if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1)
{
perror("socket failed");
return -1;
}
//3,配置参数
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.sll_family = PF_PACKET;
struct ifreq req;
bzero(&req, sizeof(struct ifreq));
strcpy(req.ifr_name, g_Network_card_name);
if(ioctl(sockfd, SIOCGIFINDEX, &req) != 0)
{
perror("ioctl()");
}
peer_addr.sll_ifindex = req.ifr_ifindex;
peer_addr.sll_protocol = htons(ETH_P_ARP);
get_wan_mac();
get_wan_ip();
while(1)
{
if(0 == get_wan_ip())
{
break;
}
else
{
sleep(2);
}
}
//初始化目的IP
for( i = 0;i<4;i++)
{
g_arp_dst_ip[i] = g_arp_src_ip[i];
}
printf("arp test start**********************************************************\n");
for(i=1;i<255;i++)
{
g_arp_dst_ip[3] = i;
//arp发送
rtval = send_arp(sockfd, &peer_addr);
times = 3;
while(times--)
{
//arp接收
rtval = recv_arp(sockfd, &peer_addr);
if(FAILURE == rtval)
{
usleep(ARP_DELAY);
rtval = send_arp(sockfd, &peer_addr);
continue;
}
else //success
{
break;
}
}
usleep(ARP_DELAY);
}
close(sockfd);
printf("arp test end*************************************************************\n");
return 0;
}
ARP 探测 C语言实现
最新推荐文章于 2023-12-15 13:36:36 发布