组arp头

获取到当前网段中所有机器的MAC地址:
每次指定一个机器发送MAC请求,通过发送多次ARP,即可得到当前网段内所有机器的MAC。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>
#include <pthread.h>

void *fun(void *arg)
{
    int sock_raw_fd = *(int *)arg;
    while(1)
    {
        unsigned char recv_msg[1024] = "";
        recvfrom(sock_raw_fd, recv_msg, sizeof(recv_msg),0, NULL, NULL);
        if(recv_msg[21] == 2) //ARP应答
        {
            char resp_mac[18] = "";
            char resp_ip[18] = "";
            sprintf(resp_mac, "%02x:%02x:%02x:%02x:%02x:%02x", \
                    recv_msg[22], recv_msg[23], recv_msg[24], \
                    recv_msg[25], recv_msg[26], recv_msg[27]);
            sprintf(resp_ip, "%d.%d.%d.%d", recv_msg[28], \
                    recv_msg[29], recv_msg[30], recv_msg[31]);
            printf("IP:%s - Mac:%s\n", resp_ip, resp_mac);
        }
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if(sock_raw_fd < 0)
    {
        perror("sock_raw_fd");
    }

    unsigned char send_buf[1024] = "";
    unsigned char d_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    unsigned char s_mac[6] = {0x00, 0x29, 0xc3, 0xfd, 0xe8, 0x33};
    unsigned char d_ip[4] = {10, 221, 1, 1};
    unsigned char s_ip[4] = {10, 221, 1, 55};

//组mac头 14字节
    //memcpy(send_buf, d_mac, 6);
    //memcpy(send_buf+6, s_mac, 6);
    //*(unsigned short *)(buf+12) = htons(0x0806);//转大端格式
    struct ether_header *eth = (struct ether_header *)send_buf;
    memcpy(eth->ether_dhost, d_mac, 6);
    memcpy(eth->ether_shost, s_mac, 6);
    eth->ether_type = htons(0x0806);

//组arp头 28字节
    struct arphdr *arp = (struct arphdr *)(send_buf+14);//去掉头部14字节
    arp->ar_hrd = htons(1);
    arp->ar_pro = htons(0x0806);
    arp->ar_hln = 6;
    arp->ar_pln = 4;
    arp->ar_op = htons(1);
    memcpy(arp->__ar_sha, s_mac, 6);
    memcpy(arp->__ar_sip, s_ip, 4);

    memcpy(arp->__ar_tip, d_ip, 4);

    struct ifreq ethreq;                        //网络接口地址
    strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); //指定网卡名称
    if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, &ethreq))
    {
        perror("ioctl"); 
        close(sock_raw_fd);
        exit(-1);
    }

    struct sockaddr_ll sll;                     //原始套接字地址结构
    bzero(&sll, sizeof(sll));
    sll.sll_ifindex = ethreq.ifr_ifindex;

    pthread_t pth;
    pthread_create(&pth, NULL, fun, &sock_raw_fd);

    int i = 0;
    unsigned char send_msg[1024] = "";
    for(i=1; i<255; i++)
    {
        send_msg[41] = i;
        int len = sendto(sock_raw_fd, send_msg, 42, 0, \
                        (struct sockaddr *)&sll, sizeof(sll));
        if(len == -1)
        {
            perror("sendto");
        }
    }
    pthread_join(pth, NULL);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一生要强的Zz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值