linux raw sock发送RS报文
来源:互联网 发布:不会算法的程序员 编辑:程序博客网 时间:2024/06/15 09:51
旨在解决内核不主动发IPV6的router solicit报文问题,手动发
1./*2. * use special interface to send ipv6 router solicit packet3. * leon, 2017-6-28 15:22:114. */5.6.#include <stdio.h>7.#include <string.h>8.#include <stdlib.h>9.#include <unistd.h>10.#include <sys/types.h>11.#include <sys/socket.h>12.#include <fcntl.h>13.#include <sys/ioctl.h>14.15.#include <netdb.h> /* getaddrinfo() */16.#include <arpa/inet.h> /* inet_ntop() */17.#include <net/if.h> /* if_nametoindex() */18.19.#include <netinet/in.h>20.#include <netdb.h>21.#include "ifaddrs.h"22.#include <netinet/icmp6.h>23.24.typedef struct25.{26. struct nd_router_solicit hdr;27. struct nd_opt_hdr opt;28. uint8_t hw_addr[6];29.} solicit_packet;30.31.static int get_mac_address(const char *ifname, uint8_t *addr)32.{33. struct ifreq req;34. memset(&req, 0, sizeof (req));35.36. if(((unsigned)strlen(ifname)) >= (unsigned)IFNAMSIZ)37. return -1; /* buffer overflow = local root */38. strcpy(req.ifr_name, ifname);39.40. int fd = socket(AF_INET6, SOCK_DGRAM, 0);41. if (fd == -1)42. return -1;43.44. if (ioctl(fd, SIOCGIFHWADDR, &req))45. {46. perror(ifname);47. close(fd);48. return -1;49. }50. close(fd);51.52. memcpy(addr, req.ifr_hwaddr.sa_data, 6);53.54. /* ppp interface maybe get zero mac address */55. uint8_t zero_mac[6] = {0};56. if(!memcmp(addr, zero_mac, sizeof(zero_mac)))57. return -1;58.59. return 0;60.}61.62.63.int get_if_link_local_addr6(char *ifname, struct sockaddr_in6 *addr6)64.{ 65. struct ifaddrs *ifaddr, *ifa; 66. char ip_str[64];67. struct in6_addr *tmp;68. int ok = 0;69.70. if(!ifname || !addr6)71. return 0;72.73. if (-1 == getifaddrs(&ifaddr))74. {75. perror("getifaddrs");76. return; 77. }78.79. for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) 80. { 81. if(ifa->ifa_name && !strcmp(ifa->ifa_name, ifname) && 82. ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6)83. { 84. tmp = &((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr;85. if(IN6_IS_ADDR_LINKLOCAL(tmp))86. {87. memcpy(addr6, ifa->ifa_addr, sizeof(struct sockaddr_in6)); 88. ok = 1;89. //inet_ntop(AF_INET6, tmp, ip_str, sizeof(ip_str));90. //printf("%s\n", ip_str);91. }92. }93. } 94. freeifaddrs(ifaddr); 95. if(!ok)96. {97. printf("Not find the interface(%s) address\n", ifname);98. return -1;99. } 100. return 0;101.}102.103.104.ssize_t build_rs(solicit_packet *rs, const char *ifname)105.{106. /* builds ICMPv6 Router Solicitation packet */107. rs->hdr.nd_rs_type = ND_ROUTER_SOLICIT;108. rs->hdr.nd_rs_code = 0;109. rs->hdr.nd_rs_cksum = 0; /* computed by the kernel */110. rs->hdr.nd_rs_reserved = 0;111.112. /* gets our own interface's link-layer address (MAC) */113. if (get_mac_address(ifname, rs->hw_addr))114. return sizeof(rs->hdr);115.116. rs->opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR;117. rs->opt.nd_opt_len = 1; /* 8 bytes */118.119. return sizeof(*rs);120.}121.122.int main(int argc, char *argv[])123.{124. int s = -1;125. struct sockaddr_in6 src;126. solicit_packet packet;127. struct sockaddr_in6 dst;128. char *ifname = NULL;129. ssize_t plen;130.131. if(argc < 2)132. {133. printf("usage: %s [ifname]\n", argv[0]);134. return -1;135. }136. ifname = argv[1];137.138. s = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);139. if(-1 == s)140. {141. perror("socket create");142. return -1;143. }144.145. get_if_link_local_addr6(ifname, &src);146. if(-1 == bind(s, (struct sockaddr *)&src, sizeof(src)))147. {148. perror("bind");149. close(s);150. return -1;151. }152.153. memcpy(&dst, &src, sizeof (dst)); /* copy some address info */154. memcpy(dst.sin6_addr.s6_addr, "\xff\x02\x00\x00\x00\x00\x00\x00"155. "\x00\x00\x00\x00\x00\x00\x00\x02", 16);156.157. plen = build_rs(&packet, ifname);158. if (sendto(s, &packet, plen, 0, (const struct sockaddr *)&dst, sizeof(dst)) != plen)159. {160. perror("Sending ICMPv6 packet");161. close(s);162. return -1;163. }164.165. return 0;166.}
ubuntu 15.04下测试OK
ARM交叉编译时,提示没有ifaddrs.h文件,需要自己添加ifaddrs.c和ifaddrs.h,然后一起编译,测试OK。
阅读全文
0 0
- linux raw sock发送RS报文
- linux内核不发(Router Solicit)RS报文问题
- linux RAW SOCKET加Packet af定制2层报文
- linux网络报文接收发送浅析
- Linux下发送全网广播报文
- linux下发送arp请求报文 代码
- linux网络报文接收发送浅析
- linux网络报文接收发送浅析
- linux socket()调用与arp报文发送
- linux网络报文接收发送浅析
- linux网络报文接收发送浅析
- linux网络报文接收发送浅析
- Linux网络报文接收与发送概述
- linux网络报文接收发送浅析
- linux网络报文接收发送浅析
- linux网络报文接收发送浅析
- [linux]网络报文发送、接收调用链
- linux原始套接字-发送ARP报文
- Minimum Scalar Produnct
- Windows中cmd操作mysql
- 定义与声明
- CentOS-CentOS6.4下修改网卡名称 eth2修改为eth0
- Android Monkey的用法
- linux raw sock发送RS报文
- Android使用Parcelable传递boolean、String、Class、List、Enum类型数据
- 三层架构
- Best Time to Buy and Sell Stock最大收益问题算法详解
- labview学习笔记01_顺序结构不能添加添加Add Sequence Local
- 注解
- WMI 的攻击,防御与取证分析技术之攻击篇 原文出自【比特网】,转载请保留原文链接:http://sec.chinabyte.com/353/13607853.shtml
- 关于mysql分组的探索
- 解决Glide加载图片中Url中有token保护问题.md