09 网络ARP请求,响应,ICMP协议

news2024/11/18 5:47:10

arp协议_arp请求_arp回应

ICMP包构造ping搜狐服务器参考

#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <pthread.h>

unsigned short in_cksum(unsigned short *addr, int len)
{
    unsigned int sum = 0, nleft = len;
    unsigned short answer = 0;
    unsigned short *w = addr;
 
    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }
    if (nleft == 1) {
        *(u_char *) (&answer) = *(u_char *) w;
        sum += answer;
    }
    sum = (sum >> 16) + (sum & 0xffff);//将高16bit与低16bit相加
 
    sum += (sum >> 16);//将进位到高位的16bit与低16bit 再相加
    answer = (unsigned short)(~sum);
    return (answer);
}

unsigned char ICMPBuf[]=
{
    //===链路层
        0x48, 0x5a, 0xea, 0x98, 0x27, 0x3c, //目标MAC为网关的MAC
        0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //ubuntu源MAC
        0x08, 0x00,                         // ICMP协议是属于IP包
    //===IP层或者说 网络层
        0x45,//4代表IPV4   5代表IP头(5*4=20个字节)
        0x00,//服务类型,可以反映当前主机一些状态信息,可以直接填0
        0,0,//IP包的长度,也不是整个包字节-链路层14个字节?
        0x00,0x00,0x40,0x00,//数据包标示编号设置为0,数据包不支持分片功能
        64,//默认TTL time to live 64最多可以过64个路由器
        1,//ICMP协议
        0,0,//IP包头的20个字节校验和
        192,168,1,11,//源IP,发送方ubuntu的IP
        47,91,20,194,//目标IP,搜狐服务器IP

       //ICMP请求内容
        0x08,0x00,//为ICMP请求包,如果是0x00,0x00,是回应
        0x00,0x00,//ICMP报文校验
        0,0,//通常填大端的getpid(),也可以填默认0 
        0x00,0x2b,//发送的包编号 43,可以随意填,回应包编号和发送包一样
 
        // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 时间戳 8个字节可加也可不加
                                    
        '1','2','3','4','5',//数据内容可以任意
        'h','e','l','l','o'        
       };





192.168.18.10

192.168.59

192.168.18.10
192.168.18+100.10






void *myfun(void *arg)
{
    int sockfd = (int)arg;
    unsigned char recvbuf[100] = {0};
    while (1)
    {
        int recvlen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
        if ((recvbuf[12] == 0x08) && (recvbuf[13] == 0x00))
        {//IP包

            if (recvbuf[23] == 0x01)
            {//ICMP协议
               
               if((recvbuf[34] == 0x00)&&(recvbuf[35] == 0x00))
               {//回应

                   printf("hjs收到搜狐网服务器ICMP回应包:TTL=%d,经过%d个路由器\n",recvbuf[22],64-recvbuf[22]);
                   
               }
              
            }
        }
   
    }

    retursn NULL;
}
int main()
{
    unsigned char data[]={0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,0x40,0x01,\
                    0,0,0xc0,0xa8,0x01,0x0b,0x2f,0x5b,0x14,0xc2};
    printf("%#x\n",htons(in_cksum(data,20)));
    //设置包编识
     unsigned short mypid=getpid();
   // *(unsigned short *)(ICMPBuf+38)=htons(mypid);

    //填入IP包长度
    *(unsigned short *)(ICMPBuf+16)=htons(sizeof(ICMPBuf)-14);
    //IP包头校验
    *(unsigned short *)(ICMPBuf+24)=in_cksum(ICMPBuf+14,20);//htons(in_cksum(ICMPBuf+14,20));
    //ICMP部分校验
    unsigned short icmplen=sizeof(ICMPBuf)-34;
    *(unsigned short *)(ICMPBuf+36)=in_cksum(ICMPBuf+34,sizeof(ICMPBuf)-34);//htons(in_cksum(ICMPBuf+34,sizeof(ICMPBuf)-34));
    
    
     int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

    struct sockaddr_ll mysocket;
    struct ifreq ethreq;

    strcpy(ethreq.ifr_ifrn.ifrn_name, "eth0");
    ioctl(myfd, SIOCGIFINDEX, &ethreq);
    memset(&mysocket, 0, sizeof(mysocket));

    mysocket.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue; //网卡信息的首地址

    pthread_t thread;
    pthread_create(&thread, NULL, myfun,(void *)myfd);
    pthread_detach(thread);
    printf("myfd=%d\n", myfd);
    
    int var = sendto(myfd, ICMPBuf, sizeof(ICMPBuf), 0, (struct sockaddr *)&mysocket, sizeof(mysocket));

    sleep(2);
    close(myfd);
}

icmp协议_请求和回应 (1)

扫描局域网主机MAC和IP参考

#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <pthread.h>

unsigned char ArpBuf[] =
    {
        0xFF, 0XFF, 0XFF, 0XFF, 0xFF, 0XFF, //目标MAC,广播
        0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //源MAC,当前主机ARP请求包发出网卡的MAC
        0x08, 0x06,                         // ARP包
        0x00, 0x01,                         //以太网类型
        0x08, 0x00,                         // IPv4
        0x06,                               //硬件地址MAC 为6个字节
        0x04,                               //网络地址 IP 为4个字节
        0x00, 0x01,                         // arp 请求
        0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //发送方MAC
        0xc0, 0xa8, 0x01, 0x0b,             //发送方IP 192.168.1.11
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //目标MAC                               
        192, 168, 1, 0};//最后一个字节待定

void *myfun(void *arg)
{
    int sockfd = (int)arg;
    unsigned char recvbuf[100] = {0};
    while (1)
    {
        int recvlen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
        if ((recvbuf[12] == 0x08) && (recvbuf[13] == 0x06))
        {//ARP 包

            if ((recvbuf[20] == 0x00) && (recvbuf[21] == 0x02))
            {//ARP 回应
               
                printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x===>",
                       recvbuf[22], recvbuf[23], recvbuf[24], recvbuf[25], recvbuf[26], recvbuf[27]);
                printf("IP: %d.%d.%d.%d\n",\
                       recvbuf[28], recvbuf[29], recvbuf[30], recvbuf[31]);
              
            }
        }
       // printf("recvlen=%d\n", recvlen);
    }

    retursn NULL;
}
int main()
{
    int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));//创建一个原始套接字

    struct sockaddr_ll mysocket;
    struct ifreq ethreq;

    strcpy(ethreq.ifr_ifrn.ifrn_name, "eth0");//设置属性,等下sendto就从 eth0网卡发送出去数据包
    ioctl(myfd, SIOCGIFINDEX, &ethreq);
    memset(&mysocket, 0, sizeof(mysocket));

    mysocket.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue; //网卡信息的首地址

    pthread_t thread;
    pthread_create(&thread, NULL, myfun,(void *)myfd);
    pthread_detach(thread);
    printf("myfd=%d\n", myfd);
    int cnt=1;
    while(cnt < 255)
    {
        
        ArpBuf[41]=cnt;   
        int var = sendto(myfd, ArpBuf, sizeof(ArpBuf), 0, (struct sockaddr *)&mysocket, sizeof(mysocket));
        cnt++;
    }
    sleep(2);
    close(myfd);
}

原始套接字构造ARP请求包获取网关的MAC

//使用原始套接字,拿到当前局域网内,所有主机的IP和MAC
// #include <stdio.h>
// #include <sys/types.h> /* See NOTES */
// #include <sys/socket.h>

// #include <linux/if_ether.h> //ETH_P_ALL
// #include <net/if.h>
// #include <sys/ioctl.h>

// #include <linux/if_packet.h> //struct sockaddr_ll
// #include<string.h>
// #include<stdlib.h>
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>

// unsigned char ArpBuf[] = {
//     0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, //目标MAC,ARP广播地址
//     0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c,       //源MAC,虚拟机ubuntu的MAC
//     0x08, 0x06,                               //是ARP包
//     0x00, 0x01,                               //是以太网类型帧
//     0x08, 0x00,                               //是IPV4协议
//     0x06,                                     //硬件地址MAC是6个字节
//     0x04,                                     //网络地址IP是4个字节
//     0x00, 0x01,                               //这是一个ARP请求包
//     0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c,       //源MAC
//     192, 168, 1, 11,                          //源IP
//     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//     192, 168, 1, 1 //目标的IP
// };                 //其实一个ARP包是48个字节
// // 17  9   7  8  1

unsigned char ArpBuf[] =
    {
        0xFF, 0XFF, 0XFF, 0XFF, 0xFF, 0XFF, //目标MAC
        0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //源MAC
        0x08, 0x06,                         // ARP包
        0x00, 0x01,                         //以太网类型
        0x08, 0x00,                         // IPv4
        0x06,                               //硬件地址MAC 为6个字节
        0x04,                               //网络地址 IP 为4个字节
        0x00, 0x01,                         // arp 请求
        0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //发送方MAC
        0xc0, 0xa8, 0x01, 0x0b,             //发送方IP 192.168.1.11
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //目标MAC
                                            // 0xc0,0xa8,0x01,0x09  //目标IP
        192, 168, 1, 1};

