Advertisement
Guest User

Untitled

a guest
Jun 30th, 2015
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.73 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <ifaddrs.h>
  8. #include <sys/types.h>
  9. #include <sys/time.h>
  10. #include <sys/ioctl.h>
  11. #include <sys/uio.h>
  12. #include <net/bpf.h>
  13. #include <net/if.h>
  14. #include <net/if_dl.h>
  15. #include <net/if_arp.h>
  16. #include <net/ethernet.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19.  
  20. int openBpf(void);
  21. void closeBpf(int fd);
  22. int setupBpf(int fd, const char *ifname);
  23.  
  24. void makeEther(struct ether_header* ether);
  25. void makeArp(const u_char* restrict srcHardwareAddress,
  26. const in_addr_t* srcProtocolAddress,
  27. const in_addr_t* dstProtocolAddress,
  28. struct arphdr* restrict arp);
  29.  
  30. static int
  31. getAddress(const char* restrict ifname,
  32. u_char* restrict hardwareAddress, in_addr_t* restrict protocolAddress);
  33.  
  34. int
  35. openBpf(void)
  36. {
  37. return open("/dev/bpf", O_RDWR);
  38. }
  39.  
  40.  
  41. void
  42. closeBpf(int fd)
  43. {
  44. close(fd);
  45. }
  46.  
  47.  
  48. int
  49. setupBpf(int fd, const char *ifname)
  50. {
  51. struct ifreq request;
  52. u_int tstamp;
  53. u_int type;
  54.  
  55. strlcpy(request.ifr_name, ifname, sizeof(request.ifr_name) - 1);
  56. if (ioctl(fd, BIOCSETIF, &request) < 0) {
  57. perror("BIOCSETIF failed: ");
  58. return -1;
  59. }
  60.  
  61. if (ioctl(fd, BIOCGDLT, &type) < 0) {
  62. perror("BIOCGDLT failed: ");
  63. return -1;
  64. }
  65. if (type != DLT_EN10MB) {
  66. printf("unsupported datalink type\n");
  67. return -1;
  68. }
  69.  
  70. tstamp = BPF_T_NANOTIME;
  71. if (ioctl(fd, BIOCSTSTAMP, &tstamp) < 0) {
  72. perror("BIOCSTSTAMP faild: ");
  73. return -1;
  74. }
  75.  
  76. return 0;
  77. }
  78.  
  79.  
  80. static int
  81. getAddress(const char* restrict ifname,
  82. u_char* restrict hardwareAddress, in_addr_t* restrict protocolAddress)
  83. {
  84. struct ifaddrs *addrList, *addr;
  85. struct sockaddr_dl *dlAddr = NULL;
  86. struct sockaddr_in *srcAddr = NULL;
  87. int ret = 0;
  88.  
  89. if (getifaddrs(&addrList) < 0) {
  90. return -1;
  91. }
  92. addr = addrList;
  93. while (addr && (!dlAddr || !srcAddr)) {
  94. if (addr->ifa_addr->sa_family == AF_LINK) {
  95. if (strcmp(ifname, addr->ifa_name) == 0) {
  96. dlAddr = (struct sockaddr_dl*)addr->ifa_addr;
  97. }
  98. }
  99. else if (addr->ifa_addr->sa_family == AF_INET) {
  100. if (strcmp(ifname, addr->ifa_name) == 0) {
  101. srcAddr = (struct sockaddr_in*)addr->ifa_addr;
  102. }
  103. }
  104. addr = addr->ifa_next;
  105. }
  106.  
  107. if (dlAddr && srcAddr) {
  108. memcpy(hardwareAddress, LLADDR(dlAddr), dlAddr->sdl_alen);
  109. memcpy(protocolAddress, &srcAddr->sin_addr, sizeof(in_addr_t));
  110. } else {
  111. printf("cannot find link layer address for %s", ifname);
  112. ret = -1;
  113. }
  114.  
  115. freeifaddrs(addrList);
  116.  
  117. return ret;
  118. }
  119.  
  120.  
  121. void
  122. makeEther(struct ether_header* ether)
  123. {
  124. static const u_char etherBroadcast[ETHER_ADDR_LEN] = {
  125. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  126. };
  127.  
  128. memset(&ether->ether_shost, 0, ETHER_ADDR_LEN);
  129. memcpy(&ether->ether_dhost, etherBroadcast, ETHER_ADDR_LEN);
  130. ether->ether_type = htons(ETHERTYPE_ARP);
  131. }
  132.  
  133.  
  134. void
  135. makeArp(const u_char* restrict srcHardwareAddress,
  136. const in_addr_t* srcProtocolAddress,
  137. const in_addr_t* dstProtocolAddress,
  138. struct arphdr* restrict arp)
  139. {
  140. arp->ar_hrd = htons(ARPHRD_ETHER);
  141. arp->ar_pro = htons(ETHERTYPE_IP);
  142. arp->ar_hln = ETHER_ADDR_LEN;
  143. arp->ar_pln = sizeof(in_addr_t);
  144. arp->ar_op = htons(ARPOP_REQUEST);
  145. memcpy(ar_sha(arp), srcHardwareAddress, ETHER_ADDR_LEN);
  146. memcpy(ar_spa(arp), srcProtocolAddress, sizeof(in_addr_t));
  147. memset(ar_tha(arp), 0, ETHER_ADDR_LEN);
  148. memcpy(ar_tpa(arp), dstProtocolAddress, sizeof(in_addr_t));
  149. }
  150.  
  151.  
  152. int
  153. main(int argc, char **argv)
  154. {
  155. struct ether_header ether;
  156. u_char srcHardwareAddress[ETHER_ADDR_LEN];
  157. in_addr_t srcProtocolAddress;
  158. struct in_addr dstProtocolAddress;
  159. int fdBpf = -1;
  160. u_char arp[sizeof(struct arphdr) +
  161. 2 * (ETHER_ADDR_LEN + sizeof(in_addr_t))];
  162.  
  163. if (argc != 3) {
  164. printf("usage: %s <interface> <target address>\n", argv[0]);
  165. return 1;
  166. }
  167.  
  168. if ((fdBpf = openBpf()) < 0) {
  169. printf("BPF cannot be opened.\n");
  170. return 1;
  171. }
  172.  
  173. if (setupBpf(fdBpf, argv[1]) < 0) {
  174. close(fdBpf);
  175. return 1;
  176. }
  177.  
  178. getAddress(argv[1], srcHardwareAddress, &srcProtocolAddress);
  179. inet_pton(AF_INET, argv[2], &dstProtocolAddress);
  180.  
  181. makeEther(&ether);
  182. makeArp(srcHardwareAddress, &srcProtocolAddress, &dstProtocolAddress.s_addr,
  183. (struct arphdr*)arp);
  184.  
  185. /* write packet */
  186. {
  187. struct iovec writeVec[2];
  188.  
  189. writeVec[0].iov_base = &ether;
  190. writeVec[0].iov_len = sizeof(ether);
  191. writeVec[1].iov_base = arp;
  192. writeVec[1].iov_len = sizeof(arp);
  193. writev(fdBpf, writeVec, 2);
  194. }
  195.  
  196. closeBpf(fdBpf);
  197. return 0;
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement