openchannel.c.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. <?xml version='1.0' encoding='iso-8859-1'?>
  2. <!doctype html public '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
  3. <html xmlns='http://www.w3c.org/1999/xhtml' lang='en-us'>
  4. <head>
  5. <title>
  6. openchannel.c
  7. </title>
  8. <meta http-equiv='content-type' content='text/html;iso-8859-1'/>
  9. <meta name='generator' content='motley-tools 1.9.4 13:40:33 Feb 18 2015'/>
  10. <meta name='author' content='cmaier@cmassoc.net'/>
  11. <meta name='robots' content='noindex,nofollow'/>
  12. <link href='toolkit.css' rel='stylesheet' type='text/css'/>
  13. </head>
  14. <body>
  15. <div class='headerlink'>
  16. [<a href='nvrampeek.c.html' title=' nvrampeek.c '>PREV</a>]
  17. [<a href='toolkit.html' title=' Index '>HOME</a>]
  18. [<a href='openport.c.html' title=' openport.c '>NEXT</a>]
  19. </div>
  20. <pre>
  21. /*====================================================================*
  22. *
  23. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  24. *
  25. * All rights reserved.
  26. *
  27. * Redistribution and use in source and binary forms, with or
  28. * without modification, are permitted (subject to the limitations
  29. * in the disclaimer below) provided that the following conditions
  30. * are met:
  31. *
  32. * * Redistributions of source code must retain the above copyright
  33. * notice, this list of conditions and the following disclaimer.
  34. *
  35. * * Redistributions in binary form must reproduce the above
  36. * copyright notice, this list of conditions and the following
  37. * disclaimer in the documentation and/or other materials
  38. * provided with the distribution.
  39. *
  40. * * Neither the name of Qualcomm Atheros nor the names of
  41. * its contributors may be used to endorse or promote products
  42. * derived from this software without specific prior written
  43. * permission.
  44. *
  45. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
  46. * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
  47. * COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR
  48. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  50. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  51. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  52. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  53. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  56. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  57. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59. *
  60. *--------------------------------------------------------------------*/
  61. /*====================================================================*
  62. *
  63. * signed openchannel (struct channel * channel);
  64. *
  65. * channel.h
  66. *
  67. * open a raw ethernet channel;
  68. *
  69. *
  70. * Contributor(s):
  71. * Charles Maier &lt;cmaier@qca.qualcomm.com&gt;
  72. * Nathaniel Houghton &lt;nhoughto@qca.qualcomm.com&gt;
  73. *
  74. *--------------------------------------------------------------------*/
  75. #ifndef OPENCHANNEL_SOURCE
  76. #define OPENCHANNEL_SOURCE
  77. #include &lt;unistd.h&gt;
  78. #include &lt;memory.h&gt;
  79. #include &lt;errno.h&gt;
  80. #if defined (__linux__)
  81. # include &lt;net/if_arp.h&gt;
  82. # include &lt;netpacket/packet.h&gt;
  83. # include &lt;sys/ioctl.h&gt;
  84. #elif defined (__APPLE__)
  85. # include &lt;sys/ioctl.h&gt;
  86. # include &lt;sys/stat.h&gt;
  87. # include &lt;fcntl.h&gt;
  88. # include &lt;stdlib.h&gt;
  89. #elif defined (__OpenBSD__)
  90. # include &lt;sys/ioctl.h&gt;
  91. # include &lt;sys/stat.h&gt;
  92. # include &lt;sys/types.h&gt;
  93. # include &lt;fcntl.h&gt;
  94. # include &lt;stdlib.h&gt;
  95. #elif defined (WINPCAP)
  96. # include &lt;string.h&gt;
  97. #else
  98. #error &quot;Unknown environment&quot;
  99. #endif
  100. #include &quot;../ether/channel.h&quot;
  101. #include &quot;../tools/memory.h&quot;
  102. #include &quot;../tools/flags.h&quot;
  103. #include &quot;../tools/error.h&quot;
  104. #if defined (__APPLE__) || defined (__OpenBSD__)
  105. # include &quot;../ether/gethwaddr.c&quot;
  106. #endif
  107. signed openchannel (struct channel * channel)
  108. {
  109. #if defined (__linux__)
  110. struct ifreq ifreq;
  111. struct sockaddr_ll sockaddr_ll =
  112. {
  113. PF_PACKET,
  114. 0x0000,
  115. 0x0000,
  116. ARPHRD_ETHER,
  117. PACKET_HOST,
  118. ETHER_ADDR_LEN,
  119. {
  120. 0x00,
  121. 0x00,
  122. 0x00,
  123. 0x00,
  124. 0x00,
  125. 0x00,
  126. 0x00,
  127. 0x00
  128. }
  129. };
  130. /*
  131. * raw packets require root privileges on linux; one does not have to be
  132. * root when this program is installed setuid using 'chown root:root' and
  133. * 'chmod 4555';
  134. */
  135. if (geteuid ())
  136. {
  137. error (1, EPERM, ERROR_NOTROOT);
  138. }
  139. memset (&amp;ifreq, 0, sizeof (ifreq));
  140. sockaddr_ll.sll_protocol = htons (channel-&gt;type);
  141. if ((channel-&gt;fd = socket (sockaddr_ll.sll_family, SOCK_RAW, sockaddr_ll.sll_protocol)) == -1)
  142. {
  143. error (1, errno, &quot;%s&quot;, channel-&gt;ifname);
  144. }
  145. memcpy (ifreq.ifr_name, channel-&gt;ifname, sizeof (ifreq.ifr_name));
  146. if (ioctl (channel-&gt;fd, SIOCGIFINDEX, &amp;ifreq) == -1)
  147. {
  148. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  149. }
  150. channel-&gt;ifindex = sockaddr_ll.sll_ifindex = ifreq.ifr_ifindex;
  151. if (ioctl (channel-&gt;fd, SIOCGIFHWADDR, &amp;ifreq) == -1)
  152. {
  153. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  154. }
  155. memcpy (sockaddr_ll.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr_ll.sll_addr));
  156. if (bind (channel-&gt;fd, (struct sockaddr *) (&amp;sockaddr_ll), sizeof (sockaddr_ll)) == -1)
  157. {
  158. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  159. }
  160. memcpy (channel-&gt;host, sockaddr_ll.sll_addr, sizeof (channel-&gt;host));
  161. if (ioctl (channel-&gt;fd, SIOCGIFFLAGS, &amp;ifreq) == -1)
  162. {
  163. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  164. }
  165. channel-&gt;ifstate = ifreq.ifr_flags;
  166. _setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST | IFF_MULTICAST));
  167. _clrbits (ifreq.ifr_flags, (IFF_ALLMULTI | IFF_PROMISC));
  168. if (ioctl (channel-&gt;fd, SIOCSIFFLAGS, &amp;ifreq) == -1)
  169. {
  170. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  171. }
  172. #else
  173. struct bpf_program bpf_program;
  174. static struct bpf_insn bpf_insn [] =
  175. {
  176. {
  177. BPF_LD + BPF_H + BPF_ABS,
  178. 0,
  179. 0,
  180. 12
  181. },
  182. {
  183. BPF_JMP + BPF_JEQ + BPF_K,
  184. 0,
  185. 18,
  186. 0
  187. },
  188. {
  189. BPF_LD + BPF_B + BPF_ABS,
  190. 0,
  191. 0,
  192. 0
  193. },
  194. {
  195. BPF_JMP + BPF_JEQ + BPF_K,
  196. 0,
  197. 10,
  198. 0
  199. },
  200. {
  201. BPF_LD + BPF_B + BPF_ABS,
  202. 0,
  203. 0,
  204. 1
  205. },
  206. {
  207. BPF_JMP + BPF_JEQ + BPF_K,
  208. 0,
  209. 8,
  210. 0
  211. },
  212. {
  213. BPF_LD + BPF_B + BPF_ABS,
  214. 0,
  215. 0,
  216. 2
  217. },
  218. {
  219. BPF_JMP + BPF_JEQ + BPF_K,
  220. 0,
  221. 6,
  222. 0
  223. },
  224. {
  225. BPF_LD + BPF_B + BPF_ABS,
  226. 0,
  227. 0,
  228. 3
  229. },
  230. {
  231. BPF_JMP + BPF_JEQ + BPF_K,
  232. 0,
  233. 4,
  234. 0
  235. },
  236. {
  237. BPF_LD + BPF_B + BPF_ABS,
  238. 0,
  239. 0,
  240. 4
  241. },
  242. {
  243. BPF_JMP + BPF_JEQ + BPF_K,
  244. 0,
  245. 2,
  246. 0
  247. },
  248. {
  249. BPF_LD + BPF_B + BPF_ABS,
  250. 0,
  251. 0,
  252. 5
  253. },
  254. {
  255. BPF_JMP + BPF_JEQ + BPF_K,
  256. 4,
  257. 0,
  258. 0
  259. },
  260. {
  261. BPF_LD + BPF_W + BPF_ABS,
  262. 0,
  263. 0,
  264. 0
  265. },
  266. {
  267. BPF_JMP + BPF_JEQ + BPF_K,
  268. 0,
  269. 4,
  270. 0xFFFFFFFF
  271. },
  272. {
  273. BPF_LD + BPF_H + BPF_ABS,
  274. 0,
  275. 0,
  276. 4
  277. },
  278. {
  279. BPF_JMP + BPF_JEQ + BPF_K,
  280. 0,
  281. 2,
  282. 0xFFFF
  283. },
  284. {
  285. BPF_LD + BPF_W + BPF_LEN,
  286. 0,
  287. 0,
  288. 0
  289. },
  290. {
  291. BPF_RET + BPF_A,
  292. 0,
  293. 0,
  294. 0
  295. },
  296. {
  297. BPF_RET + BPF_K,
  298. 0,
  299. 0,
  300. 0
  301. }
  302. };
  303. #if defined (__APPLE__) || defined (__OpenBSD__)
  304. struct ifreq ifreq;
  305. struct timeval timeval;
  306. struct bpf * bpf;
  307. char filename [sizeof (CHANNEL_BPFDEVICE) + 1];
  308. unsigned count;
  309. unsigned state;
  310. int stat_errno = 0;
  311. int open_errno = 0;
  312. for (count = 0; count &lt; 100; count++)
  313. {
  314. struct stat st;
  315. snprintf (filename, sizeof (filename), CHANNEL_BPFDEVICE, count);
  316. if (stat(filename, &amp;st) == -1)
  317. {
  318. stat_errno = errno;
  319. continue;
  320. }
  321. if ((channel-&gt;fd = open (filename, O_RDWR)) != -1)
  322. {
  323. break;
  324. }
  325. else
  326. {
  327. open_errno = errno;
  328. }
  329. }
  330. if (channel-&gt;fd == -1)
  331. {
  332. if (open_errno)
  333. {
  334. error (1, open_errno, &quot;Could not open bpf device&quot;);
  335. }
  336. else
  337. {
  338. error (1, stat_errno, &quot;No bpf device found&quot;);
  339. }
  340. }
  341. memcpy (ifreq.ifr_name, channel-&gt;ifname, sizeof (ifreq.ifr_name));
  342. if (ioctl (channel-&gt;fd, BIOCSETIF, &amp;ifreq) == -1)
  343. {
  344. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  345. }
  346. channel-&gt;bpf = bpf = malloc (sizeof (* bpf));
  347. if (ioctl (channel-&gt;fd, BIOCGBLEN, &amp;bpf-&gt;bpf_length) == -1)
  348. {
  349. error (1, errno, &quot;Can't determine buffer length: %s&quot;, ifreq.ifr_name);
  350. }
  351. bpf-&gt;bpf_bp = bpf-&gt;bpf_buffer = malloc (bpf-&gt;bpf_length);
  352. if (bpf-&gt;bpf_buffer == NULL)
  353. {
  354. error (1, errno, &quot;Can't allocate receive buffer&quot;);
  355. }
  356. #if defined (__APPLE__)
  357. state = 0;
  358. if (ioctl (channel-&gt;fd, BIOCSSEESENT, &amp;state) == -1)
  359. {
  360. error (1, errno, &quot;Can't hide outgoing frames: %s&quot;, ifreq.ifr_name);
  361. }
  362. #elif defined (__OpenBSD__)
  363. state = BPF_DIRECTION_OUT;
  364. if (ioctl (channel-&gt;fd, BIOCSDIRFILT, &amp;state) == -1)
  365. {
  366. error (0, errno, &quot;Can't hide outgoing frames&quot;);
  367. }
  368. #else
  369. #error &quot;Abandon all hope&quot;
  370. #endif
  371. if (channel-&gt;capture &gt; 1000)
  372. {
  373. timeval.tv_sec = channel-&gt;capture / 1000;
  374. timeval.tv_usec = 0;
  375. }
  376. else
  377. {
  378. #if defined (__MAC_10_6)
  379. /*
  380. * accommodate known bug in BPF on MAC OS X 10.6; shorter times cause socket read
  381. * operations to block indefinitely if no frames are waiting because tv_usec gets
  382. * clobbered;
  383. */
  384. timeval.tv_sec = 1;
  385. timeval.tv_usec = 0;
  386. #else
  387. timeval.tv_sec = 0;
  388. timeval.tv_usec = channel-&gt;capture * 1000;
  389. #endif
  390. }
  391. if (ioctl (channel-&gt;fd, BIOCSRTIMEOUT, &amp;timeval) == -1)
  392. {
  393. error (1, errno, &quot;Can't set channel timeout: %s&quot;, ifreq.ifr_name);
  394. }
  395. state = 1;
  396. if (ioctl (channel-&gt;fd, BIOCIMMEDIATE, &amp;state) == -1)
  397. {
  398. error (1, errno, &quot;Can't set immediate mode: %s&quot;, ifreq.ifr_name);
  399. }
  400. #if 1
  401. state = 1;
  402. if (ioctl (channel-&gt;fd, BIOCSHDRCMPLT, &amp;state) == -1)
  403. {
  404. error (1, errno, &quot;Can't set header complete mode: %s&quot;, ifreq.ifr_name);
  405. }
  406. #endif
  407. #if 1
  408. gethwaddr (channel-&gt;host, channel-&gt;ifname);
  409. #else
  410. if (ioctl (channel-&gt;fd, SIOCGIFADDR, &amp;ifreq) &gt; 0)
  411. {
  412. error (1, errno, &quot;%s&quot;, ifreq.ifr_name);
  413. }
  414. memcpy (channel-&gt;host, LLADDR (ifreq.ifr_ifru.ifru_addr), sizeof (channel-&gt;host));
  415. #endif
  416. bpf_program.bf_len = sizeof (bpf_insn) / sizeof (struct bpf_insn);
  417. bpf_program.bf_insns = bpf_insn;
  418. if (channel-&gt;type == ETH_P_802_2)
  419. {
  420. bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
  421. bpf_insn [1].jt = 18;
  422. bpf_insn [1].jf = 0;
  423. bpf_insn [1].k = ETHERMTU;
  424. }
  425. else
  426. {
  427. bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
  428. bpf_insn [1].jt = 0;
  429. bpf_insn [1].jf = 18;
  430. bpf_insn [1].k = channel-&gt;type;
  431. }
  432. bpf_insn [3].k = channel-&gt;host [0];
  433. bpf_insn [5].k = channel-&gt;host [1];
  434. bpf_insn [7].k = channel-&gt;host [2];
  435. bpf_insn [9].k = channel-&gt;host [3];
  436. bpf_insn [11].k = channel-&gt;host [4];
  437. bpf_insn [13].k = channel-&gt;host [5];
  438. if (ioctl (channel-&gt;fd, BIOCSETF, &amp;bpf_program) == -1)
  439. {
  440. error (1, errno, &quot;Can't store filter: %s&quot;, channel-&gt;ifname);
  441. }
  442. #elif defined (WINPCAP) || defined (LIBPCAP)
  443. channel-&gt;ifname = getifname (channel-&gt;ifindex);
  444. gethwaddr (channel-&gt;host, channel-&gt;ifname);
  445. channel-&gt;socket = pcap_open_live (channel-&gt;ifname, 65536, 0, channel-&gt;capture, channel-&gt;errbuf);
  446. snprintf ((char *)(channel-&gt;ifname), strlen (channel-&gt;ifname), &quot;nic%d&quot;, channel-&gt;ifindex);
  447. if (!channel-&gt;socket)
  448. {
  449. error (1, errno, &quot;Can't open interface: %s&quot;, channel-&gt;ifname);
  450. }
  451. bpf_program.bf_len = sizeof (bpf_insn)/sizeof (struct bpf_insn);
  452. bpf_program.bf_insns = bpf_insn;
  453. if (channel-&gt;type == ETH_P_802_2)
  454. {
  455. bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
  456. bpf_insn [1].jt = 18;
  457. bpf_insn [1].jf = 0;
  458. bpf_insn [1].k = ETHERMTU;
  459. }
  460. else
  461. {
  462. bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
  463. bpf_insn [1].jt = 0;
  464. bpf_insn [1].jf = 18;
  465. bpf_insn [1].k = channel-&gt;type;
  466. }
  467. bpf_insn [3].k = channel-&gt;host [0];
  468. bpf_insn [5].k = channel-&gt;host [1];
  469. bpf_insn [7].k = channel-&gt;host [2];
  470. bpf_insn [9].k = channel-&gt;host [3];
  471. bpf_insn [11].k = channel-&gt;host [4];
  472. bpf_insn [13].k = channel-&gt;host [5];
  473. if (pcap_setfilter (channel-&gt;socket, &amp;bpf_program) &lt; 0)
  474. {
  475. error (1, errno, &quot;Can't store filter: %s&quot;, channel-&gt;ifname);
  476. }
  477. if (pcap_setmintocopy (channel-&gt;socket, ETHER_MIN_LEN) &lt; 0)
  478. {
  479. error (1, errno, &quot;Can't set pcap mintocopy: %s&quot;, channel-&gt;ifname);
  480. }
  481. #else
  482. #error &quot;Unknown Environment&quot;
  483. #endif
  484. #endif
  485. return (0);
  486. }
  487. #endif
  488. </pre>
  489. <div class='footerlink'>
  490. [<a href='nvrampeek.c.html' title=' nvrampeek.c '>PREV</a>]
  491. [<a href='toolkit.html' title=' Index '>HOME</a>]
  492. [<a href='openport.c.html' title=' openport.c '>NEXT</a>]
  493. </div>
  494. </body>
  495. </html>