Example #1
0
static void
configure_interface1(struct interface *ifp)
{
	struct if_options *ifo = ifp->options;
	int ra_global, ra_iface;

	/* Do any platform specific configuration */
	if_conf(ifp);

	if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM))
		ifo->options |= DHCPCD_STATIC;
	if (ifp->flags & IFF_NOARP ||
	    ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
		ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL);
	if (!(ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK | IFF_MULTICAST)))
		ifo->options &= ~DHCPCD_IPV6RS;
	if (ifo->options & DHCPCD_LINK && carrier_status(ifp) == LINK_UNKNOWN)
		ifo->options &= ~DHCPCD_LINK;

	if (ifo->metric != -1)
		ifp->metric = ifo->metric;

	/* We want to disable kernel interface RA as early as possible. */
	if (ifo->options & DHCPCD_IPV6RS) {
		ra_global = check_ipv6(NULL, options & DHCPCD_IPV6RA_OWN ? 1:0);
		ra_iface = check_ipv6(ifp->name,
		    ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0);
		if (ra_global == -1 || ra_iface == -1)
			ifo->options &= ~DHCPCD_IPV6RS;
		else if (ra_iface == 0)
			ifo->options |= DHCPCD_IPV6RA_OWN;
	}

	/* If we haven't specified a ClientID and our hardware address
	 * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID
	 * of the hardware address family and the hardware address. */
	if (ifp->hwlen > DHCP_CHADDR_LEN)
		ifo->options |= DHCPCD_CLIENTID;

	/* Firewire and InfiniBand interfaces require ClientID and
	 * the broadcast option being set. */
	switch (ifp->family) {
	case ARPHRD_IEEE1394:	/* FALLTHROUGH */
	case ARPHRD_INFINIBAND:
		ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST;
		break;
	}
}
Example #2
0
int main(int argc, char *argv[])
{
	int err;
	char *buf[2];
	struct sockaddr_storage address;

	if (argc == 1) { /* automated tests */
		check_ipv4();
		check_ipv6();
		check_resolve();
		exit(EXIT_SUCCESS);
	} else if (argc != 3) {
		printf("usage: %s [host] [port]\n", argv[0]);
		exit(EXIT_SUCCESS);
	}

	err = strtoaddr(argv[1], argv[2], (struct sockaddr *) &address,
					sizeof(struct sockaddr_storage));

	if (err != 0) {
		printf("Unable to convert strings to sockaddr\n");
		exit(EXIT_FAILURE);
	}

	err = addrtostr((struct sockaddr *) &address,
			sizeof(struct sockaddr_storage), buf);

	if (err != 0) {
		printf("Unable to convert sockaddr to strings\n");
		exit(EXIT_FAILURE);
	}

	printf("host: %s port: %s\n", buf[0], buf[1]);
	addrtostr_free(buf);

	return 0;
}
Example #3
0
static void
configure_interface1(struct interface *ifp)
{
	struct if_options *ifo = ifp->options;
	int ra_global, ra_iface;

	/* Do any platform specific configuration */
	if_conf(ifp);

	if (ifp->flags & IFF_POINTOPOINT && !(ifo->options & DHCPCD_INFORM))
		ifo->options |= DHCPCD_STATIC;
	if (ifp->flags & IFF_NOARP ||
	    ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))
		ifo->options &= ~(DHCPCD_ARP | DHCPCD_IPV4LL);
	if (!(ifp->flags & (IFF_POINTOPOINT | IFF_LOOPBACK | IFF_MULTICAST)))
		ifo->options &= ~DHCPCD_IPV6RS;
	if (ifo->options & DHCPCD_LINK && carrier_status(ifp) == LINK_UNKNOWN)
		ifo->options &= ~DHCPCD_LINK;

	if (ifo->metric != -1)
		ifp->metric = ifo->metric;

	if (!(ifo->options & DHCPCD_IPV6))
		ifo->options &= ~DHCPCD_IPV6RS;

	/* We want to disable kernel interface RA as early as possible. */
	if (ifo->options & DHCPCD_IPV6RS) {
		ra_global = check_ipv6(NULL, options & DHCPCD_IPV6RA_OWN ? 1:0);
		ra_iface = check_ipv6(ifp->name,
		    ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0);
		if (ra_global == -1 || ra_iface == -1)
			ifo->options &= ~DHCPCD_IPV6RS;
		else if (ra_iface == 0)
			ifo->options |= DHCPCD_IPV6RA_OWN;
	}

	/* If we haven't specified a ClientID and our hardware address
	 * length is greater than DHCP_CHADDR_LEN then we enforce a ClientID
	 * of the hardware address family and the hardware address. */
	if (ifp->hwlen > DHCP_CHADDR_LEN)
		ifo->options |= DHCPCD_CLIENTID;

	/* Firewire and InfiniBand interfaces require ClientID and
	 * the broadcast option being set. */
	switch (ifp->family) {
	case ARPHRD_IEEE1394:	/* FALLTHROUGH */
	case ARPHRD_INFINIBAND:
		ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST;
		break;
	}

	if (!(ifo->options & DHCPCD_IAID)) {
		/*
		 * An IAID is for identifying a unqiue interface within
		 * the client. It is 4 bytes long. Working out a default
		 * value is problematic.
		 *
		 * Interface name and number are not stable
		 * between different OS's. Some OS's also cannot make
		 * up their mind what the interface should be called
		 * (yes, udev, I'm looking at you).
		 * Also, the name could be longer than 4 bytes.
		 * Also, with pluggable interfaces the name and index
		 * could easily get swapped per actual interface.
		 *
		 * The MAC address is 6 bytes long, the final 3
		 * being unique to the manufacturer and the initial 3
		 * being unique to the organisation which makes it.
		 * We could use the last 4 bytes of the MAC address
		 * as the IAID as it's the most stable part given the
		 * above, but equally it's not guaranteed to be
		 * unique.
		 *
		 * Given the above, and our need to reliably work
		 * between reboots without persitent storage,
		 * generating the IAID from the MAC address is the only
		 * logical default.
		 *
		 * dhclient uses the last 4 bytes of the MAC address.
		 * dibbler uses an increamenting counter.
		 * wide-dhcpv6 uses 0 or a configured value.
		 * odhcp6c uses 1.
		 * Windows 7 uses the first 3 bytes of the MAC address
		 * and an unknown byte.
		 * dhcpcd-6.1.0 and earlier used the interface name,
		 * falling back to interface index if name > 4.
		 */
		memcpy(ifo->iaid, ifp->hwaddr + ifp->hwlen - sizeof(ifo->iaid),
		    sizeof(ifo->iaid));
#if 0
		len = strlen(ifp->name);
		if (len <= sizeof(ifo->iaid)) {
			memcpy(ifo->iaid, ifp->name, len);
			memset(ifo->iaid + len, 0, sizeof(ifo->iaid) - len);
		} else {
			/* IAID is the same size as a uint32_t */
			len = htonl(ifp->index);
			memcpy(ifo->iaid, &len, sizeof(len));
		}
#endif
		ifo->options |= DHCPCD_IAID;
	}

