146_路由器项目_附加功能:可以拿取文件内IP保存到过滤链表中,过滤IP也可以保存到txt文件,也可以终端输入IP,保存到文件【单链表的尾插、头插、删除指定节点、遍历等】】

本文介绍了一个路由器项目的附加功能,利用链表来存储和管理过滤IP。用户可以将IP从文件中读取并保存到过滤链表,同时也可以将过滤IP保存到TXT文件中。此外,支持通过终端输入IP直接保存到文件,实现IP的动态管理。涉及到的操作包括链表的尾插、头插、删除指定节点以及遍历等操作。
摘要由CSDN通过智能技术生成

动图:

在这里插入图片描述

在这里插入图片描述

ip_file.h:

#ifndef IP_FILE_H
#define IP_FILE_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>


//*************************过滤链表******************************
typedef struct myrouter
{
    unsigned char ip[32] ;
    struct myrouter* next;
}MY_ROU;

//释放链表
extern MY_ROU* rou_freeLink(MY_ROU *head);
//尾插
extern MY_ROU *rou_pTailInsert(MY_ROU *head);
//遍历
extern void rou_print_link(MY_ROU *head);
//查找ip
extern int rou_searcharpLink(MY_ROU *head,char *ip);
//删除
extern MY_ROU *rou_pDeleteLink(MY_ROU *head);
//*************************过滤链表******************************

/******************************************************************
函	数:	void init_ip_link()
功	能:	读取配置文件数据到链表
参	数:	无
返回值: 无
*******************************************************************/
extern void init_ip_link();

/******************************************************************
函	数:	IP_LINK *find_ip(IP_LINK *head, unsigned char *ip)
功	能:	插入ip过滤链表
参	数:	IP_LINK *head ip过滤链表头  IP_LINK* p 待插入节点
返回值: IP_LINK *找到的节点
*******************************************************************/
extern MY_ROU *inner_ip_link(MY_ROU *head,MY_ROU* p);

/******************************************************************
函	数:	void save_ip_link()
功	能:	保存链表数据到配置文件
参	数:	无
返回值: 无
*******************************************************************/
extern void save_ip_link();

#endif

ip_file.c:–与main.c共用一个结构体指针变量,保存过滤IP链表头节点

//与main.c共用一个结构体指针变量,保存过滤IP链表头节点
MY_ROU * roulink_head = NULL;

.
.

#include "ip_file.h"
#define ip_config_name "ip_config"

//与main.c共用一个结构体指针变量,保存过滤IP链表头节点
MY_ROU * roulink_head = NULL;

//--------------------操作文件中的过滤IP----------------------//
void init_ip_link()
{
    FILE *ip_config = NULL;
    ip_config = fopen(ip_config_name,"rb+");
	if(ip_config == NULL){
		perror("!!!configure file,in main.c");
		_exit(1);
	}
	puts("filter IP:");
    int i = 0;
    while(1)
    {
        
        char buff[500]="";
        bzero(buff, sizeof(buff));
        int ip;
        if(fgets(buff, sizeof(buff), ip_config) == NULL)
        {
            printf("ip_config 文件为空\n");
            break;
        }
        if(strlen(buff) < 7)//1.1.1.1
        {
            break;
        }
        buff[strlen(buff)-1]=0;//注意文件中存在\r
        //printf("IP[%d] = %s\n",i++,buff);
        inet_pton(AF_INET, buff, &ip);

        MY_ROU *pb = (MY_ROU *)malloc(sizeof(MY_ROU));	
        char ip_buf[16] = "";
        inet_ntop(AF_INET, &ip, ip_buf, 16);
        //printf("ip_buf[%d] = %s\n", ++i, ip_buf);
        //strcpy(pb->ip, ip_buf);
        memcpy(pb->ip, ip_buf, 16);
        printf("pb->ip[%d] = %s\n", i, pb->ip);

        //传入变化的头节点 + 带有IP信息的结构体指针变量
        roulink_head = inner_ip_link(roulink_head, pb);
        i++;
    }

    //rou_print_link(ip_head);
	fclose(ip_config);
}

