Exemple #1
0
static int ensure_iface_setup(int sock, struct Interface *iface)
{
#ifdef HAVE_NETLINK
	if (iface->state_info.changed)
		setup_iface(sock, iface);
#else
	setup_iface(sock, iface);
#endif

	return (iface->state_info.ready ? 0 : -1);
}
Exemple #2
0
static void setup_iface_foo(struct Interface *iface, void *data)
{
	int sock = *(int *)data;

	if (setup_iface(sock, iface) < 0) {
		if (iface->IgnoreIfMissing) {
			dlog(LOG_DEBUG, 4, "interface %s does not exist or is not set up properly, ignoring the interface",
			     iface->props.name);
			return;
		} else {
			flog(LOG_ERR, "interface %s does not exist or is not set up properly", iface->props.name);
			exit(1);
		}
	}

	config_interface(iface);
	kickoff_adverts(sock, iface);
}
Exemple #3
0
void process(int sock, struct Interface *interfaces, unsigned char *msg, int len, struct sockaddr_in6 *addr,
             struct in6_pktinfo *pkt_info, int hoplimit)
{
    char if_namebuf[IF_NAMESIZE] = { "" };
    char *if_name = if_indextoname(pkt_info->ipi6_ifindex, if_namebuf);
    if (!if_name) {
        if_name = "unknown interface";
    }
    dlog(LOG_DEBUG, 4, "%s received a packet", if_name);

    char addr_str[INET6_ADDRSTRLEN];
    addrtostr(&addr->sin6_addr, addr_str, sizeof(addr_str));

    if (!pkt_info) {
        flog(LOG_WARNING, "%s received packet with no pkt_info from %s!", if_name, addr_str);
        return;
    }

    /*
     * can this happen?
     */

    if (len < sizeof(struct icmp6_hdr)) {
        flog(LOG_WARNING, "%s received icmpv6 packet with invalid length (%d) from %s", if_name, len, addr_str);
        return;
    }

    struct icmp6_hdr *icmph = (struct icmp6_hdr *)msg;

    if (icmph->icmp6_type != ND_ROUTER_SOLICIT && icmph->icmp6_type != ND_ROUTER_ADVERT) {
        /*
         *      We just want to listen to RSs and RAs
         */

        flog(LOG_ERR, "%s icmpv6 filter failed", if_name);
        return;
    }

    if (icmph->icmp6_type == ND_ROUTER_ADVERT) {
        if (len < sizeof(struct nd_router_advert)) {
            flog(LOG_WARNING, "%s received icmpv6 RA packet with invalid length (%d) from %s", if_name, len, addr_str);
            return;
        }

        if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
            flog(LOG_WARNING, "%s received icmpv6 RA packet with non-linklocal source address from %s", if_name, addr_str);
            return;
        }
    }

    if (icmph->icmp6_type == ND_ROUTER_SOLICIT) {
        if (len < sizeof(struct nd_router_solicit)) {
            flog(LOG_WARNING, "%s received icmpv6 RS packet with invalid length (%d) from %s", if_name, len, addr_str);
            return;
        }
    }

    if (icmph->icmp6_code != 0) {
        flog(LOG_WARNING, "%s received icmpv6 RS/RA packet with invalid code (%d) from %s", if_name, icmph->icmp6_code,
             addr_str);
        return;
    }

    /* get iface by received if_index */
    struct Interface *iface = find_iface_by_index(interfaces, pkt_info->ipi6_ifindex);

    if (iface == NULL) {
        dlog(LOG_WARNING, 4, "%s received icmpv6 RS/RA packet on an unknown interface with index %d", if_name,
             pkt_info->ipi6_ifindex);
        return;
    }

    if (!iface->state_info.ready && (0 != setup_iface(sock, iface))) {
        flog(LOG_WARNING, "%s received RS or RA on %s but %s is not ready and setup_iface failed", if_name, iface->props.name,
             iface->props.name);
        return;
    }

    if (hoplimit != 255) {
        flog(LOG_WARNING, "%s received RS or RA with invalid hoplimit %d from %s", if_name, hoplimit, addr_str);
        return;
    }

    if (icmph->icmp6_type == ND_ROUTER_SOLICIT) {
        dlog(LOG_DEBUG, 3, "%s received RS from: %s", if_name, addr_str);
        process_rs(sock, iface, msg, len, addr);
    } else if (icmph->icmp6_type == ND_ROUTER_ADVERT) {
        if (0 == memcmp(&addr->sin6_addr, &iface->props.if_addr, sizeof(iface->props.if_addr))) {
            dlog(LOG_DEBUG, 3, "%s received RA from: %s (myself)", if_name, addr_str);
        } else {
            dlog(LOG_DEBUG, 3, "%s received RA from: %s", if_name, addr_str);
        }
        process_ra(iface, msg, len, addr);
    }
}