sendpacket.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /* $Id: sendpacket.c 1583 2006-08-08 04:25:31Z aturner $ */
  2. /*
  3. * Copyright (c) 2006 Aaron Turner.
  4. * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
  5. * Copyright (c) 2000 Torsten Landschoff <torsten@debian.org>
  6. * Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
  7. * Copyright (c) 1993, 1994, 1995, 1996, 1998
  8. * The Regents of the University of California.
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in the
  19. * documentation and/or other materials provided with the distribution.
  20. * 3. Neither the names of the copyright owners nor the names of its
  21. * contributors may be used to endorse or promote products derived from
  22. * this software without specific prior written permission.
  23. * 4. All advertising materials mentioning features or use of this software
  24. * display the following acknowledgement:
  25. * ``This product includes software developed by the University of
  26. * California, Lawrence Berkeley Laboratory and its contributors.''
  27. *
  28. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  31. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  32. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  35. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  36. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  37. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  38. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. */
  40. /* sendpacket.[ch] is my attempt to write a universal packet injection
  41. * API for BPF, libpcap, libnet, and Linux's PF_PACKET. I got sick
  42. * and tired dealing with libnet bugs and its lack of active maintenence,
  43. * but unfortunately, libpcap frame injection support is relatively new
  44. * and not everyone uses Linux, so I decided to support all four as
  45. * best as possible. If your platform/OS/hardware supports an additional
  46. * injection method, then by all means add it here (and send me a patch).
  47. *
  48. * Anyways, long story short, for now the order of preference is:
  49. * 1. PF_PACKET
  50. * 2. BPF
  51. * 3. libnet
  52. * 4. pcap_inject()
  53. * 5. pcap_sendpacket()
  54. *
  55. * Right now, one big problem with the pcap_* methods is that libpcap
  56. * doesn't provide a reliable method of getting the MAC address of
  57. * an interface (required for tcpbridge).
  58. * You can use PF_PACKET or BPF to get that, but if your system suports
  59. * those, might as well inject directly without going through another
  60. * level of indirection.
  61. *
  62. * Please note that some of this code was copied from Libnet 1.1.3
  63. */
  64. #include "config.h"
  65. #include "defines.h"
  66. #include "common.h"
  67. #include "sendpacket.h"
  68. #if !defined HAVE_PCAP_INJECT && !defined HAVE_PCAP_SENDPACKET && !defined HAVE_LIBNET && !defined HAVE_PF_PACKET && !defined HAVE_BPF
  69. #error You need pcap_inject() or pcap_sendpacket() from libpcap, libnet 1.1.3+, Linux's PF_PACKET or *BSD's BPF
  70. #endif
  71. #include <string.h>
  72. #include <errno.h>
  73. #include <stdarg.h>
  74. #include <sys/types.h>
  75. #include <sys/time.h>
  76. #include <sys/ioctl.h>
  77. #include <sys/file.h>
  78. #include <sys/sysctl.h>
  79. #include <net/route.h>
  80. #include <stdlib.h>
  81. #include <unistd.h>
  82. #if defined HAVE_PF_PACKET
  83. #include <fcntl.h>
  84. #include <sys/socket.h>
  85. #include <sys/utsname.h>
  86. #include <net/if.h>
  87. #include <netinet/in.h>
  88. #include <linux/if_ether.h>
  89. #include <net/if_arp.h>
  90. #include <netpacket/packet.h>
  91. #ifndef __GLIBC__
  92. typedef int socklen_t;
  93. #endif
  94. static sendpacket_t *sendpacket_open_pf(const char *, char *);
  95. static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *);
  96. static int get_iface_index(int fd, const int8_t *device, char *);
  97. #elif defined HAVE_BPF
  98. #include <net/bpf.h>
  99. #include <sys/socket.h>
  100. #include <net/if.h>
  101. #include <sys/uio.h>
  102. #include <pcap.h>
  103. #include <net/if_dl.h> // used for get_hwaddr_bpf()
  104. static sendpacket_t *sendpacket_open_bpf(const char *, char *);
  105. static struct tcpr_ether_addr *sendpacket_get_hwaddr_bpf(sendpacket_t *);
  106. #elif defined HAVE_LIBNET
  107. static sendpacket_t *sendpacket_open_libnet(const char *, char *);
  108. static struct tcpr_ether_addr *sendpacket_get_hwaddr_libnet(sendpacket_t *);
  109. #elif defined HAVE_PCAP_INJECT || defined HAVE_PACKET_SENDPACKET
  110. #include <pcap.h>
  111. static sendpacket_t *sendpacket_open_pcap(const char *, char *);
  112. static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *);
  113. #endif
  114. static void sendpacket_seterr(sendpacket_t *sp, const char *fmt, ...);
  115. /* You need to define didsig in your main .c file. Set to 1 if CTRL-C was pressed */
  116. extern volatile int didsig;
  117. /*
  118. * returns number of bytes sent on success or -1 on error
  119. * Note: it is theoretically possible to get a return code >0 and < len
  120. * which for most people would be considered an error (the packet wasn't fully sent)
  121. * so you may want to test for recode != len too.
  122. */
  123. int
  124. sendpacket(sendpacket_t *sp, const u_char *data, size_t len)
  125. {
  126. int retcode;
  127. assert(sp);
  128. assert(data);
  129. if (len <= 0)
  130. return -1;
  131. TRY_SEND_AGAIN:
  132. sp->attempt ++;
  133. #if defined HAVE_PF_PACKET
  134. retcode = (int)send(sp->handle.fd, (void *)data, len, 0);
  135. /* out of buffers, silently retry */
  136. if (retcode < 0 && errno == ENOBUFS && !didsig) {
  137. sp->retry ++;
  138. goto TRY_SEND_AGAIN;
  139. }
  140. /* some other kind of error */
  141. else if (retcode < 0) {
  142. sendpacket_seterr(sp, "Error with pf send(): %s", strerror(errno));
  143. }
  144. #elif defined HAVE_BPF
  145. retcode = write(sp->handle.fd, (void *)data, len);
  146. if (retcode < 0 && errno == ENOBUFS && !didsig) {
  147. sp->retry ++;
  148. goto TRY_SEND_AGAIN;
  149. } else if (retcode < 0) {
  150. sendpacket_seterr(sp, "Error with bpf write(): %s", strerror(errno));
  151. }
  152. #elif defined HAVE_LIBNET
  153. retcode = libnet_adv_write_link(sp->handle.lnet, (u_int8_t*)data, (u_int32_t)len);
  154. if (retcode < 0 && errno == ENOBUFS && !didsig) {
  155. sp->retry ++;
  156. goto TRY_SEND_AGAIN;
  157. } else if (retcode < 0) {
  158. sendpacket_seterr(sp, "Error with libnet write: %s", libnet_geterror(sp->handle.lnet));
  159. }
  160. /*
  161. * pcap methods don't seem to support ENOBUFS, so we just straight fail
  162. * is there a better way???
  163. */
  164. #elif defined HAVE_PCAP_INJECT
  165. if ((retcode = pcap_inject(sp->handle.pcap, (void*)data, len)) < 0)
  166. sendpacket_seterr(sp, "Error with pcap_inject(): %s", pcap_geterr(sp->handle.pcap));
  167. #elif defined HAVE_PCAP_SENDPACKET
  168. if ((retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len)) < 0)
  169. sendpacket_seterr(sp, "Error with pcap_sendpacket(): %s", pcap_geterr(sp->handle.pcap));
  170. #endif
  171. if (retcode < 0) {
  172. sp->failed ++;
  173. } else if (retcode != (int)len) {
  174. sendpacket_seterr(sp, "Only able to write %d bytes out of %u bytes total",
  175. retcode, len);
  176. } else {
  177. sp->bytes_sent += len;
  178. sp->sent ++;
  179. }
  180. return retcode;
  181. }
  182. sendpacket_t *
  183. sendpacket_open(const char *device, char *errbuf)
  184. {
  185. sendpacket_t *sp;
  186. assert(device);
  187. assert(errbuf);
  188. #if defined HAVE_PF_PACKET
  189. sp = sendpacket_open_pf(device, errbuf);
  190. #elif defined HAVE_BPF
  191. sp = sendpacket_open_bpf(device, errbuf);
  192. #elif defined HAVE_LIBNET
  193. sp = sendpacket_open_libnet(device, errbuf);
  194. #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
  195. sp = sendpacket_open_pcap(device, errbuf);
  196. #endif
  197. if (sp != NULL)
  198. sp->open = 1;
  199. return sp;
  200. }
  201. char *
  202. sendpacket_getstat(sendpacket_t *sp)
  203. {
  204. static char buf[1024];
  205. assert(sp);
  206. memset(buf, 0, sizeof(buf));
  207. sprintf(buf, "Statistics for network device: %s\n", sp->device);
  208. sprintf(buf, "Attempted packets: " COUNTER_SPEC "\n", sp->attempt);
  209. sprintf(buf, "Successful packets: " COUNTER_SPEC "\n", sp->sent);
  210. sprintf(buf, "Failed packets: " COUNTER_SPEC "\n", sp->failed);
  211. sprintf(buf, "Retried packets: " COUNTER_SPEC "\n", sp->retry);
  212. return(buf);
  213. }
  214. int
  215. sendpacket_close(sendpacket_t *sp)
  216. {
  217. assert(sp);
  218. free(sp);
  219. return 0;
  220. }
  221. /*
  222. * returns the Layer 2 address of the interface current
  223. * open. on error, return NULL
  224. */
  225. struct tcpr_ether_addr *
  226. sendpacket_get_hwaddr(sendpacket_t *sp)
  227. {
  228. struct tcpr_ether_addr *addr;
  229. assert(sp);
  230. /* if we already have our MAC address stored, just return it */
  231. if (memcmp(&sp->ether, "\00\00\00\00\00\00", ETHER_ADDR_LEN) != 0)
  232. return &sp->ether;
  233. #if defined HAVE_PF_PACKET
  234. addr = sendpacket_get_hwaddr_pf(sp);
  235. #elif defined HAVE_BPF
  236. addr = sendpacket_get_hwaddr_bpf(sp);
  237. #elif defined HAVE_LIBNET
  238. addr = sendpacket_get_hwaddr_libnet(sp);
  239. #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
  240. addr = sendpacket_get_hwaddr_pcap(sp);
  241. #endif
  242. return addr;
  243. }
  244. /*
  245. * returns the error string
  246. */
  247. char *
  248. sendpacket_geterr(sendpacket_t *sp)
  249. {
  250. assert(sp);
  251. return sp->errbuf;
  252. }
  253. /*
  254. * Set's the error string
  255. */
  256. static void
  257. sendpacket_seterr(sendpacket_t *sp, const char *fmt, ...)
  258. {
  259. va_list ap;
  260. assert(sp);
  261. va_start(ap, fmt);
  262. if (fmt != NULL)
  263. (void)vsnprintf(sp->errbuf, SENDPACKET_ERRBUF_SIZE, fmt, ap);
  264. va_end(ap);
  265. sp->errbuf[(SENDPACKET_ERRBUF_SIZE-1)] = '\0'; // be safe
  266. }
  267. #if defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET
  268. static sendpacket_t *
  269. sendpacket_open_pcap(const char *device, char *errbuf)
  270. {
  271. pcap_t *pcap;
  272. sendpacket_t *sp;
  273. assert(device);
  274. assert(errbuf);
  275. /* open_pcap_live automatically fills out our errbuf for us */
  276. if ((pcap = pcap_open_live(device, 0, 0, 0, errbuf)) == NULL)
  277. return NULL;
  278. sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
  279. strlcpy(sp->device, device, sizeof(sp->device));
  280. sp->handle.pcap = pcap;
  281. return sp;
  282. }
  283. static struct tcpr_ether_addr *
  284. sendpacket_get_hwaddr_pcap(sendpacket_t *sp)
  285. {
  286. assert(sp);
  287. sendpacket_seterr(sp, "Error: sendpacket_get_hwaddr() not yet supported for pcap injection");
  288. return NULL;
  289. }
  290. #endif
  291. #if defined HAVE_LIBNET
  292. static sendpacket_t *
  293. sendpacket_open_libnet(const char *device, char *errbuf)
  294. {
  295. libnet_t *lnet;
  296. sendpacket_t *sp;
  297. assert(device);
  298. assert(errbuf);
  299. if ((lnet = libnet_init(LIBNET_LINK_ADV, device, errbuf)) == NULL)
  300. return NULL;
  301. sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
  302. strlcpy(sp->device, device, sizeof(sp->device));
  303. sp->handle.lnet = lnet;
  304. return sp;
  305. }
  306. static struct tcpr_ether_addr *
  307. sendpacket_get_hwaddr_libnet(sendpacket_t *sp)
  308. {
  309. struct tcpr_ether_addr *addr;
  310. assert(sp);
  311. addr = (struct tcpr_ether_addr *)libnet_get_hwaddr(sp->handle.lnet);
  312. if (addr == NULL) {
  313. sendpacket_seterr(sp, "Error getting hwaddr via libnet: %s", libnet_geterror(sp->handle.lnet));
  314. return NULL;
  315. }
  316. memcpy(&sp->ether, addr, sizeof(struct tcpr_ether_addr));
  317. return(&sp->ether);
  318. }
  319. #endif
  320. #if defined HAVE_PF_PACKET
  321. static sendpacket_t *
  322. sendpacket_open_pf(const char *device, char *errbuf)
  323. {
  324. int mysocket;
  325. sendpacket_t *sp;
  326. struct ifreq ifr;
  327. struct sockaddr_ll sa;
  328. int n = 1, err;
  329. socklen_t errlen = sizeof(err);
  330. assert(device);
  331. assert(errbuf);
  332. /* open our socket */
  333. if ((mysocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
  334. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "socket: %s", strerror(errno));
  335. return NULL;
  336. }
  337. /* get the interface id for the device */
  338. if ((sa.sll_ifindex = get_iface_index(mysocket, device, errbuf)) < 0) {
  339. close(mysocket);
  340. return NULL;
  341. }
  342. /* bind socket to our interface id */
  343. sa.sll_family = AF_PACKET;
  344. sa.sll_protocol = htons(ETH_P_ALL);
  345. if (bind(mysocket, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
  346. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "bind error: %s", strerror(errno));
  347. close(mysocket);
  348. return NULL;
  349. }
  350. /* check for errors, network down, etc... */
  351. if (getsockopt(mysocket, SOL_SOCKET, SO_ERROR, &err, &errlen) < 0) {
  352. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device,
  353. strerror(errno));
  354. close(mysocket);
  355. return NULL;
  356. }
  357. if (err > 0) {
  358. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device,
  359. strerror(err));
  360. close(mysocket);
  361. return NULL;
  362. }
  363. /* get hardware type for our interface */
  364. memset(&ifr, 0, sizeof(ifr));
  365. strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  366. if (ioctl(mysocket, SIOCGIFHWADDR, &ifr) < 0) {
  367. close(mysocket);
  368. sendpacket_seterr(sp, "Error getting hardware type: %s", strerror(errno));
  369. return NULL;
  370. }
  371. /* make sure it's ethernet */
  372. switch (ifr.ifr_hwaddr.sa_family) {
  373. case ARPHRD_ETHER:
  374. break;
  375. default:
  376. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
  377. "unsupported pysical layer type 0x%x", ifr.ifr_hwaddr.sa_family);
  378. close(mysocket);
  379. return NULL;
  380. }
  381. #ifdef SO_BROADCAST
  382. /*
  383. * man 7 socket
  384. *
  385. * Set or get the broadcast flag. When enabled, datagram sockets
  386. * receive packets sent to a broadcast address and they are allowed
  387. * to send packets to a broadcast address. This option has no
  388. * effect on stream-oriented sockets.
  389. */
  390. if (setsockopt(mysocket, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) == -1) {
  391. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
  392. "SO_BROADCAS: %s\n", strerror(errno));
  393. close(mysocket);
  394. return NULL;
  395. }
  396. #endif /* SO_BROADCAST */
  397. /* prep & return our sp handle */
  398. sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
  399. strlcpy(sp->device, device, sizeof(sp->device));
  400. sp->handle.fd = mysocket;
  401. return sp;
  402. }
  403. /* get the interface index (necessary for sending packets w/ PF_PACKET) */
  404. static int
  405. get_iface_index(int fd, const int8_t *device, char *errbuf) {
  406. struct ifreq ifr;
  407. memset(&ifr, 0, sizeof(ifr));
  408. strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  409. if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
  410. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "ioctl: %s", strerror(errno));
  411. return (-1);
  412. }
  413. return ifr.ifr_ifindex;
  414. }
  415. /*
  416. * get's the hardware address via Linux's PF packet
  417. * interface
  418. */
  419. struct tcpr_ether_addr *
  420. sendpacket_get_hwaddr_pf(sendpacket_t *sp)
  421. {
  422. struct ifreq ifr;
  423. int fd;
  424. assert(sp);
  425. if (!sp->open) {
  426. sendpacket_seterr(sp, "Unable to get hardware address on un-opened sendpacket handle");
  427. return NULL;
  428. }
  429. /* create dummy socket for ioctl */
  430. if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  431. sendpacket_seterr(sp, "Unable to open dummy socket for get_hwaddr: %s", strerror(errno));
  432. return NULL;
  433. }
  434. memset(&ifr, 0, sizeof(ifr));
  435. strlcpy(ifr.ifr_name, sp->device, sizeof(ifr.ifr_name));
  436. if (ioctl(fd, SIOCGIFHWADDR, (int8_t *)&ifr) < 0) {
  437. close(fd);
  438. sendpacket_seterr(sp, "Error getting hardware address: %s", strerror(errno));
  439. return NULL;
  440. }
  441. memcpy(&sp->ether, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
  442. close(fd);
  443. return(&sp->ether);
  444. }
  445. #endif
  446. #if defined HAVE_BPF
  447. static sendpacket_t *
  448. sendpacket_open_bpf(const char *device, char *errbuf)
  449. {
  450. sendpacket_t *sp;
  451. char bpf_dev[10];
  452. int dev, mysocket, link_offset, link_type;
  453. struct ifreq ifr;
  454. struct bpf_version bv;
  455. u_int v;
  456. #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__)
  457. u_int spoof_eth_src = 1;
  458. #endif
  459. assert(device);
  460. assert(errbuf);
  461. memset(&ifr, '\0', sizeof(struct ifreq));
  462. /* open socket */
  463. mysocket = -1;
  464. for (dev = 0; dev <= 9; dev ++) {
  465. memset(bpf_dev, '\0', sizeof(bpf_dev));
  466. snprintf(bpf_dev, sizeof(bpf_dev), "/dev/bpf%d", dev);
  467. if ((mysocket = open(bpf_dev, O_RDWR, 0)) > 0) {
  468. break;
  469. }
  470. }
  471. /* error?? */
  472. if (mysocket < 0) {
  473. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
  474. "Unable to open /dev/bpfX: %s", strerror(errno));
  475. errbuf[SENDPACKET_ERRBUF_SIZE -1] = '\0';
  476. return NULL;
  477. }
  478. /* get BPF version */
  479. if (ioctl(mysocket, BIOCVERSION, (caddr_t)&bv) < 0) {
  480. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to get bpf version: %s", strerror(errno));
  481. return NULL;
  482. }
  483. if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor != BPF_MINOR_VERSION) {
  484. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Kernel's bpf version is out of date.");
  485. return NULL;
  486. }
  487. /* attach to device */
  488. strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
  489. if (ioctl(mysocket, BIOCSETIF, (caddr_t)&ifr) < 0) {
  490. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to bind %s to %s: %s",
  491. bpf_dev, device, strerror(errno));
  492. return NULL;
  493. }
  494. /* get datalink type */
  495. if (ioctl(mysocket, BIOCGDLT, (caddr_t)&v) < 0) {
  496. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to get datalink type: %s",
  497. strerror(errno));
  498. return NULL;
  499. }
  500. /*
  501. * NetBSD and FreeBSD BPF have an ioctl for enabling/disabling
  502. * automatic filling of the link level source address.
  503. */
  504. #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) && !(__APPLE__)
  505. if (ioctl(mysocket, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
  506. snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
  507. "Unable to enable spoofing src MAC: %s", strerror(errno));
  508. return NULL;
  509. }
  510. #endif
  511. /* assign link type and offset */
  512. switch (v) {
  513. case DLT_SLIP:
  514. link_offset = 0x10;
  515. break;
  516. case DLT_RAW:
  517. link_offset = 0x0;
  518. break;
  519. case DLT_PPP:
  520. link_offset = 0x04;
  521. break;
  522. case DLT_EN10MB:
  523. default: /* default to Ethernet */
  524. link_offset = 0xe;
  525. break;
  526. }
  527. #if _BSDI_VERSION - 0 > 199510
  528. switch (v) {
  529. case DLT_SLIP:
  530. v = DLT_SLIP_BSDOS;
  531. link_offset = 0x10;
  532. break;
  533. case DLT_PPP:
  534. v = DLT_PPP_BSDOS;
  535. link_offset = 0x04;
  536. break;
  537. }
  538. #endif
  539. link_type = v;
  540. /* allocate our sp handle, and return it */
  541. sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
  542. strlcpy(sp->device, device, sizeof(sp->device));
  543. sp->handle.fd = mysocket;
  544. //sp->link_type = link_type;
  545. //sp->link_offset = link_offset;
  546. return sp;
  547. }
  548. struct tcpr_ether_addr *
  549. sendpacket_get_hwaddr_bpf(sendpacket_t *sp)
  550. {
  551. int mib[6];
  552. size_t len;
  553. int8_t *buf, *next, *end;
  554. struct if_msghdr *ifm;
  555. struct sockaddr_dl *sdl;
  556. assert(sp);
  557. mib[0] = CTL_NET;
  558. mib[1] = AF_ROUTE;
  559. mib[2] = 0;
  560. mib[3] = AF_LINK;
  561. mib[4] = NET_RT_IFLIST;
  562. mib[5] = 0;
  563. if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
  564. sendpacket_seterr(sp, "%s(): sysctl(): %s", __func__, strerror(errno));
  565. return NULL;
  566. }
  567. buf = (int8_t *)safe_malloc(len);
  568. if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) {
  569. sendpacket_seterr(sp, "%s(): sysctl(): %s", __func__, strerror(errno));
  570. free(buf);
  571. return NULL;
  572. }
  573. end = buf + len;
  574. for (next = buf; next < end; next += ifm->ifm_msglen) {
  575. ifm = (struct if_msghdr *)next;
  576. if (ifm->ifm_type == RTM_IFINFO) {
  577. sdl = (struct sockaddr_dl *)(ifm + 1);
  578. if (strncmp(&sdl->sdl_data[0], sp->device, sdl->sdl_len) == 0) {
  579. memcpy(&sp->ether, LLADDR(sdl), ETHER_ADDR_LEN);
  580. break;
  581. }
  582. }
  583. }
  584. free(buf);
  585. return(&sp->ether);
  586. }
  587. #endif