MY_ROU *inner_ip_link(MY_ROU *head, MY_ROU* p)
{

    // head = (MY_ROU*)malloc(sizeof(MY_ROU));     //创建头结点 
    // head->next = NULL;
    MY_ROU * pb = head;
	int a = rou_searcharpLink(head, p->ip);//查找是否有该记录
    if(a == 0)
    {
        if(pb==NULL)
        {//未查找到,插入链表,直接插入表头方便
            p->next = NULL;
            head = p;
        }
        else
        {           
            #if 1  //头插法--寻找插入的节点              
                MY_ROU * p2_new = (MY_ROU*)malloc(sizeof(MY_ROU)); 
                strcpy(p2_new->ip, p->ip);
                // printf("继续头插!!!!p2_new->ip = %s!!!!!!\n",p2_new->ip);
                p2_new->next = pb->next;
                pb->next = p2_new;
            #endif                                  
            #if 0 //尾插法--正确
                MY_ROU *p1=pb;
                while(p1->next!=NULL)
                {
                    p1=p1->next;
                }
                //插入
                p1->next=p;  
            #endif             
        }
    }
	return head;
}

void save_ip_link()
{
    FILE *ip_config = fopen(ip_config_name,"wb+");
	if(ip_config == NULL){
		perror("!!!configure file,in main.c");
		_exit(1);
	}

    char buff[20]="";
	MY_ROU *pb=roulink_head;
    while(pb != NULL)
    {
        printf("!保存2命令输入IP\n");
        memcpy(buff, pb->ip, 16);//一次拷贝16个字节
        buff[strlen(buff)+1]='\n';//注意文件中存在\r

        //一个IP新切换一行保存到文件
        fprintf(ip_config, "%s\n", buff);
		pb = pb->next;
    }
    fclose(ip_config);
}
//--------------------操作文件中的过滤IP----------------------//




//*************************过滤链表******************************//
//尾插
MY_ROU *rou_pTailInsert(MY_ROU *head)
{

    //申请一个待插入的空间
    MY_ROU *pi=(MY_ROU*)malloc(sizeof(MY_ROU));
    pi->next=NULL;
    printf("输入过滤ip:");
    //向空间中插入数据
    scanf("%s",pi->ip);
    //判断是否有数据
    if(head==NULL)
    {
        head=pi;
    }
    else
    {
        //寻找插入的节点
        MY_ROU *p1=head;
        while(p1->next!=NULL)
        {
            p1=p1->next;
        }
        //插入
        p1->next=pi;
    }
    

    printf("设置完成\n");
    return head;
}

//遍历
void rou_print_link(MY_ROU *head)
{
    if(head==NULL)
    {
        printf("没有数据\n");
    }
    else
    {
        while(head!=NULL)
        {
            printf("ip:%s\n",head->ip);
            head=head->next;
        }
    }
    return;
}

//释放链表
MY_ROU* rou_freeLink(MY_ROU *head)
{
    MY_ROU *pd;
    pd=head;
    while(head!=NULL)
    {
        head=pd->next;
        free(pd);
        pd=head;
    }
    printf("过滤链表释放完毕\n");
    return head;
}

//查找ip
int rou_searcharpLink(MY_ROU *head,char *ip)
{
    MY_ROU * pb = head;
    int i=0;
    while(pb!=NULL)
    {
        if(strcmp(ip, pb->ip)==0)
        {
            i++;
            //printf("存在相同ip\n");
            return 1;
        }
        pb = pb->next;
    }
    if(0==i)
    {
        //printf("未找到ip\n");
        return 0;
    }
}

//删除
MY_ROU *rou_pDeleteLink(MY_ROU *head)
{
    char num[16]="";
    MY_ROU *pe=head;
    MY_ROU *pf=head;

    printf("请输入你要删除的ip:");
    scanf("%s",num);

    if(NULL==head)
    {
        printf("无可删除数据\n");
    }
    else
    {
        while(strcmp(pe->ip,num))
        {
            pf=pe;
            pe=pe->next;
            if(NULL==pf->next)
            {
                printf("未找到要删除数据\n");
                return head;
            }
        }

        if(pe==head)
        {
            head=pe->next;
            free(pe);
        }
        else
        {
            pf->next=pe->next;
            free(pe);
        }
    }
    return head;
}
//*************************过滤链表******************************

