Beispiel #1
0
int parse_ip(char *str, char **ipstr, unsigned int *mask)
{
	int ret;
	char *maskstr;
	unsigned int ip[4];
	char dst[65];
	int family;

	if ((maskstr = strchr(str, '/')) != NULL)
		*maskstr++ = 0;
	if ((family = get_netaddr(str, ip)) == -1)
		return -1;
	if ((inet_ntop(family, ip, dst, sizeof(dst) - 1)) == NULL)
		return -1;
	*mask = 0;
	if (maskstr != NULL) {
		if (check_ipv4(maskstr)) {
			if (get_netaddr(maskstr, ip) == -1)
				return -1;
			*mask = ip[0];
		} else {
			ret = parse_int(maskstr, (int *)mask);
			if (ret || *mask > 128 || *mask < 0)
				return -1;
			if (family == AF_INET)
				*mask = htonl(~0 << (32 - *mask));
		}
	}

	*ipstr = strdup(dst);
	return 0;
}
Beispiel #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;
}
Beispiel #3
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);
}