当前位置:   article > 正文

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

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

arp协议_arp请求_arp回应

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

  1. #include <stdio.h>
  2. #include <sys/types.h> /* See NOTES */
  3. #include <sys/socket.h>
  4. #include <linux/if_packet.h>
  5. #include <linux/if_ether.h>
  6. #include <string.h>
  7. #include <net/if.h>
  8. #include <sys/ioctl.h>
  9. #include <pthread.h>
  10. unsigned short in_cksum(unsigned short *addr, int len)
  11. {
  12. unsigned int sum = 0, nleft = len;
  13. unsigned short answer = 0;
  14. unsigned short *w = addr;
  15. while (nleft > 1) {
  16. sum += *w++;
  17. nleft -= 2;
  18. }
  19. if (nleft == 1) {
  20. *(u_char *) (&answer) = *(u_char *) w;
  21. sum += answer;
  22. }
  23. sum = (sum >> 16) + (sum & 0xffff);//将高16bit与低16bit相加
  24. sum += (sum >> 16);//将进位到高位的16bit与低16bit 再相加
  25. answer = (unsigned short)(~sum);
  26. return (answer);
  27. }
  28. unsigned char ICMPBuf[]=
  29. {
  30. //===链路层
  31. 0x48, 0x5a, 0xea, 0x98, 0x27, 0x3c, //目标MAC为网关的MAC
  32. 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //ubuntu源MAC
  33. 0x08, 0x00, // ICMP协议是属于IP包
  34. //===IP层或者说 网络层
  35. 0x45,//4代表IPV4 5代表IP头(5*4=20个字节)
  36. 0x00,//服务类型,可以反映当前主机一些状态信息,可以直接填0
  37. 0,0,//IP包的长度,也不是整个包字节-链路层14个字节?
  38. 0x00,0x00,0x40,0x00,//数据包标示编号设置为0,数据包不支持分片功能
  39. 64,//默认TTL time to live 64最多可以过64个路由器
  40. 1,//ICMP协议
  41. 0,0,//IP包头的20个字节校验和
  42. 192,168,1,11,//源IP,发送方ubuntu的IP
  43. 47,91,20,194,//目标IP,搜狐服务器IP
  44. //ICMP请求内容
  45. 0x08,0x00,//为ICMP请求包,如果是0x00,0x00,是回应
  46. 0x00,0x00,//ICMP报文校验
  47. 0,0,//通常填大端的getpid(),也可以填默认0
  48. 0x00,0x2b,//发送的包编号 43,可以随意填,回应包编号和发送包一样
  49. // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 时间戳 8个字节可加也可不加
  50. '1','2','3','4','5',//数据内容可以任意
  51. 'h','e','l','l','o'
  52. };
  53. 192.168.18.10
  54. 192.168.59
  55. 192.168.18.10
  56. 192.168.18+100.10
  57. void *myfun(void *arg)
  58. {
  59. int sockfd = (int)arg;
  60. unsigned char recvbuf[100] = {0};
  61. while (1)
  62. {
  63. int recvlen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
  64. if ((recvbuf[12] == 0x08) && (recvbuf[13] == 0x00))
  65. {//IP包
  66. if (recvbuf[23] == 0x01)
  67. {//ICMP协议
  68. if((recvbuf[34] == 0x00)&&(recvbuf[35] == 0x00))
  69. {//回应
  70. printf("hjs收到搜狐网服务器ICMP回应包:TTL=%d,经过%d个路由器\n",recvbuf[22],64-recvbuf[22]);
  71. }
  72. }
  73. }
  74. }
  75. retursn NULL;
  76. }
  77. int main()
  78. {
  79. unsigned char data[]={0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,0x40,0x01,\
  80. 0,0,0xc0,0xa8,0x01,0x0b,0x2f,0x5b,0x14,0xc2};
  81. printf("%#x\n",htons(in_cksum(data,20)));
  82. //设置包编识
  83. unsigned short mypid=getpid();
  84. // *(unsigned short *)(ICMPBuf+38)=htons(mypid);
  85. //填入IP包长度
  86. *(unsigned short *)(ICMPBuf+16)=htons(sizeof(ICMPBuf)-14);
  87. //IP包头校验
  88. *(unsigned short *)(ICMPBuf+24)=in_cksum(ICMPBuf+14,20);//htons(in_cksum(ICMPBuf+14,20));
  89. //ICMP部分校验
  90. unsigned short icmplen=sizeof(ICMPBuf)-34;
  91. *(unsigned short *)(ICMPBuf+36)=in_cksum(ICMPBuf+34,sizeof(ICMPBuf)-34);//htons(in_cksum(ICMPBuf+34,sizeof(ICMPBuf)-34));
  92. int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  93. struct sockaddr_ll mysocket;
  94. struct ifreq ethreq;
  95. strcpy(ethreq.ifr_ifrn.ifrn_name, "eth0");
  96. ioctl(myfd, SIOCGIFINDEX, &ethreq);
  97. memset(&mysocket, 0, sizeof(mysocket));
  98. mysocket.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue; //网卡信息的首地址
  99. pthread_t thread;
  100. pthread_create(&thread, NULL, myfun,(void *)myfd);
  101. pthread_detach(thread);
  102. printf("myfd=%d\n", myfd);
  103. int var = sendto(myfd, ICMPBuf, sizeof(ICMPBuf), 0, (struct sockaddr *)&mysocket, sizeof(mysocket));
  104. sleep(2);
  105. close(myfd);
  106. }

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

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

  1. #include <stdio.h>
  2. #include <sys/types.h> /* See NOTES */
  3. #include <sys/socket.h>
  4. #include <linux/if_packet.h>
  5. #include <linux/if_ether.h>
  6. #include <string.h>
  7. #include <net/if.h>
  8. #include <sys/ioctl.h>
  9. #include <pthread.h>
  10. unsigned char ArpBuf[] =
  11. {
  12. 0xFF, 0XFF, 0XFF, 0XFF, 0xFF, 0XFF, //目标MAC,广播
  13. 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //源MAC,当前主机ARP请求包发出网卡的MAC
  14. 0x08, 0x06, // ARP包
  15. 0x00, 0x01, //以太网类型
  16. 0x08, 0x00, // IPv4
  17. 0x06, //硬件地址MAC 为6个字节
  18. 0x04, //网络地址 IP 为4个字节
  19. 0x00, 0x01, // arp 请求
  20. 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //发送方MAC
  21. 0xc0, 0xa8, 0x01, 0x0b, //发送方IP 192.168.1.11
  22. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //目标MAC
  23. 192, 168, 1, 0};//最后一个字节待定
  24. void *myfun(void *arg)
  25. {
  26. int sockfd = (int)arg;
  27. unsigned char recvbuf[100] = {0};
  28. while (1)
  29. {
  30. int recvlen = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
  31. if ((recvbuf[12] == 0x08) && (recvbuf[13] == 0x06))
  32. {//ARP 包
  33. if ((recvbuf[20] == 0x00) && (recvbuf[21] == 0x02))
  34. {//ARP 回应
  35. printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x===>",
  36. recvbuf[22], recvbuf[23], recvbuf[24], recvbuf[25], recvbuf[26], recvbuf[27]);
  37. printf("IP: %d.%d.%d.%d\n",\
  38. recvbuf[28], recvbuf[29], recvbuf[30], recvbuf[31]);
  39. }
  40. }
  41. // printf("recvlen=%d\n", recvlen);
  42. }
  43. retursn NULL;
  44. }
  45. int main()
  46. {
  47. int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));//创建一个原始套接字
  48. struct sockaddr_ll mysocket;
  49. struct ifreq ethreq;
  50. strcpy(ethreq.ifr_ifrn.ifrn_name, "eth0");//设置属性,等下sendto就从 eth0网卡发送出去数据包
  51. ioctl(myfd, SIOCGIFINDEX, &ethreq);
  52. memset(&mysocket, 0, sizeof(mysocket));
  53. mysocket.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue; //网卡信息的首地址
  54. pthread_t thread;
  55. pthread_create(&thread, NULL, myfun,(void *)myfd);
  56. pthread_detach(thread);
  57. printf("myfd=%d\n", myfd);
  58. int cnt=1;
  59. while(cnt < 255)
  60. {
  61. ArpBuf[41]=cnt;
  62. int var = sendto(myfd, ArpBuf, sizeof(ArpBuf), 0, (struct sockaddr *)&mysocket, sizeof(mysocket));
  63. cnt++;
  64. }
  65. sleep(2);
  66. close(myfd);
  67. }

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

  1. //使用原始套接字,拿到当前局域网内,所有主机的IP和MAC
  2. // #include <stdio.h>
  3. // #include <sys/types.h> /* See NOTES */
  4. // #include <sys/socket.h>
  5. // #include <linux/if_ether.h> //ETH_P_ALL
  6. // #include <net/if.h>
  7. // #include <sys/ioctl.h>
  8. // #include <linux/if_packet.h> //struct sockaddr_ll
  9. // #include<string.h>
  10. // #include<stdlib.h>
  11. #include <stdio.h>
  12. #include <sys/types.h> /* See NOTES */
  13. #include <sys/socket.h>
  14. #include <linux/if_packet.h>
  15. #include <linux/if_ether.h>
  16. #include <string.h>
  17. #include <net/if.h>
  18. #include <sys/ioctl.h>
  19. // unsigned char ArpBuf[] = {
  20. // 0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, //目标MAC,ARP广播地址
  21. // 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //源MAC,虚拟机ubuntu的MAC
  22. // 0x08, 0x06, //是ARP包
  23. // 0x00, 0x01, //是以太网类型帧
  24. // 0x08, 0x00, //是IPV4协议
  25. // 0x06, //硬件地址MAC是6个字节
  26. // 0x04, //网络地址IP是4个字节
  27. // 0x00, 0x01, //这是一个ARP请求包
  28. // 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //源MAC
  29. // 192, 168, 1, 11, //源IP
  30. // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  31. // 192, 168, 1, 1 //目标的IP
  32. // }; //其实一个ARP包是48个字节
  33. // // 17 9 7 8 1
  34. unsigned char ArpBuf[] =
  35. {
  36. 0xFF, 0XFF, 0XFF, 0XFF, 0xFF, 0XFF, //目标MAC
  37. 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //源MAC
  38. 0x08, 0x06, // ARP包
  39. 0x00, 0x01, //以太网类型
  40. 0x08, 0x00, // IPv4
  41. 0x06, //硬件地址MAC 为6个字节
  42. 0x04, //网络地址 IP 为4个字节
  43. 0x00, 0x01, // arp 请求
  44. 0x00, 0x0c, 0x29, 0x5b, 0xe5, 0x7c, //发送方MAC
  45. 0xc0, 0xa8, 0x01, 0x0b, //发送方IP 192.168.1.11
  46. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //目标MAC
  47. // 0xc0,0xa8,0x01,0x09 //目标IP
  48. 192, 168, 1, 1};
  49. int main()
  50. {
  51. // 192.168.1.0 组网,主机IP 192.168.1.1~192.168.1.254
  52. //手动构造192.168.1.1~192.168.1.254 的ARP请求包,在子网发送,拿到所有的
  53. // ARP回应包。回应包 IP和MAC提取出来打印出来。
  54. //经过扫描就可以拿到当前局域里所有的主机IP和MAC
  55. //创建原始套接字,补充协议需要主机字节序转网络字节序
  56. // int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  57. // //指定从哪一个网卡发送出去?
  58. // //要获取一个个网卡 eth0
  59. // struct ifreq myeth;
  60. // memset(&myeth,0,sizeof(myeth));
  61. // strcpy(myeth.ifr_ifrn.ifrn_name, "eth0"); //填入网卡名字
  62. // ioctl(myfd, SIOCGIFINDEX, &myeth); //获取网卡名为 eth0的信息,并填入到myeth
  63. // struct sockaddr_ll sll;
  64. // bzero(&sll,sizeof(sll));
  65. // sll.sll_ifindex = myeth.ifr_ifru.ifru_ivalue; //网卡信息的首地址
  66. // int ret = sendto(myfd, ArpBuf, sizeof(ArpBuf), 0, (struct sockaddr *)&sll, sizeof(struct sockaddr)); //把ARP封包发送出去
  67. int myfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  68. struct sockaddr_ll mysocket;
  69. struct ifreq ethreq;
  70. // IFNAMSIZ
  71. // # define ifr_name ifr_ifrn.ifrn_name
  72. // strcpy(ethreq.ifr_name,"eth0");仅仅是一个宏定义
  73. strcpy(ethreq.ifr_ifrn.ifrn_name, "eth0");
  74. ioctl(myfd, SIOCGIFINDEX, &ethreq);
  75. memset(&mysocket, 0, sizeof(mysocket));
  76. mysocket.sll_ifindex = ethreq.ifr_ifru.ifru_ivalue; //网卡信息的首地址
  77. int var = sendto(myfd, ArpBuf, sizeof(ArpBuf), 0, (struct sockaddr *)&mysocket, sizeof(mysocket));
  78. printf("myfd=%d,ret=%d\n", myfd, var);
  79. unsigned char recvbuf[100] = {0};
  80. int recvlen = recvfrom(myfd, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
  81. printf("recvlen=%d\n", recvlen);
  82. int i = 0;
  83. recvlen = 42;
  84. while (i < recvlen)
  85. {
  86. if ((i % 10 == 0) && (i != 0))
  87. { //一行如果有10个字节,就换行打印
  88. printf("\n");
  89. }
  90. printf("%x ", recvbuf[i]);
  91. i++;
  92. }
  93. if ((recvbuf[12] == 0x08) && (recvbuf[13] == 0x06))
  94. {
  95. printf("这是ARP包!!\n");
  96. if ((recvbuf[20] == 0x00) && (recvbuf[21] == 0x02))
  97. {
  98. printf("这是回应包!!\n");
  99. printf("网关的MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",\
  100. recvbuf[6], recvbuf[7], recvbuf[8], recvbuf[9], recvbuf[10], recvbuf[11]);
  101. }
  102. }
  103. close(myfd);
  104. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/332650
推荐阅读
相关标签
  

闽ICP备14008679号