main.c:–与ip_file.c共用了一个过滤IP链表的头节点

extern MY_ROU * roulink_head;//与ip_file.c共用一个结构体指针变量,保存过滤IP链表头节点

.
.

#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/ether.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include "get_interface.h"
#include "arp_link.h"
#include"ip_file.h"


extern MY_ROU * roulink_head;//与ip_file.c共用一个结构体指针变量,保存过滤IP链表头节点
MY_ARP * arplink_head = NULL;
int sockfd = 0;
//*************************人机交互线程**********************************
void *callback1(void *arg)
{ 
    while(1)
    {  
        printf("输入相应的序号,实现对应功能\n");
        int usercmd = -1;
        scanf("%d", &usercmd);
        switch (usercmd)
        {
        case 0:
            getchar();
            title();
            break;
        case 2:                    
            getchar();//接收输入2的回车
            roulink_head=rou_pTailInsert(roulink_head);
            break;        
        case 3:
            getchar();
            roulink_head=rou_pDeleteLink(roulink_head);
            break;
        case 4:
            getchar();
            rou_print_link(roulink_head);/*将指针pHead传入输出函数遍历输出*/           
            printf("链表打印完毕!\n");
            break;        
        case 5:
            arp_print_link(arplink_head);
            break;
        case 6:
            save_ip_link();
            break;
        case 10:
            printf("10:退出路由器,释放IP、ARP链表\n");
            getchar();
            arp_freeLink(arplink_head);
            rou_freeLink(roulink_head);//释放链表
            exit(1);
            break;
        }
    }
    pthread_exit(NULL);
}
//*************************人机交互线程**********************************


//*************************ARP应答的IP和MAC存入缓存链表线程【开始】**************//
void * callback2_arp(void *arg)
{
    arp_mac_ip *p = (arp_mac_ip*)arg;
    
    //printf("将 ARP 应答的 IP 和 MAC 存入缓存链\n");
    //printf("### %s\n", p->stc_ip);
    if(arp_searcharpLink(arplink_head, p->stc_ip) == 0)
    {
        //printf("插入链表中没有的ARP 应答 IP 和 MAC\n");
        arplink_head = arp_pTailInsert( arplink_head, p->stc_mac ,p->stc_ip);
    }

    pthread_exit(NULL);
}
//*************************ARP应答的IP和MAC存入缓存链表线程【结束】***************//