#ifdef INET6
	if (ifo->ia == NULL && ifo->options & DHCPCD_IPV6) {
		ifo->ia = malloc(sizeof(*ifo->ia));
		if (ifo->ia == NULL)
			syslog(LOG_ERR, "%s: %m", __func__);
		else {
			if (ifo->ia_type == 0)
				ifo->ia_type = D6_OPTION_IA_NA;
			memcpy(ifo->ia->iaid, ifo->iaid, sizeof(ifo->iaid));
			ifo->ia_len = 1;
			ifo->ia->sla = NULL;
			ifo->ia->sla_len = 0;
		}
	}
#endif
}
Example #4
0
// TODO and for non NTP packets? (ie 1588)
// FIXME: the ip pointer is dirty and will break with IPv6 packets
int
get_valid_ntp_payload(radpcap_packet_t *packet, struct ntp_pkt **ntp,
                      struct sockaddr_storage *ss_src, struct sockaddr_storage *ss_dst,
                      int *ttl)
{
    struct sockaddr_in *sin;
    struct sockaddr_in6 *sin6;
    struct ip *iph;
    struct ip6_hdr *ip6h;
    struct udphdr *udph;
    linux_sll_header_t *sllh;
    uint16_t proto;
    int remaining;
    int err;

    JDEBUG

    remaining = ((struct pcap_pkthdr *)packet->header)->caplen;

    switch (packet->type) {

    /*
     * This is format #1, skip 14 bytes ethernet header. Only NTP packets ever
     * captured in this format are IPv4
     */
    case DLT_EN10MB:
        iph = (struct ip *)(packet->payload + sizeof(struct ether_header));
        remaining -= sizeof(struct ether_header);
        ip6h = NULL;
        break;

    /*
     * This is format #2 and #3. Here we take advantage of a bug in bytes order in
     * libtrace-3.0-beta3 to identify the formats.
     * - if sllh->hatype = ARPHRD_ETHER (0x0001), we have format 3.
     * - if sllh->hatype is 256 (0x0100) it's a libtrace format.
    */
    case DLT_LINUX_SLL:
        sllh = (linux_sll_header_t*) packet->payload;

        /* Format #2 */
        if (ntohs(sllh->hatype) != 0x0001) {
            iph = (struct ip *)(packet->payload + sizeof(struct ether_header) +
                                sizeof(linux_sll_header_t));
            remaining -= sizeof(struct ether_header);
            ip6h = NULL;
            break;
        }

        /* This is format 3 */
        proto = ntohs(sllh->protocol);
        switch (proto) {

        /* IPv4 */
        case (ETHERTYPE_IP):
            ip6h = NULL;
            iph = (struct ip *)(packet->payload + sizeof(linux_sll_header_t));
            remaining -= sizeof(linux_sll_header_t);

            err = check_ipv4(iph, remaining);
            if (err)
                return (1);

            ss_src->ss_family = AF_INET;
            ss_dst->ss_family = AF_INET;
            sin = (struct sockaddr_in *)ss_src;
            sin->sin_addr = iph->ip_src;
            sin = (struct sockaddr_in *)ss_dst;
            sin->sin_addr = iph->ip_dst;
            *ttl = iph->ip_ttl;

            udph = (struct udphdr *)((char *)iph + (iph->ip_hl * 4));
            remaining -= sizeof(struct ip);
            break;

        /* IPv6 */
        case (ETHERTYPE_IPV6):
            iph = NULL;
            ip6h = (struct ip6_hdr *)(packet->payload + sizeof(linux_sll_header_t));
            remaining -= sizeof(linux_sll_header_t);

            err = check_ipv6(ip6h, remaining);
            if (err)
                return (1);

            ss_src->ss_family = AF_INET6;
            ss_dst->ss_family = AF_INET6;
            sin6 = (struct sockaddr_in6 *)ss_src;
            sin6->sin6_addr = ip6h->ip6_src;
            sin6 = (struct sockaddr_in6 *)ss_dst;
            sin6->sin6_addr = ip6h->ip6_dst;
            *ttl = ip6h->ip6_hops;

            udph = (struct udphdr *)((char *)ip6h + sizeof(struct ip6_hdr));
            remaining -= sizeof(struct ip6_hdr);
            break;

        /* IEEE 1588 over Ethernet */
        case (0x88F7):
            verbose(LOG_ERR, "1588 over Ethernet not implemented");
            return (1);

        default:
            verbose(LOG_ERR, "Unsupported protocol in SLL header %u", proto);
            return(1);
        }
        break;

    default:
        verbose(LOG_ERR, "MAC layer type not supported yet.");
        return (1);
        break;
    }

    if (remaining < sizeof(struct udphdr)) {
        verbose(LOG_WARNING, "Broken UDP datagram");
        return (1);
    }

    *ntp = (struct ntp_pkt *)((char *)udph + sizeof(struct udphdr));
    remaining -= sizeof(struct udphdr);

    /*
     * Make sure the NTP packet is not truncated. A normal NTP packet is at
     * least 48 bytes long, but a control or private request is as small as 12
     * bytes.
     */
    if (remaining < 12) {
        verbose(LOG_WARNING, "NTP packet truncated, payload is %d bytes "
                "instead of at least 12 bytes", remaining);
        return (1);
    }

    return (0);
}