l2_packet_freebsd.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. * WPA Supplicant - Layer2 packet handling with FreeBSD
  3. * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
  4. * Copyright (c) 2005, Sam Leffler <sam@errno.com>
  5. *
  6. * This software may be distributed under the terms of the BSD license.
  7. * See README for more details.
  8. */
  9. #include "includes.h"
  10. #if defined(__APPLE__) || defined(__GLIBC__)
  11. #include <net/bpf.h>
  12. #endif /* __APPLE__ */
  13. #include <pcap.h>
  14. #include <sys/ioctl.h>
  15. #ifdef __sun__
  16. #include <libdlpi.h>
  17. #else /* __sun__ */
  18. #include <sys/sysctl.h>
  19. #endif /* __sun__ */
  20. #include <net/if.h>
  21. #include <net/if_dl.h>
  22. #include <net/route.h>
  23. #include <netinet/in.h>
  24. #include "common.h"
  25. #include "eloop.h"
  26. #include "l2_packet.h"
  27. static const u8 pae_group_addr[ETH_ALEN] =
  28. { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };
  29. struct l2_packet_data {
  30. pcap_t *pcap;
  31. char ifname[100];
  32. u8 own_addr[ETH_ALEN];
  33. void (*rx_callback)(void *ctx, const u8 *src_addr,
  34. const u8 *buf, size_t len);
  35. void *rx_callback_ctx;
  36. int l2_hdr; /* whether to include layer 2 (Ethernet) header data
  37. * buffers */
  38. };
  39. int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
  40. {
  41. os_memcpy(addr, l2->own_addr, ETH_ALEN);
  42. return 0;
  43. }
  44. int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
  45. const u8 *buf, size_t len)
  46. {
  47. if (!l2->l2_hdr) {
  48. int ret;
  49. struct l2_ethhdr *eth = os_malloc(sizeof(*eth) + len);
  50. if (eth == NULL)
  51. return -1;
  52. os_memcpy(eth->h_dest, dst_addr, ETH_ALEN);
  53. os_memcpy(eth->h_source, l2->own_addr, ETH_ALEN);
  54. eth->h_proto = htons(proto);
  55. os_memcpy(eth + 1, buf, len);
  56. ret = pcap_inject(l2->pcap, (u8 *) eth, len + sizeof(*eth));
  57. os_free(eth);
  58. return ret;
  59. } else
  60. return pcap_inject(l2->pcap, buf, len);
  61. }
  62. static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
  63. {
  64. struct l2_packet_data *l2 = eloop_ctx;
  65. pcap_t *pcap = sock_ctx;
  66. struct pcap_pkthdr hdr;
  67. const u_char *packet;
  68. struct l2_ethhdr *ethhdr;
  69. unsigned char *buf;
  70. size_t len;
  71. packet = pcap_next(pcap, &hdr);
  72. if (packet == NULL || hdr.caplen < sizeof(*ethhdr))
  73. return;
  74. ethhdr = (struct l2_ethhdr *) packet;
  75. if (l2->l2_hdr) {
  76. buf = (unsigned char *) ethhdr;
  77. len = hdr.caplen;
  78. } else {
  79. buf = (unsigned char *) (ethhdr + 1);
  80. len = hdr.caplen - sizeof(*ethhdr);
  81. }
  82. l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len);
  83. }
  84. static int l2_packet_init_libpcap(struct l2_packet_data *l2,
  85. unsigned short protocol)
  86. {
  87. bpf_u_int32 pcap_maskp, pcap_netp;
  88. char pcap_filter[200], pcap_err[PCAP_ERRBUF_SIZE];
  89. struct bpf_program pcap_fp;
  90. pcap_lookupnet(l2->ifname, &pcap_netp, &pcap_maskp, pcap_err);
  91. l2->pcap = pcap_open_live(l2->ifname, 2500, 0, 10, pcap_err);
  92. if (l2->pcap == NULL) {
  93. fprintf(stderr, "pcap_open_live: %s\n", pcap_err);
  94. fprintf(stderr, "ifname='%s'\n", l2->ifname);
  95. return -1;
  96. }
  97. if (pcap_datalink(l2->pcap) != DLT_EN10MB &&
  98. pcap_set_datalink(l2->pcap, DLT_EN10MB) < 0) {
  99. fprintf(stderr, "pcap_set_datalink(DLT_EN10MB): %s\n",
  100. pcap_geterr(l2->pcap));
  101. return -1;
  102. }
  103. os_snprintf(pcap_filter, sizeof(pcap_filter),
  104. "not ether src " MACSTR " and "
  105. "( ether dst " MACSTR " or ether dst " MACSTR " ) and "
  106. "ether proto 0x%x",
  107. MAC2STR(l2->own_addr), /* do not receive own packets */
  108. MAC2STR(l2->own_addr), MAC2STR(pae_group_addr),
  109. protocol);
  110. if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0) {
  111. fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(l2->pcap));
  112. return -1;
  113. }
  114. if (pcap_setfilter(l2->pcap, &pcap_fp) < 0) {
  115. fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(l2->pcap));
  116. return -1;
  117. }
  118. pcap_freecode(&pcap_fp);
  119. #ifndef __sun__
  120. /*
  121. * When libpcap uses BPF we must enable "immediate mode" to
  122. * receive frames right away; otherwise the system may
  123. * buffer them for us.
  124. */
  125. {
  126. unsigned int on = 1;
  127. if (ioctl(pcap_fileno(l2->pcap), BIOCIMMEDIATE, &on) < 0) {
  128. fprintf(stderr, "%s: cannot enable immediate mode on "
  129. "interface %s: %s\n",
  130. __func__, l2->ifname, strerror(errno));
  131. /* XXX should we fail? */
  132. }
  133. }
  134. #endif /* __sun__ */
  135. eloop_register_read_sock(pcap_get_selectable_fd(l2->pcap),
  136. l2_packet_receive, l2, l2->pcap);
  137. return 0;
  138. }
  139. static int eth_get(const char *device, u8 ea[ETH_ALEN])
  140. {
  141. #ifdef __sun__
  142. dlpi_handle_t dh;
  143. u32 physaddrlen = DLPI_PHYSADDR_MAX;
  144. u8 physaddr[DLPI_PHYSADDR_MAX];
  145. int retval;
  146. retval = dlpi_open(device, &dh, 0);
  147. if (retval != DLPI_SUCCESS) {
  148. wpa_printf(MSG_ERROR, "dlpi_open error: %s",
  149. dlpi_strerror(retval));
  150. return -1;
  151. }
  152. retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, physaddr,
  153. &physaddrlen);
  154. if (retval != DLPI_SUCCESS) {
  155. wpa_printf(MSG_ERROR, "dlpi_get_physaddr error: %s",
  156. dlpi_strerror(retval));
  157. dlpi_close(dh);
  158. return -1;
  159. }
  160. os_memcpy(ea, physaddr, ETH_ALEN);
  161. dlpi_close(dh);
  162. #else /* __sun__ */
  163. struct if_msghdr *ifm;
  164. struct sockaddr_dl *sdl;
  165. u_char *p, *buf;
  166. size_t len;
  167. int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
  168. if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
  169. return -1;
  170. if ((buf = os_malloc(len)) == NULL)
  171. return -1;
  172. if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
  173. os_free(buf);
  174. return -1;
  175. }
  176. for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
  177. ifm = (struct if_msghdr *)p;
  178. sdl = (struct sockaddr_dl *)(ifm + 1);
  179. if (ifm->ifm_type != RTM_IFINFO ||
  180. (ifm->ifm_addrs & RTA_IFP) == 0)
  181. continue;
  182. if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
  183. os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0)
  184. continue;
  185. os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
  186. break;
  187. }
  188. os_free(buf);
  189. if (p >= buf + len) {
  190. errno = ESRCH;
  191. return -1;
  192. }
  193. #endif /* __sun__ */
  194. return 0;
  195. }
  196. struct l2_packet_data * l2_packet_init(
  197. const char *ifname, const u8 *own_addr, unsigned short protocol,
  198. void (*rx_callback)(void *ctx, const u8 *src_addr,
  199. const u8 *buf, size_t len),
  200. void *rx_callback_ctx, int l2_hdr)
  201. {
  202. struct l2_packet_data *l2;
  203. l2 = os_zalloc(sizeof(struct l2_packet_data));
  204. if (l2 == NULL)
  205. return NULL;
  206. os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname));
  207. l2->rx_callback = rx_callback;
  208. l2->rx_callback_ctx = rx_callback_ctx;
  209. l2->l2_hdr = l2_hdr;
  210. if (eth_get(l2->ifname, l2->own_addr) < 0) {
  211. fprintf(stderr, "Failed to get link-level address for "
  212. "interface '%s'.\n", l2->ifname);
  213. os_free(l2);
  214. return NULL;
  215. }
  216. if (l2_packet_init_libpcap(l2, protocol)) {
  217. os_free(l2);
  218. return NULL;
  219. }
  220. return l2;
  221. }
  222. struct l2_packet_data * l2_packet_init_bridge(
  223. const char *br_ifname, const char *ifname, const u8 *own_addr,
  224. unsigned short protocol,
  225. void (*rx_callback)(void *ctx, const u8 *src_addr,
  226. const u8 *buf, size_t len),
  227. void *rx_callback_ctx, int l2_hdr)
  228. {
  229. return l2_packet_init(br_ifname, own_addr, protocol, rx_callback,
  230. rx_callback_ctx, l2_hdr);
  231. }
  232. void l2_packet_deinit(struct l2_packet_data *l2)
  233. {
  234. if (l2 != NULL) {
  235. if (l2->pcap) {
  236. eloop_unregister_read_sock(
  237. pcap_get_selectable_fd(l2->pcap));
  238. pcap_close(l2->pcap);
  239. }
  240. os_free(l2);
  241. }
  242. }
  243. int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len)
  244. {
  245. pcap_if_t *devs, *dev;
  246. struct pcap_addr *addr;
  247. struct sockaddr_in *saddr;
  248. int found = 0;
  249. char err[PCAP_ERRBUF_SIZE + 1];
  250. if (pcap_findalldevs(&devs, err) < 0) {
  251. wpa_printf(MSG_DEBUG, "pcap_findalldevs: %s\n", err);
  252. return -1;
  253. }
  254. for (dev = devs; dev && !found; dev = dev->next) {
  255. if (os_strcmp(dev->name, l2->ifname) != 0)
  256. continue;
  257. addr = dev->addresses;
  258. while (addr) {
  259. saddr = (struct sockaddr_in *) addr->addr;
  260. if (saddr && saddr->sin_family == AF_INET) {
  261. os_strlcpy(buf, inet_ntoa(saddr->sin_addr),
  262. len);
  263. found = 1;
  264. break;
  265. }
  266. addr = addr->next;
  267. }
  268. }
  269. pcap_freealldevs(devs);
  270. return found ? 0 : -1;
  271. }
  272. void l2_packet_notify_auth_start(struct l2_packet_data *l2)
  273. {
  274. }
  275. int l2_packet_set_packet_filter(struct l2_packet_data *l2,
  276. enum l2_packet_filter_type type)
  277. {
  278. return -1;
  279. }