diff options
Diffstat (limited to 'src/ipcpd')
-rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index c2309272..3fd2188a 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -53,8 +53,17 @@ #include <sys/types.h> #include <sys/ioctl.h> #include <netinet/in.h> + +#ifdef __linux__ #include <linux/if_packet.h> #include <linux/if_ether.h> +#endif + +#ifdef __FreeBSD__ +#include <net/if_dl.h> +#include <netinet/if_ether.h> +#endif + #include <poll.h> #include <sys/mman.h> @@ -89,7 +98,11 @@ struct eth_llc_ipcp_data { /* Keep ipcp_data first for polymorphism. */ struct ipcp_data ipcp_data; +#ifdef __FreeBSD__ + struct sockaddr_dl device; +#else struct sockaddr_ll device; +#endif int s_fd; struct bmp * indices; @@ -285,7 +298,11 @@ static int eth_llc_ipcp_send_frame(uint8_t dst_addr[MAC_SIZE], uint8_t * frame; #else uint8_t frame[SHIM_ETH_LLC_MAX_SDU_SIZE]; - struct sockaddr_ll device; +#ifdef __FreeBSD__ + struct sockaddr_dl device; +#else + struct sockaddr_ll device; +#endif #endif if (payload == NULL) { @@ -321,7 +338,11 @@ static int eth_llc_ipcp_send_frame(uint8_t dst_addr[MAC_SIZE], memcpy(frame, dst_addr, MAC_SIZE * sizeof(uint8_t)); frame_len += MAC_SIZE; memcpy(frame + frame_len, +#ifdef __FreeBSD__ + LLADDR(&shim_data(_ipcp)->device), +#else shim_data(_ipcp)->device.sll_addr, +#endif MAC_SIZE * sizeof(uint8_t)); frame_len += MAC_SIZE; memcpy(frame + frame_len, &length, 2 * sizeof(uint8_t)); @@ -671,8 +692,11 @@ static void * eth_llc_ipcp_sdu_reader(void * o) #endif for (i = 0; i < MAC_SIZE; i++) dst_mac[i] = buf[i]; - +#ifdef __FreeBSD__ + if (memcmp(LLADDR(&shim_data(_ipcp)->device), +#else if (memcmp(shim_data(_ipcp)->device.sll_addr, +#endif dst_mac, MAC_SIZE) && memcmp(br_addr, dst_mac, MAC_SIZE)) { @@ -868,7 +892,13 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf) int fd = -1; struct ifreq ifr; int index; +#ifdef __FreeBSD__ + struct ifaddrs * ifaddr; + struct ifaddrs * ifa; + struct sockaddr_dl device; +#else struct sockaddr_ll device; +#endif #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) struct tpacket_req req; @@ -897,21 +927,58 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf) memcpy(ifr.ifr_name, conf->if_name, strlen(conf->if_name)); +#ifdef __FreeBSD__ + if (getifaddrs(&ifaddr) < 0) { + close(fd); + LOG_ERR("Could not get interfaces."); + return -1; + } + + for (ifa = ifaddr, index = 0; ifa != NULL; ifa = ifa->ifa_next, ++index) { + if (strcmp(ifa->ifa_name, conf->if_name)) + continue; + LOG_DBGF("Interface %s found.", conf->if_name); + + memcpy(&ifr.ifr_addr, ifa->ifa_addr, sizeof(*ifa->ifa_addr)); + break; + } + + if (ifa == NULL) { + LOG_ERR("Interface not found."); + freeifaddrs(ifaddr); + return -1; + } + + freeifaddrs(ifaddr); + +#else if (ioctl(fd, SIOCGIFHWADDR, &ifr)) { close(fd); LOG_ERR("Failed to ioctl: %s.", strerror(errno)); return -1; } - close(fd); - index = if_nametoindex(conf->if_name); if (index == 0) { LOG_ERR("Failed to retrieve interface index."); return -1; } +#endif + + close(fd); memset(&(device), 0, sizeof(device)); +#ifdef __FreeBSD__ + device.sdl_index = index; + device.sdl_family = AF_LINK; + memcpy(LLADDR(&device), + ifr.ifr_addr.sa_data, + MAC_SIZE * sizeof (uint8_t)); + device.sdl_alen = MAC_SIZE; + /* TODO: replace socket calls with bpf for BSD */ + LOG_MISSING; + fd = socket(AF_LINK, SOCK_RAW, 0); +#else device.sll_ifindex = index; device.sll_family = AF_PACKET; memcpy(device.sll_addr, @@ -921,6 +988,7 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf) device.sll_protocol = htons(ETH_P_ALL); fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_802_2)); +#endif if (fd < 0) { LOG_ERR("Failed to create socket: %s.", strerror(errno)); return -1; @@ -953,8 +1021,7 @@ static int eth_llc_ipcp_bootstrap(struct dif_config * conf) } #endif - if (bind(fd,(struct sockaddr *) &device, - sizeof(struct sockaddr_ll))) { + if (bind(fd,(struct sockaddr *) &device, sizeof(device))) { LOG_ERR("Failed to bind socket to interface"); close(fd); return -1; |