Ejemplo n.º 1
0
static int cb(
    struct nfq_q_handle *q,
    struct nfgenmsg *nfmsg,
    struct nfq_data *nfa,
    void *arg
) {
    int id = 0;
    struct nfqnl_msg_packet_hdr *ph;
    
    size_t packet_length;
    unsigned char   *packet_data;
    struct pkt_buff *packet;
    struct iphdr    *ip_header;
    struct tcphdr   *tcp_header;
    
    ph = nfq_get_msg_packet_hdr(nfa);
    if (ph) {
        id = ntohl(ph->packet_id);
    }
    
    packet_length = nfq_get_payload(nfa, &packet_data);
    packet = pktb_alloc(AF_INET, packet_data, packet_length, 4096);
    
    ip_header = nfq_ip_get_hdr(packet);
    nfq_ip_set_transport_header(packet, ip_header);
    tcp_header = nfq_tcp_get_hdr(packet);
    
    if (ip_header) {
        struct in_addr *target;
        if (src_or_dst == src) {
            target = (struct in_addr *) &ip_header->saddr;
        } else if (src_or_dst == dst) {
            target = (struct in_addr *) &ip_header->daddr;
        }
        inet_aton(target_ip_address, target);
        
        nfq_ip_set_checksum(ip_header);
        nfq_tcp_compute_checksum_ipv4(tcp_header, ip_header);
        memcpy(packet_data, pktb_data(packet), packet_length);
    }
    
    pktb_free(packet);
    
    return nfq_set_verdict(q, id, NF_ACCEPT, packet_length, packet_data);
}
Ejemplo n.º 2
0
static int
cthelper_process_packet(const uint8_t *pkt, uint32_t pktlen,
			struct ctd_helper *h, int proto, uint16_t port,
			int type)
{
	struct pkt_buff *pktb;
	struct cthelper_proto_l2l3_helper *l3h;
	struct cthelper_proto_l4_helper *l4h;
	unsigned int l3hdr_len, l4protonum;
	struct nf_ct_entry *ct;
	int ret, this_proto;
	uint32_t dataoff, ctinfo = 0;

	l3h = cthelper_proto_l2l3_helper_find(pkt, &l4protonum, &l3hdr_len);
	if (l3h == NULL) {
		fprintf(stderr, "Unsupported layer 3 protocol, skipping.\n");
		return -1;
	}

	l4h = cthelper_proto_l4_helper_find(pkt, l4protonum);
	if (l4h == NULL) {
		fprintf(stderr, "Unsupported layer 4 protocol, skipping.\n");
		return -1;
	}
	/* get layer 3 header. */
	pkt += l3h->l2hdr_len;
	pktlen -= l3h->l2hdr_len;

	/* skip packet with mismatching protocol */
	this_proto = l3h->l4pkt_proto(pkt);
	if (this_proto != proto) {
		cthelper_test_stats.pkt_mismatch_proto++;
		return 0;
	}

	/* Look for the fake conntrack. */
	ct = ct_find(pkt, l3hdr_len, l3h, l4h, &ctinfo);
	if (ct == NULL) {
		/* It doesn't exist any, create one. */
		ct = ct_alloc(pkt, l3hdr_len, l3h, l4h);
		if (ct == NULL) {
			fprintf(stderr, "Not enough memory\n");
			return -1;
		}
		ct_add(ct);
		ctinfo += IP_CT_NEW;
	} else
		ctinfo += IP_CT_ESTABLISHED;

	/* skip packets with mismatching ports */
	if (!l4h->l4ct_cmp_port(ct->myct->ct, ntohs(port))) {
		cthelper_test_stats.pkt_mismatch_port++;
		return -1;
	}

	/*
	 * FIXME: reminder, implement this below in the kernel for cthelper.
	 */

	/* This packet contains no data, skip it. */
/*	if (l4h->l4pkt_no_data && l4h->l4pkt_no_data(pkt + l3hdr_len)) {
		NFG_DEBUG("skipping packet with no data\n");
		continue;
	} */

	/* Create the fake network buffer. */
	pktb = pktb_alloc(AF_INET, pkt, pktlen, 128);
	if (pktb == NULL) {
		fprintf(stderr, "Not enough memory\n");
		return -1;
	}

	dataoff = l3h->l3pkt_hdr_len(pkt);
	if (dataoff > pktb_len(pktb)) {
		fprintf(stderr, "wrong layer 3 offset: %d > %d\n",
			dataoff, pktb_len(pktb));
		return -1;
	}

	/* tweak to run DNAT mangling code using the same PCAP file. */
	if (type == TEST_DNAT) {
		struct nf_conntrack *tmp = ct->myct->ct;
		/* as long as this is tested, who cares the destination IP? */
		in_addr_t addr = inet_addr("1.1.1.1");

		/* clone the real conntrack, to add DNAT information */
		ct->myct->ct = nfct_clone(ct->myct->ct);
		/* set fake DNAT information */
		nfct_set_attr_u32(ct->myct->ct, ATTR_STATUS, IPS_DST_NAT);
		nfct_set_attr_u32(ct->myct->ct, ATTR_ORIG_IPV4_DST, addr);
		/* pass it to helper */
		ret = h->cb(pktb, dataoff, ct->myct, ctinfo);
		/* restore real conntrack */
		nfct_destroy(ct->myct->ct);
		ct->myct->ct = tmp;

		if (pktb_mangled(pktb)) {
			int i;
			uint8_t *data = pktb_network_header(pktb);

			printf("\e[1;31mmangled content: ", pktb_len(pktb));

			for (i=0; i < pktb_len(pktb); i++)
				printf("%c", data[i]);

			printf("\e[0m\n");
		}
	} else