openchannel.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. /*====================================================================*
  9. *
  10. * signed openchannel (struct channel * channel);
  11. *
  12. * channel.h
  13. *
  14. * open a raw ethernet channel;
  15. *
  16. * Contributor(s):
  17. * Charles Maier <cmaier@qca.qualcomm.com>
  18. * Nathaniel Houghton <nhoughto@qca.qualcomm.com>
  19. *
  20. *--------------------------------------------------------------------*/
  21. #ifndef OPENCHANNEL_SOURCE
  22. #define OPENCHANNEL_SOURCE
  23. #include <unistd.h>
  24. #include <memory.h>
  25. #include <errno.h>
  26. #if defined (__linux__)
  27. # include <net/if_arp.h>
  28. # include <netpacket/packet.h>
  29. # include <sys/ioctl.h>
  30. #elif defined (__APPLE__)
  31. # include <sys/ioctl.h>
  32. # include <sys/stat.h>
  33. # include <fcntl.h>
  34. # include <stdlib.h>
  35. #elif defined (__OpenBSD__)
  36. # include <sys/ioctl.h>
  37. # include <sys/stat.h>
  38. # include <sys/types.h>
  39. # include <fcntl.h>
  40. # include <stdlib.h>
  41. #elif defined (WINPCAP)
  42. # include <string.h>
  43. #else
  44. #error "Unknown environment"
  45. #endif
  46. #include "../ether/channel.h"
  47. #include "../tools/memory.h"
  48. #include "../tools/flags.h"
  49. #include "../tools/error.h"
  50. #if defined (__APPLE__) || defined (__OpenBSD__)
  51. # include "../ether/gethwaddr.c"
  52. #endif
  53. signed openchannel (struct channel * channel)
  54. {
  55. #if defined (__linux__)
  56. struct ifreq ifreq;
  57. struct sockaddr_ll sockaddr_ll =
  58. {
  59. PF_PACKET,
  60. 0x0000,
  61. 0x0000,
  62. ARPHRD_ETHER,
  63. PACKET_HOST,
  64. ETHER_ADDR_LEN,
  65. {
  66. 0x00,
  67. 0x00,
  68. 0x00,
  69. 0x00,
  70. 0x00,
  71. 0x00,
  72. 0x00,
  73. 0x00
  74. }
  75. };
  76. /*
  77. * raw packets require root privileges on linux; one does not have to be
  78. * root when this program is installed setuid using 'chown root:root' and
  79. * 'chmod 4555';
  80. */
  81. if (geteuid ())
  82. {
  83. error (1, EPERM, ERROR_NOTROOT);
  84. }
  85. memset (& ifreq, 0, sizeof (ifreq));
  86. sockaddr_ll.sll_protocol = htons (channel->type);
  87. if ((channel->fd = socket (sockaddr_ll.sll_family, SOCK_RAW, sockaddr_ll.sll_protocol)) == - 1)
  88. {
  89. error (1, errno, "%s", channel->ifname);
  90. }
  91. memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name));
  92. if (ioctl (channel->fd, SIOCGIFINDEX, & ifreq) == - 1)
  93. {
  94. error (1, errno, "%s", ifreq.ifr_name);
  95. }
  96. channel->ifindex = sockaddr_ll.sll_ifindex = ifreq.ifr_ifindex;
  97. if (ioctl (channel->fd, SIOCGIFHWADDR, & ifreq) == - 1)
  98. {
  99. error (1, errno, "%s", ifreq.ifr_name);
  100. }
  101. memcpy (sockaddr_ll.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr_ll.sll_addr));
  102. if (bind (channel->fd, (struct sockaddr *) (& sockaddr_ll), sizeof (sockaddr_ll)) == - 1)
  103. {
  104. error (1, errno, "%s", ifreq.ifr_name);
  105. }
  106. memcpy (channel->host, sockaddr_ll.sll_addr, sizeof (channel->host));
  107. if (ioctl (channel->fd, SIOCGIFFLAGS, & ifreq) == - 1)
  108. {
  109. error (1, errno, "%s", ifreq.ifr_name);
  110. }
  111. channel->ifstate = ifreq.ifr_flags;
  112. _setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST | IFF_MULTICAST));
  113. _clrbits (ifreq.ifr_flags, (IFF_ALLMULTI | IFF_PROMISC));
  114. if (ioctl (channel->fd, SIOCSIFFLAGS, & ifreq) == - 1)
  115. {
  116. error (1, errno, "%s", ifreq.ifr_name);
  117. }
  118. #else
  119. struct bpf_program bpf_program;
  120. static struct bpf_insn bpf_insn [] =
  121. {
  122. {
  123. BPF_LD + BPF_H + BPF_ABS,
  124. 0,
  125. 0,
  126. 12
  127. },
  128. {
  129. BPF_JMP + BPF_JEQ + BPF_K,
  130. 0,
  131. 18,
  132. 0
  133. },
  134. {
  135. BPF_LD + BPF_B + BPF_ABS,
  136. 0,
  137. 0,
  138. 0
  139. },
  140. {
  141. BPF_JMP + BPF_JEQ + BPF_K,
  142. 0,
  143. 10,
  144. 0
  145. },
  146. {
  147. BPF_LD + BPF_B + BPF_ABS,
  148. 0,
  149. 0,
  150. 1
  151. },
  152. {
  153. BPF_JMP + BPF_JEQ + BPF_K,
  154. 0,
  155. 8,
  156. 0
  157. },
  158. {
  159. BPF_LD + BPF_B + BPF_ABS,
  160. 0,
  161. 0,
  162. 2
  163. },
  164. {
  165. BPF_JMP + BPF_JEQ + BPF_K,
  166. 0,
  167. 6,
  168. 0
  169. },
  170. {
  171. BPF_LD + BPF_B + BPF_ABS,
  172. 0,
  173. 0,
  174. 3
  175. },
  176. {
  177. BPF_JMP + BPF_JEQ + BPF_K,
  178. 0,
  179. 4,
  180. 0
  181. },
  182. {
  183. BPF_LD + BPF_B + BPF_ABS,
  184. 0,
  185. 0,
  186. 4
  187. },
  188. {
  189. BPF_JMP + BPF_JEQ + BPF_K,
  190. 0,
  191. 2,
  192. 0
  193. },
  194. {
  195. BPF_LD + BPF_B + BPF_ABS,
  196. 0,
  197. 0,
  198. 5
  199. },
  200. {
  201. BPF_JMP + BPF_JEQ + BPF_K,
  202. 4,
  203. 0,
  204. 0
  205. },
  206. {
  207. BPF_LD + BPF_W + BPF_ABS,
  208. 0,
  209. 0,
  210. 0
  211. },
  212. {
  213. BPF_JMP + BPF_JEQ + BPF_K,
  214. 0,
  215. 4,
  216. 0xFFFFFFFF
  217. },
  218. {
  219. BPF_LD + BPF_H + BPF_ABS,
  220. 0,
  221. 0,
  222. 4
  223. },
  224. {
  225. BPF_JMP + BPF_JEQ + BPF_K,
  226. 0,
  227. 2,
  228. 0xFFFF
  229. },
  230. {
  231. BPF_LD + BPF_W + BPF_LEN,
  232. 0,
  233. 0,
  234. 0
  235. },
  236. {
  237. BPF_RET + BPF_A,
  238. 0,
  239. 0,
  240. 0
  241. },
  242. {
  243. BPF_RET + BPF_K,
  244. 0,
  245. 0,
  246. 0
  247. }
  248. };
  249. #if defined (__APPLE__) || defined (__OpenBSD__)
  250. struct ifreq ifreq;
  251. struct timeval timeval;
  252. struct bpf * bpf;
  253. char filename [sizeof (CHANNEL_BPFDEVICE) + 1];
  254. unsigned count;
  255. unsigned state;
  256. int stat_errno = 0;
  257. int open_errno = 0;
  258. for (count = 0; count < 100; count++)
  259. {
  260. struct stat st;
  261. snprintf (filename, sizeof (filename), CHANNEL_BPFDEVICE, count);
  262. if (stat (filename, & st) == - 1)
  263. {
  264. stat_errno = errno;
  265. continue;
  266. }
  267. if ((channel->fd = open (filename, O_RDWR)) != - 1)
  268. {
  269. break;
  270. }
  271. else
  272. {
  273. open_errno = errno;
  274. }
  275. }
  276. if (channel->fd == - 1)
  277. {
  278. if (open_errno)
  279. {
  280. error (1, open_errno, "Could not open bpf device");
  281. }
  282. else
  283. {
  284. error (1, stat_errno, "No bpf device found");
  285. }
  286. }
  287. memcpy (ifreq.ifr_name, channel->ifname, sizeof (ifreq.ifr_name));
  288. if (ioctl (channel->fd, BIOCSETIF, & ifreq) == - 1)
  289. {
  290. error (1, errno, "%s", ifreq.ifr_name);
  291. }
  292. channel->bpf = bpf = malloc (sizeof (* bpf));
  293. if (ioctl (channel->fd, BIOCGBLEN, & bpf->bpf_length) == - 1)
  294. {
  295. error (1, errno, "Can't determine buffer length: %s", ifreq.ifr_name);
  296. }
  297. bpf->bpf_bp = bpf->bpf_buffer = malloc (bpf->bpf_length);
  298. if (bpf->bpf_buffer == NULL)
  299. {
  300. error (1, errno, "Can't allocate receive buffer");
  301. }
  302. #if defined (__APPLE__)
  303. state = 0;
  304. if (ioctl (channel->fd, BIOCSSEESENT, & state) == - 1)
  305. {
  306. error (1, errno, "Can't hide outgoing frames: %s", ifreq.ifr_name);
  307. }
  308. #elif defined (__OpenBSD__)
  309. state = BPF_DIRECTION_OUT;
  310. if (ioctl (channel->fd, BIOCSDIRFILT, & state) == - 1)
  311. {
  312. error (0, errno, "Can't hide outgoing frames");
  313. }
  314. #else
  315. #error "Abandon all hope"
  316. #endif
  317. if (channel->capture > 1000)
  318. {
  319. timeval.tv_sec = channel->capture / 1000;
  320. timeval.tv_usec = 0;
  321. }
  322. else
  323. {
  324. #if defined (__MAC_10_6)
  325. /*
  326. * accommodate known bug in BPF on MAC OS X 10.6; shorter times cause socket read
  327. * operations to block indefinitely if no frames are waiting because tv_usec gets
  328. * clobbered;
  329. */
  330. timeval.tv_sec = 1;
  331. timeval.tv_usec = 0;
  332. #else
  333. timeval.tv_sec = 0;
  334. timeval.tv_usec = channel->capture * 1000;
  335. #endif
  336. }
  337. if (ioctl (channel->fd, BIOCSRTIMEOUT, & timeval) == - 1)
  338. {
  339. error (1, errno, "Can't set channel capture: %s", ifreq.ifr_name);
  340. }
  341. state = 1;
  342. if (ioctl (channel->fd, BIOCIMMEDIATE, & state) == - 1)
  343. {
  344. error (1, errno, "Can't set immediate mode: %s", ifreq.ifr_name);
  345. }
  346. #if 1
  347. state = 1;
  348. if (ioctl (channel->fd, BIOCSHDRCMPLT, & state) == - 1)
  349. {
  350. error (1, errno, "Can't set header complete mode: %s", ifreq.ifr_name);
  351. }
  352. #endif
  353. #if 1
  354. gethwaddr (channel->host, channel->ifname);
  355. #else
  356. if (ioctl (channel->fd, SIOCGIFADDR, & ifreq) > 0)
  357. {
  358. error (1, errno, "%s", ifreq.ifr_name);
  359. }
  360. memcpy (channel->host, LLADDR (ifreq.ifr_ifru.ifru_addr), sizeof (channel->host));
  361. #endif
  362. bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn);
  363. bpf_program.bf_insns = bpf_insn;
  364. if (channel->type == ETH_P_802_2)
  365. {
  366. bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
  367. bpf_insn [1].jt = 18;
  368. bpf_insn [1].jf = 0;
  369. bpf_insn [1].k = ETHERMTU;
  370. }
  371. else
  372. {
  373. bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
  374. bpf_insn [1].jt = 0;
  375. bpf_insn [1].jf = 18;
  376. bpf_insn [1].k = channel->type;
  377. }
  378. bpf_insn [3].k = channel->host [0];
  379. bpf_insn [5].k = channel->host [1];
  380. bpf_insn [7].k = channel->host [2];
  381. bpf_insn [9].k = channel->host [3];
  382. bpf_insn [11].k = channel->host [4];
  383. bpf_insn [13].k = channel->host [5];
  384. if (ioctl (channel->fd, BIOCSETF, & bpf_program) == - 1)
  385. {
  386. error (1, errno, "Can't store filter: %s", channel->ifname);
  387. }
  388. #elif defined (WINPCAP) || defined (LIBPCAP)
  389. channel->ifname = getifname (channel->ifindex);
  390. gethwaddr (channel->host, channel->ifname);
  391. channel->socket = pcap_open_live (channel->ifname, 65536, 0, channel->capture, channel->errbuf);
  392. snprintf ((char *) (channel->ifname), strlen (channel->ifname), "nic%d", channel->ifindex);
  393. if (! channel->socket)
  394. {
  395. error (1, errno, "Can't open interface: %s", channel->ifname);
  396. }
  397. bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn);
  398. bpf_program.bf_insns = bpf_insn;
  399. if (channel->type == ETH_P_802_2)
  400. {
  401. bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
  402. bpf_insn [1].jt = 18;
  403. bpf_insn [1].jf = 0;
  404. bpf_insn [1].k = ETHERMTU;
  405. }
  406. else
  407. {
  408. bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
  409. bpf_insn [1].jt = 0;
  410. bpf_insn [1].jf = 18;
  411. bpf_insn [1].k = channel->type;
  412. }
  413. bpf_insn [3].k = channel->host [0];
  414. bpf_insn [5].k = channel->host [1];
  415. bpf_insn [7].k = channel->host [2];
  416. bpf_insn [9].k = channel->host [3];
  417. bpf_insn [11].k = channel->host [4];
  418. bpf_insn [13].k = channel->host [5];
  419. if (pcap_setfilter (channel->socket, & bpf_program) < 0)
  420. {
  421. error (1, errno, "Can't store filter: %s", channel->ifname);
  422. }
  423. if (pcap_setmintocopy (channel->socket, ETHER_MIN_LEN) < 0)
  424. {
  425. error (1, errno, "Can't set pcap mintocopy: %s", channel->ifname);
  426. }
  427. #else
  428. #error "Unknown Environment"
  429. #endif
  430. #endif
  431. return (0);
  432. }
  433. #endif