//*************************IP包转发线程【开始】**********************************//
void *callback3_ip(void *arg)
{
    
    //发送接口的结构体
    struct sockaddr_ll sll;
    ip_buf *pthread_ip_buf = (ip_buf *)arg;
  

    unsigned char * ip_head= pthread_ip_buf->buf + 14;
    char dst_ip[16] = "";

    inet_ntop(AF_INET, ip_head + 16, dst_ip, 16);
    printf("IP包转发线程中 目的 dst_ip = %s\n", dst_ip);


    int i = 0;
    for (i = 0; i < 16; i++)
    {
       
        unsigned char ip[16]=""; 
        inet_ntop(AF_INET,net_interface[i].ip, ip, 16);//get_interface文件中得到的都是32位无符号整形数据(计算机数据),现转成成点分十进制(人能够书别的)

        //---------------------[调试]----------------------------------------//
        //printf("设置网卡循环进入次数 i = %d\n", i);
        //printf("检索到的所有网卡名字net_interface[i].name = %s\n", net_interface[i].name);
        //printf("net_interface[i].ip = %s\n",ip);
        //---------------------[调试]----------------------------------------//

        if(strncmp(ip,  dst_ip, 9) == 0)//根据目标网段 查找活跃网卡
        {   
            //网卡结构体
            struct ifreq ethreq;
            strncpy(ethreq.ifr_name, net_interface[i].name , IFNAMSIZ);//指定网卡名字
            printf("网卡名字:%s\n", ethreq.ifr_name);
            
            if(ioctl(sockfd, SIOCGIFINDEX, &ethreq) == -1)//获取网卡接口地址
            {
                return 0;
            }

            bzero(&sll, sizeof(sll));
            sll.sll_ifindex = ethreq.ifr_ifindex;//将网卡的接口类型赋值给发送接口
            break;
        }
        else
        {
            //printf("找不到网段对应的网卡,继续查\n");
            continue;
        }
    }

    //--------------------------------------------拿到网卡,开始检索对应网卡所有数据,对比【开始】------------------------------------------------------//
    if(strcmp(dst_ip + strlen(dst_ip) - 3, "255") == 0)//是 否为广 播地址
    {
       // printf("是广播地址, 退出线\n"); 
        return;              
    }
    else
    {
        //printf("不是广播地址,判断是否为回 环地址\n");
        if(strcmp("127.0.0.1",  dst_ip) == 0)
        {
            //printf("是回 环地址, 退出线\n");
            return;                      
        }
        else
        {
            //printf("查找ARP缓存表 对应 MAC\n");
            //指定目的MAC地址
            //可以在链表中找到目的IP,组ICMP包的目的MAC就可以了
            //之所以这样,是因为在网络中的ICMP包里,变化的只有目的MAC,源MAC、IP都不会发生变动
            if(arp_searcharpLink(arplink_head, dst_ip) == 1)
            {  
                //1网段中 指定目标IP是主机的IP、MAC
                //2C-4D-54-57-04-7F
                //printf("****icmp****\n");
                if(strncmp("192.168.1.49", dst_ip, 9) == 0)
                {
                    pthread_ip_buf->buf[0]=0x2C;
                    pthread_ip_buf->buf[1]=0x4D;
                    pthread_ip_buf->buf[2]=0x54;
                    pthread_ip_buf->buf[3]=0x57;
                    pthread_ip_buf->buf[4]=0x04;
                    pthread_ip_buf->buf[5]=0x7F;//目标
                    int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));

                    //-------------------[调试]------------------------//
                    //printf("****1 网段 icmp缓存表****\n");   
                    // printf("send_len ICMP 1 = %d\n", send_len);
                    //-------------------[调试]------------------------//

                }
                //2网段中 指定目标IP是开发板的IP、MAC
                //  00:53:50:00:01:33
                else if(strncmp("192.168.2.100", dst_ip, 9) == 0)
                {                   
                    pthread_ip_buf->buf[0]=0x00;
                    pthread_ip_buf->buf[1]=0x53;
                    pthread_ip_buf->buf[2]=0x50;
                    pthread_ip_buf->buf[3]=0x00;
                    pthread_ip_buf->buf[4]=0x59;
                    pthread_ip_buf->buf[5]=0x12;
                   
                    //发送给套接字的数据长度,是实际传送过来的长度(main中的IP包有收到具体长度信息)
                    int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));

                    //-------------------[调试]------------------------//
                    //printf("****2 网段 icmp缓存表****\n");   
                    // printf("send_len ICMP 2 = %d\n", send_len);
                    //-------------------[调试]------------------------//
                }
            }
            else
            {//没在链表中没有找到目的IP,需要重新组arp包才行

                //printf("***************组ARP包\n");
                int i = 0;
                for(; i < 3; i++)
                {     
                    //printf("%s\n",dst_ip);  
                    //比对到1网段的数据             
                    if(strstr(dst_ip,"192.168.1") != 0)                      
                    {
                        printf("发送网段1arp包\n");
                        unsigned char arp_buf[42] = {
                        0xff,0xff,0xff,0xff,0xff,0xff,//目的mac,广播的形式发出去,等待目的IP恢复后覆盖
                        0x00,0x0c,0x29,0xfa,0x7c,0x9e,//源mac
                        0x08, 0x00,//协议类型
                        0, 1,//硬件类型
                        6,
                        4,
                        0, 1,//op
                        0x00,0x0c,0x29,0xfa,0x7c,0x9e,//源mac(网卡1 ech0的MAC)
                        192,168,1,88,//源IP是路由器1网段的网关,通过它发送到2网段
                        0x00,0x00,0x00,0x00,0x00,0x00,//目的mac,等待目的IP恢复后覆盖
                        0,0,0,0
                        //192,168,1,49,
                        };
                        int int_ip=0;
                        inet_pton(AF_INET, dst_ip, &int_ip);
                        unsigned char *intp=(char *)&int_ip;
                        arp_buf[38]=intp[0];
                        arp_buf[39]=intp[1];
                        arp_buf[40]=intp[2];
                        arp_buf[41]=intp[3];
                        int send_len = sendto(sockfd, arp_buf, sizeof(arp_buf), 0, (struct sockaddr *)&sll, sizeof(sll));
                        printf("send_len 11 = %d\n",send_len);

                    }
                    //网卡2,ech1的MAC:00:0c:29:fa:7c:a8
                    else if(strstr(dst_ip,"192.168.2") != 0)                      
                    {
                        printf("发送网段2arp包\n");
                        unsigned char arp_buf[42] = {
                        0xff,0xff,0xff,0xff,0xff,0xff,//目的mac
                        0x00,0x0c,0x29,0xfa,0x7c,0xa8,//源mac
                        0x08, 0x00,//协议类型
                        0, 1,//硬件类型
                        6,
                        4,
                        0, 1,//op
                        0x00,0x0c,0x29,0xfa,0x7c,0xa8,//源mac
                        192,168,2,89,//源IP是路由器2网段的网关,通过它发送到1网段
                        0x00,0x00,0x00,0x00,0x00,0x00,//目的mac
                        192,168,2,100,
                        };
                        int send_len = sendto(sockfd, arp_buf, sizeof(arp_buf), 0, (struct sockaddr *)&sll, sizeof(sll));
                        printf("send_len 22 = %d\n",send_len);

                    }

                    if(arp_searcharpLink(arplink_head, dst_ip) == 1)
                    {
                        //1
                        //2C-4D-54-57-04-7F
                        if(strncmp("192.168.1.49", dst_ip, 9) == 0)
                        {
                            pthread_ip_buf->buf[0] =  0x2C;
                            pthread_ip_buf->buf[1] =  0x4D;
                            pthread_ip_buf->buf[2] =  0x54;
                            pthread_ip_buf->buf[3] =  0x57;
                            pthread_ip_buf->buf[4] =  0x04;
                            pthread_ip_buf->buf[5] =  0x7F;
                            int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));
                            //-------------------[调试]------------------------//
                            //printf("****3次发ARP过程中检索到ICMP包 1 网段****\n");   
                            // printf("send_len ICMP 1 = %d\n", send_len);
                            //-------------------[调试]------------------------//
                        }
                        //2
                        // 开发板MAC(每次启动都会变化):00:53:50:00:3B:DB
                        else if(strncmp("192.168.2.100", dst_ip, 9) == 0)
                        {
                            pthread_ip_buf->buf[0] =  0x00;
                            pthread_ip_buf->buf[1] =  0x53;
                            pthread_ip_buf->buf[2] =  0x50;
                            pthread_ip_buf->buf[3] =  0x00;
                            pthread_ip_buf->buf[4] =  0x59;
                            pthread_ip_buf->buf[5] =  0x12;
                            int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll));
                            //-------------------[调试]------------------------//
                            //printf("****3次发ARP过程中检索到ICMP包 2 网段****\n");   
                            // printf("send_len ICMP 2 = %d\n", send_len);
                            //-------------------[调试]------------------------//

                        }
                        break;
                    }
                }
            }

            return;

        }
    } 
    //--------------------------------------------拿到网卡,开始检索对应网卡所有数据,对比【结束】------------------------------------------------------//


    pthread_exit(NULL);

}
//*************************建IP包转发线程【结束】**********************************//

int main()
{
    //初始化 配置文件
	init_ip_link();

    //创建原始套接字,接收发送方的网卡信息
    sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if(sockfd<0)
    {
        perror("sockfd:");
        return 0;
    }
    getinterface();//拿取网卡信息(虚拟机的所有网卡,包括回环网卡)

    pthread_t pth;
    pthread_create(&pth, NULL, callback1, NULL);//人机交互线程,这里可以放在main里面

    int len = 0;

    char recv_buff[RECV_SIZE]="";//原始套接字数据包大约为1500个字节
	ssize_t recv_len=0;
    while(1)
    {              
        //开始接收其他人的网卡信息
        bzero(recv_buff,sizeof(recv_buff));
       
        //[recv_len]设置成全局变量,让线程可以共用数据
        recv_len = recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0,  NULL, NULL);
        if(recv_len<=0||recv_len>RECV_SIZE)
        {
		    perror("recvfrom");
			continue;
		}
        //printf("链路层截取数据包长度 recv_len=%d\n",recv_len);

        //MAC包类型
        unsigned short mac_type = 0;
        mac_type = ntohs( *((unsigned short *)(recv_buff + 12)));
        if(mac_type == 0x0800)
        {
            //printf("-----------ip数据包------------\n");
            unsigned char *ip_head = recv_buff + 14; 
            unsigned char dst_ip[16] ="";
            inet_ntop(AF_INET, ip_head + 16, dst_ip, 16);

            //IP包的类型
            if(ip_head[9] == 1)
            {
                //printf("-----ICMP数据包\n");
                //查找过滤IP链表中存在我们指定的目的IP吗
                if(rou_searcharpLink(roulink_head, dst_ip) == 0)
                {
                    static int i=0;
                          
                    //-----------调试,打印原始套接字接收到的数据内容是否是空--------------------//           
                    //printf("i=%d   IP包中的目的IP = %d\n",++i, strlen(recv_buff + 30));                             
                    // printf("Rvfbuf=%p\n",recv_buff);
                    // int kk=0;
                    // while(kk<98)
                    // {
                    //     printf("Rvfbuf[%d]=%d\n",kk,recv_buff[kk]);
                    //     kk++;

                    // }
                    //----------------------------[调试]---------------------------------------//

                    usleep(1000); 
                    ip_buf *recv = (ip_buf *)malloc(sizeof(ip_buf));
                    recv->my_buf_date_len = recv_len;
                    memcpy(recv->buf, recv_buff, recv_len);

                    //线程的创建放在满足它的条件中,while循环,满足就进来创建一个,切记不要放到条件外面创建线程,否则只会创建一个,导致所有情况共用一个线程
                    pthread_t pth2;
                    //最后数据包是ICMP的整包
                    pthread_create(&pth2, NULL, callback3_ip, (void*)recv);
                    pthread_detach(pth2);
                }

            }

        }
        else if(mac_type == 0x0806)
        {           
            arp_mac_ip * head_mac_ip = NULL;//保存目的MAC\IP的结构体,安全措施,防止栈空间释放导致给线程传参为空,失败
            head_mac_ip = (arp_mac_ip *)malloc(sizeof(arp_mac_ip ));
            
            
            unsigned char *arp_head = recv_buff + 14;
            unsigned char * arp_src_mac =  arp_head + 8;//跳过[4.硬件类型、5.协议类型、6.硬件地址长度、7.协议地址长度、8.OP,拿到源MAC地址首地址信息]
            unsigned char stc_mac[18] = "";
            sprintf(stc_mac, "%02x:%02x:%02x:%02x:%02x:%02x", arp_src_mac[0],\
                arp_src_mac[1],\
                arp_src_mac[2], \
                arp_src_mac[3],\
                arp_src_mac[4], \
                arp_src_mac[5]);
            strcpy(head_mac_ip->stc_mac, stc_mac);
                   
            unsigned char src_ip[16]  = "";
            inet_ntop(AF_INET, arp_head + 14, src_ip, 16);//拿到源IP           
            strcpy(head_mac_ip->stc_ip, src_ip);

            //-----------------------------------[调试]-----------------------------------//   
            //printf("-----------arp数据包------------\n");
            //printf("arp 源mac:%s\n",head_mac_ip->stc_mac);        
            //printf("arp 源IP:src_ip = %s  \n", src_ip); 
            //-----------------------------------[调试]-----------------------------------//  

            //线程中只保存源ARP的MAC、IP,目的主机的MAC、IP,在IP线程中指定(写死)
            pthread_t pth1;
            pthread_create(&pth1, NULL, callback2_arp, (void*)head_mac_ip);
            pthread_detach(pth1);
        }


    }

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扳手的海角

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值