Esempio n. 1
0
File: bpf.c Progetto: gduchene/dhcpd
int
ipv4_output(struct reply *reply, struct request *req)
{
	unsigned short len;
	u_int32_t sum;

	if (reply->off <= 0)
		fatalx("bad reply offset");

	len = sizeof reply->pkt.bootp + reply->off;

	reply->pkt.l3.ip_v = 4;
	reply->pkt.l3.ip_hl = 5;
	reply->pkt.l3.ip_ttl = 16;
	reply->pkt.l3.ip_len = htons(len +
	    sizeof reply->pkt.l3 + sizeof reply->pkt.l4);
	reply->pkt.l3.ip_tos = IPTOS_LOWDELAY;
	reply->pkt.l3.ip_p = IPPROTO_UDP;

	reply->pkt.l3.ip_src = ipv4_addr(req->rcvd_on);
	reply->pkt.l3.ip_dst = destination(reply, req, &reply->pkt.l4.uh_dport);

	/* Fill in IPv4 checksum. */
	sum = checksum(&reply->pkt.l3, sizeof reply->pkt.l3, 0);
	reply->pkt.l3.ip_sum = wrapsum(sum);

	/* Fill in UDP checksum, now that we have the IPv4 header. */
	sum = ntohs(reply->pkt.l4.uh_ulen) + IPPROTO_UDP;
	sum = checksum(&reply->pkt.l3.ip_src, 2 * sizeof(struct in_addr), sum);
	sum = checksum(&reply->pkt.bootp, len, sum);
	sum = checksum(&reply->pkt.l4, sizeof reply->pkt.l4, sum);
	reply->pkt.l4.uh_sum = wrapsum(sum);

	return 20;
}
Esempio n. 2
0
File: acl.c Progetto: jkadlec/knot
bool netblock_match(const struct sockaddr_storage *ss1,
                    const struct sockaddr_storage *ss2,
                    unsigned prefix)
{
	if (ss1 == NULL || ss2 == NULL) {
		return false;
	}

	if (ss1->ss_family != ss2->ss_family) {
		return false;
	}

	const uint8_t *addr1, *addr2;
	switch (ss1->ss_family) {
	case AF_INET:
		addr1 = ipv4_addr(ss1);
		addr2 = ipv4_addr(ss2);
		prefix = prefix > IPV4_PREFIXLEN ? IPV4_PREFIXLEN : prefix;
		break;
	case AF_INET6:
		addr1 = ipv6_addr(ss1);
		addr2 = ipv6_addr(ss2);
		prefix = prefix > IPV6_PREFIXLEN ? IPV6_PREFIXLEN : prefix;
		break;
	default:
		return false;
	}

	/* Compare full bytes address block. */
	uint8_t full_bytes = prefix / 8;
	for (int i = 0; i < full_bytes; i++) {
		if (addr1[i] != addr2[i]) {
			return false;
		}
	}

	/* Compare last partial byte address block. */
	uint8_t rest_bits = prefix % 8;
	if (rest_bits > 0) {
		uint8_t rest1 = addr1[full_bytes] >> (8 - rest_bits);
		uint8_t rest2 = addr2[full_bytes] >> (8 - rest_bits);
		if (rest1 != rest2) {
			return false;
		}
	}
    int port(struct sockaddr_storage *addr)
    {
        if (AF_INET == addr->ss_family)
        {
            return ntohs(ipv4_addr(addr)->sin_port);
        }
        else if (AF_INET6 == addr->ss_family)
        {
            return ntohs(ipv6_addr(addr)->sin6_port);
        }

        return 0;
    }
    const char *inet_ntop(struct sockaddr_storage *addr)
    {
        if (AF_INET == addr->ss_family)
        {
            return ::inet_ntop(AF_INET, &(ipv4_addr(addr)->sin_addr), m_buffer, sizeof(m_buffer));
        }
        else if (AF_INET6 == addr->ss_family)
        {
            return ::inet_ntop(AF_INET6, &(ipv6_addr(addr)->sin6_addr), m_buffer, sizeof(m_buffer));
        }

        return NULL;
    }