static int open_socket(const char *name, int event) { struct sockaddr_ll addr; int fd, index; fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd < 0) { pr_err("socket failed: %m"); goto no_socket; } index = sk_interface_index(fd, name); if (index < 0) goto no_option; memset(&addr, 0, sizeof(addr)); addr.sll_ifindex = index; addr.sll_family = AF_PACKET; addr.sll_protocol = htons(ETH_P_ALL); if (bind(fd, (struct sockaddr *) &addr, sizeof(addr))) { pr_err("bind failed: %m"); goto no_option; } if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))) { pr_err("setsockopt SO_BINDTODEVICE failed: %m"); goto no_option; } if (raw_configure(fd, event, index, ptp_dst_mac, p2p_dst_mac, 1)) goto no_option; return fd; no_option: close(fd); no_socket: return -1; }
static int open_socket_ipv6(char *name, struct in6_addr mc_addr[2], short port, int *interface_index) { struct sockaddr_in6 addr; int fd, index, on = 1; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_addr = in6addr_any; addr.sin6_port = htons(port); fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { pr_err("socket failed: %m"); goto no_socket; } index = sk_interface_index(fd, name); if (index < 0) goto no_option; *interface_index = index; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { pr_err("setsockopt SO_REUSEADDR failed: %m"); goto no_option; } if (bind(fd, (struct sockaddr *) &addr, sizeof(addr))) { pr_err("bind failed: %m"); goto no_option; } if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))) { pr_err("setsockopt SO_BINDTODEVICE failed: %m"); goto no_option; } addr.sin6_addr = mc_addr[0]; if (mc_join(fd, index, (struct sockaddr *) &addr, sizeof(addr))) { pr_err("mcast_join failed"); goto no_option; } addr.sin6_addr = mc_addr[1]; if (mc_join(fd, index, (struct sockaddr *) &addr, sizeof(addr))) { pr_err("mcast_join failed"); goto no_option; } if (mc_bind(fd, index)) { goto no_option; } return fd; no_option: close(fd); no_socket: return -1; }