int main()
{
    // 192.168.1.0 组网,主机IP 192.168.1.1~192.168.1.254
    //手动构造192.168.1.1~192.168.1.254  的ARP请求包,在子网发送,拿到所有的
    // ARP回应包。回应包 IP和MAC提取出来打印出来。
    //经过扫描就可以拿到当前局域里所有的主机IP和MAC

    //创建原始套接字,补充协议需要主机字节序转网络字节序

    // int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

    // //指定从哪一个网卡发送出去?
    // //要获取一个个网卡 eth0

    // struct ifreq myeth;
    // memset(&myeth,0,sizeof(myeth));
    // strcpy(myeth.ifr_ifrn.ifrn_name, "eth0"); //填入网卡名字
    // ioctl(myfd, SIOCGIFINDEX, &myeth);        //获取网卡名为 eth0的信息,并填入到myeth

    // struct sockaddr_ll sll;
    // bzero(&sll,sizeof(sll));
    // sll.sll_ifindex = myeth.ifr_ifru.ifru_ivalue; //网卡信息的首地址

    // int ret = sendto(myfd, ArpBuf, sizeof(ArpBuf), 0, (struct sockaddr *)&sll, sizeof(struct sockaddr)); //把ARP封包发送出去
    int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

    struct sockaddr_ll mysocket;
    struct ifreq ethreq;

    // IFNAMSIZ
    // # define ifr_name	ifr_ifrn.ifrn_name
    // strcpy(ethreq.ifr_name,"eth0");仅仅是一个宏定义
    strcpy(ethreq.ifr_ifrn.ifrn_name, "eth0");
    ioctl(myfd, SIOCGIFINDEX, &ethreq);
    memset(&mysocket, 0, sizeof(mysocket));

    mysocket.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue; //网卡信息的首地址

    int var = sendto(myfd, ArpBuf, sizeof(ArpBuf), 0, (struct sockaddr *)&mysocket, sizeof(mysocket));

    printf("myfd=%d,ret=%d\n", myfd, var);

    unsigned char recvbuf[100] = {0};
    int recvlen = recvfrom(myfd, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
    printf("recvlen=%d\n", recvlen);
    int i = 0;
    recvlen = 42;
    while (i < recvlen)
    {
        if ((i % 10 == 0) && (i != 0))
        { //一行如果有10个字节,就换行打印
            printf("\n");
        }
        printf("%x ", recvbuf[i]);
        i++;
    }
    if ((recvbuf[12] == 0x08) && (recvbuf[13] == 0x06))
    {
        printf("这是ARP包!!\n");
        if ((recvbuf[20] == 0x00) && (recvbuf[21] == 0x02))
        {
            printf("这是回应包!!\n");
            printf("网关的MAC:  %02x:%02x:%02x:%02x:%02x:%02x\n",\
                   recvbuf[6], recvbuf[7], recvbuf[8], recvbuf[9], recvbuf[10], recvbuf[11]);
        }
    }

    close(myfd);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1548220.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

加密软件VMProtect教程:使用脚本Mach-O文件

VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic&#xff08;本机&#xff09;、Virtual Pascal和XCode编译器。 同时&#xff0c;VMProtect有一个内置的反汇编程序&#xff0c;可以与Windows和Mac OS X可执行文件一起…

怎么制作iOS证书

首先我们登录appuploder官网 搜索 appuploder 第一个就是我们官网啦&#xff0c;网址是&#xff1a;Appuploader home -- A tool improve ios develop efficiency such as submit ipa to appstore and manage ios certificate 可以跨平台开发&#xff0c;无论是Windows还是Ma…

前端面试题---->JavaScript

const声明的对象属性和数组的值可以被修改吗&#xff1f;为什么 原因&#xff1a;当使用const声明一个对象或数组时&#xff0c;实际上是保证了对象或数组的引用不会被修改&#xff0c;但对象或数组本身的属性或元素是可以被修改的。这是因为const只能保证指向的内存地址不变&a…

搭载前净柔泉女冲技术的科勒马桶盖,你的家中必备

近几年智能家居逐渐成为众多家庭的首选&#xff0c;尤其是智能马桶已经逐渐变成家中必备&#xff0c;但智能马桶动辄几千上万的价格让很多家庭望而却步&#xff0c;于是智能马桶盖应运而生。科勒清舒宝智能便盖不仅可以适配市面上大多数马桶&#xff0c;而且功能丰富&#xff0…

基于springboot+vue调用百度ai实现车牌号识别功能

百度车牌号识别官方文档 结果视频演示 后端代码 private String getCarNumber(String imagePath, int count) {// 请求urlString url "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";try {byte[] imgData FileUtil.readFileByBytes(imagePath);Stri…

精酿啤酒:多阶段发酵工艺的特点与优势

Fendi Club啤酒采用多阶段发酵工艺&#xff0c;这种工艺在啤酒酿造中具有显著的特点和优势。 首先&#xff0c;多阶段发酵工艺是一种复杂的酿造过程&#xff0c;它包括多个阶段的发酵和陈化过程。这种工艺需要切确控制每个阶段的时间、温度和酵母种类等参数&#xff0c;以确保…

【揭秘】企讯通106短信通知:那些你不可不知的“幕后功臣”

在日常生活中&#xff0c;你是否留意过那些来自“106”开头的短信&#xff1f;它们悄无声息地出现在你的手机收件箱&#xff0c;为你带来账单提醒、验证码、优惠活动等各类重要信息。看似平淡无奇的“106短信通知”&#xff0c;实则蕴含着丰富的科技力量与智慧结晶。今天&#…

together.ai简介

Together AI Solutions | Fastest Tools for Building Private Models for Enterprise Quickstart

【linux深入剖析】基础IO操作 | 使用Linux库函数实现读写操作 | 文件相关系统调用接口

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1.复习C文件IO相关操…

设计模式深度解析:深入浅出的揭秘游标尺模式与迭代器模式的神秘面纱 ✨

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 深入浅出的揭秘游标尺模式与迭代器模式的神秘面纱 开篇&#xff1a; 欢迎来到设计模式的神秘…

如何在数字化转型中确保数据安全

随着科技的飞速发展&#xff0c;数字化转型已成为企业发展的必然趋势。数字化转型是指企业利用数字技术对业务流程、组织结构和商业模式进行全面创新和变革&#xff0c;以提高企业的竞争力和创新能力。然而&#xff0c;在数字化转型过程中&#xff0c;数据安全问题日益凸显&…

胖东来:超越零售巨头山姆和Costco的秘密武器

在零售业的江湖中&#xff0c;胖东来这个名字正在悄然崭露头角。3月26日&#xff0c;胖东来创始人于东来豪言壮志地表示&#xff0c;未来3-5年内&#xff0c;他的目标是超越零售巨头山姆和Costco。这不仅仅是一个口号&#xff0c;而是胖东来凭借自身实力&#xff0c;逐步迈向更…

为什么requests不是python标准库?

在知乎上看到有人问&#xff1a;为什么requests不是python标准库&#xff1f; 这确实是部分人困惑的问题&#xff0c;requests作为python最受欢迎的http请求库&#xff0c;已经成为爬虫必备利器&#xff0c;为什么不把requests直接装到python标准库里呢&#xff1f;可以省去第…

什么是公网IP?

公网IP&#xff0c;即公开网络IP地址&#xff0c;是指在互联网中公开可见、可访问的IP地址。每个设备在连接互联网时&#xff0c;都需要一个唯一的公网IP地址&#xff0c;以便其他设备可以定位并与之通信。 尽管公网IP在网络通信中具有重要作用&#xff0c;但它也带来了一些安全…

扫码登录到底是怎么实现的?

扫码登录的原理&#xff0c;其实很简单。 扫码登录的本质是&#xff0c;通过已经登录过的 App 应用&#xff0c;扫描未登录的 Web 端程序中的二维 码&#xff0c; 通过某种机制触发登录凭证的写入从而实现 Web 端自动登录的过程。 1、首先&#xff0c;在网页端打开登录页面&…

低功耗电子方案开发定制

低功耗电子方案开发定制 东莞市酷得智能科技有限公司是一家专注于为客户提供高质量解决方案的创新型科技公司。成立于2018年&#xff0c;我们的使命是通过技术创新和卓越的服务&#xff0c;帮助客户实现业务目标和价值最大化。 作为一家小而精悍的公司&#xff0c;我们拥有一支…

QML | JavaScript作用域和命名解析2

QML | JavaScript作用域和命名解析3.绑定的作用域对象 属性绑定是QML中最常见的JavaScript应用。属性绑定关联了一个JavaScript表达式的结果和对象的一个属性,该属性所归属的对象被称为绑定的作用域对象。在下面的代码中,Item对象就是一个绑定的作用域对象: ​ 绑定可以…

uniapp流浪动物救助小程序Java宠物领养小程序springboot

uniapp流浪动物救助小程序Java宠物领养小程序springboot 代码40块&#xff0c;需要的私聊 前台基于uniapp小程序 后台管理基于springbootvue前后端分离项目 开发语言&#xff1a;Java 框架&#xff1a;springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xf…

张宇1000题要刷崩溃了值不值得坚持做?

可以做1000题&#xff0c;但是复习效果可能不理想&#xff0c;因为1000题的内容难度高&#xff0c;最好基础好&#xff0c;能全程跟张宇的选择&#xff0c;否则容易浪费时间。 从题型上来看&#xff0c;1000题更注重于综合类的题目&#xff0c;题型上有些非常规。 使用1000题…

每日一题 --- 链表相交[力扣][Go]

链表相交 题目&#xff1a;面试题 02.07. 链表相交 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交**&#xff1a;** 题目数据 保证 整个链式结…