Beispiel #1
0
int cb (struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
    struct nfq_data *nfa, void *data)
{
  int id;
  int len;
  int hlen;
  char *pkt;
  struct nfqnl_msg_packet_hdr *ph;
  struct nfqnl_msg_packet_hw *hwph;
  struct timeval tv;

  tv.tv_sec = 0; // init

  if ((ph = nfq_get_msg_packet_hdr(nfa)))
    id = ntohl(ph->packet_id);
  else
    id = 0;

  if ((hwph = nfq_get_packet_hw(nfa)))
    hlen = ntohs(hwph->hw_addrlen);
  else
    hlen = 0;

  /* hole payload ... falls es nicht klappt ... Paket durchreichen */
  if ((len = nfq_get_payload (nfa, (char **) &pkt)) < 0)
    return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);

  nfq_get_timestamp(nfa,&tv);
  return nfq_set_verdict(qh, id, myworker (data, pkt, len,&tv) ? NF_DROP :
                          NF_ACCEPT, 0, NULL);
}
Beispiel #2
0
static inline int SetPktHdr (
    NfqImpl* impl,
    struct nfq_data* nfad,
    DAQ_PktHdr_t* hdr,
    uint8_t** pkt
) {
    int len = nfq_get_payload(nfad, (char**)pkt);

    if ( len <= 0 )
        return -1;

    hdr->caplen = ((uint32_t)len <= impl->snaplen) ? (uint32_t)len : impl->snaplen;
    hdr->pktlen = len;
    hdr->flags = 0;
    hdr->address_space_id = 0;

    // if nfq fails to provide a timestamp, we fall back on tod
    if ( nfq_get_timestamp(nfad, &hdr->ts) )
        gettimeofday(&hdr->ts, NULL);

    hdr->ingress_index = nfq_get_physindev(nfad);
    hdr->egress_index = -1;
    hdr->ingress_group = -1;
    hdr->egress_group = -1;

    return 0;
}
Beispiel #3
0
static inline int SetPktHdr (
    NfqImpl* impl,
    struct nfq_data* nfad,
    DAQ_PktHdr_t* hdr,
    uint8_t** pkt
) {
    int len = nfq_get_payload(nfad, (char**)pkt);

    if ( len <= 0 )
        return -1;

    hdr->caplen = ((uint32_t)len <= impl->snaplen) ? (uint32_t)len : impl->snaplen;
    hdr->pktlen = len;
    hdr->flags = 0;

    nfq_get_timestamp(nfad, &hdr->ts);
    hdr->device_index = nfq_get_physindev(nfad);

    return 0;
}
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
	      struct nfq_data *nfa, void *data)
{
	int id = 0;
	struct nfqnl_msg_packet_hdr *ph;
	struct timeval tv, now;
	long long time_passed;
	long long wait_time;

	ph = nfq_get_msg_packet_hdr(nfa);
	if (ph)
		id = ntohl(ph->packet_id);

	/* figure out how long to delay this single packet */
	nfq_get_timestamp(nfa, &tv);
	gettimeofday(&now, NULL);
	time_passed = diff_time(&tv, &now);

	/* see how much more we want to wait */
	wait_time = sleep_for_mode - time_passed;
	if (wait_time < 0)
	    goto accept;

        /* for multi second intervals we need to do this */
	while (wait_time > 0) {
		long long sleep = wait_time;
		if (sleep > WAIT_MAX)
		    sleep = WAIT_MAX;

		usleep(sleep);
		wait_time -= WAIT_MAX;
	}

accept:
	return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}
Beispiel #5
0
int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data)
{
    struct nfq_data *tb = (struct nfq_data *)data;
    int ret;
    char *pktdata;
    struct nfqnl_msg_packet_hdr *ph;

    ph = nfq_get_msg_packet_hdr(tb);
    if (ph != NULL) {
        p->nfq_v.id = ntohl(ph->packet_id);
        //p->nfq_v.hw_protocol = ntohs(p->nfq_v.ph->hw_protocol);
        p->nfq_v.hw_protocol = ph->hw_protocol;
    }
    p->nfq_v.mark = nfq_get_nfmark(tb);
    if (nfq_config.mode == NFQ_REPEAT_MODE) {
        if ((nfq_config.mark & nfq_config.mask) ==
                (p->nfq_v.mark & nfq_config.mask)) {
            int iter = 0;
            if (already_seen_warning < MAX_ALREADY_TREATED)
                SCLogInfo("Packet seems already treated by suricata");
            already_seen_warning++;
            do {
                ret = nfq_set_verdict(qh, p->nfq_v.id, NF_ACCEPT, 0, NULL);
            } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME));
            if (ret < 0) {
                SCLogWarning(SC_ERR_NFQ_SET_VERDICT,
                             "nfq_set_verdict of %p failed %" PRId32 "",
                             p, ret);
            }
            return -1 ;
        }
    }
    p->nfq_v.ifi  = nfq_get_indev(tb);
    p->nfq_v.ifo  = nfq_get_outdev(tb);

#ifdef NFQ_GET_PAYLOAD_SIGNED
    ret = nfq_get_payload(tb, &pktdata);
#else
    ret = nfq_get_payload(tb, (unsigned char **) &pktdata);
#endif /* NFQ_GET_PAYLOAD_SIGNED */
    if (ret > 0) {
        /* nfq_get_payload returns a pointer to a part of memory
         * that is not preserved over the lifetime of our packet.
         * So we need to copy it. */
        if (ret > 65536) {
            /* Will not be able to copy data ! Set length to 0
             * to trigger an error in packet decoding.
             * This is unlikely to happen */
            SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "NFQ sent too big packet");
            SET_PKT_LEN(p, 0);
        } else {
            PacketCopyData(p, (uint8_t *)pktdata, ret);
        }
    } else if (ret ==  -1) {
        /* unable to get pointer to data, ensure packet length is zero.
         * This will trigger an error in packet decoding */
        SET_PKT_LEN(p, 0);
    }

    ret = nfq_get_timestamp(tb, &p->ts);
    if (ret != 0) {
        memset (&p->ts, 0, sizeof(struct timeval));
        gettimeofday(&p->ts, NULL);
    }

    p->datalink = DLT_RAW;
    return 0;
}
Beispiel #6
0
/**
 * \brief Callback called by NetFilter when a packet with target QUEUE is matched.
 *
 * For TCP packet with flags different than SYN, just send it to NuAuth and
 * accept it.
 *
 * For other packet: First of all, fill a structure ::packet_idl (identifier,
 * timestamp, ...). Try to add the new packet to ::packets_list (fails if the
 * list is full). Ask an authentication to NuAuth using auth_request_send(),
 * If the packet can't be sended, remove it from the list.
 *
 * \return If an error occurs, returns 0, else returns 1.
 */
static int treat_packet(struct nfq_handle *qh, struct nfgenmsg *nfmsg,
			struct nfq_data *nfa, void *data)
{
	packet_idl *current;
	struct queued_pckt q_pckt;
	struct nfqnl_msg_packet_hdr *ph;
	struct timeval timestamp;
	int ret;
#ifdef HAVE_NFQ_INDEV_NAME
	struct nlif_handle *nlif_handle = (struct nlif_handle *) data;
#endif

	debug_log_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_VERBOSE_DEBUG,
			 "(*) New packet");

	q_pckt.payload_len = nfq_get_payload(nfa, &(q_pckt.payload));
	if (q_pckt.payload_len == -1) {
		log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_INFO,
				"Unable to get payload");
		return 0;
	}

	q_pckt.mark = nfq_get_nfmark(nfa);

#ifdef HAVE_NFQ_INDEV_NAME
	if (!get_interface_information(nlif_handle, &q_pckt, nfa)) {
		log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_INFO,
				"Can not get interfaces information for message");
		return 0;
	}
#else
	snprintf(q_pckt.indev, sizeof(q_pckt.indev), "*");
	snprintf(q_pckt.physindev, sizeof(q_pckt.physindev), "*");
	snprintf(q_pckt.outdev, sizeof(q_pckt.outdev), "*");
	snprintf(q_pckt.physoutdev, sizeof(q_pckt.physoutdev), "*");
#endif

	ret = nfq_get_timestamp(nfa, &timestamp);
	if (ret == 0) {
		q_pckt.timestamp = timestamp.tv_sec;
	} else {
		q_pckt.timestamp = time(NULL);
	}

	if (look_for_tcp_flags
	    ((unsigned char *) q_pckt.payload, q_pckt.payload_len)) {
		ph = nfq_get_msg_packet_hdr(nfa);
		if (ph) {
			q_pckt.packet_id = ntohl(ph->packet_id);
			auth_request_send(AUTH_CONTROL, &q_pckt);
			IPQ_SET_VERDICT(q_pckt.packet_id, NF_ACCEPT);
			RETURN_NO_LOG 1;
		} else {
			log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_VERBOSE_DEBUG,
					"Can not get the packet headers");
			return 0;
		}
	}
	current = calloc(1, sizeof(packet_idl));
	current->nfmark = q_pckt.mark;
	current->timestamp = q_pckt.timestamp ;
	current->id = 0;
	if (current == NULL) {
		log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_MESSAGE,
				"Can not allocate packet_id");
		return 0;
	}
#ifdef PERF_DISPLAY_ENABLE
	gettimeofday(&(current->arrival_time), NULL);
#endif
	/* Get unique identifier of packet in queue */
	ph = nfq_get_msg_packet_hdr(nfa);
	if (ph) {
		current->id = ntohl(ph->packet_id);
	} else {
		free(current);
		log_area_printf(DEBUG_AREA_PACKET, DEBUG_LEVEL_INFO,
				"Can not get id for message");
		return 0;
	}

	/* Try to add the packet to the list */
	ret = padd(current);
	q_pckt.packet_id = current->id;

	if (ret == 0) {
		/* send an auth request packet */
		if (!auth_request_send(AUTH_REQUEST, &q_pckt)) {
			int sandf = 0;
			/* send failure dropping packet */
			IPQ_SET_VERDICT(q_pckt.packet_id, NF_DROP);
			/* we fail to send the packet so we free packet related to current */
			/* search and destroy packet by packet_id */
			sandf = psearch_and_destroy(q_pckt.packet_id,
						&(q_pckt.mark));

			if (!sandf) {
				log_area_printf(DEBUG_AREA_MAIN,
						DEBUG_LEVEL_WARNING,
						"Packet could not be removed: %u",
						q_pckt.packet_id);
			}
		}
	}
	return 1;
}
Beispiel #7
0
static int packet_input(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
              		struct nfq_data *nfa, void *data)
{
	divert_cb cb = (divert_cb) data;
	char *d;
	int len;
	int rc;
	unsigned int id;
	struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(nfa);
	struct ip *ip;
	int flags = 0;
	struct timeval tv;
	int rlen = 0;
	void *rdata = NULL;

	len = nfq_get_payload(nfa, &d);
	if (len < 0)
		err(1, "nfq_get_payload()");

	if (nfq_get_indev(nfa))
		flags |= DF_IN;

	if (nfq_get_timestamp(nfa, &tv) == 0)
		set_time(&tv);
	else {
		static int warn = 0;

		if (!warn && !_conf.cf_disable_timers)
			xprintf(XP_ALWAYS, "No timestamp provided in packet"
			                   " - expect low performance due to"
					   " calls to gettimeofday\n");
		warn = 1;	
	}

	rc = cb(d, len, flags);

	id = ntohl(ph->packet_id);

	switch (rc) {
	case DIVERT_MODIFY:
		ip    = (struct ip*) d;
		rlen  = ntohs(ip->ip_len);
		rdata = d;
		/* fallthrough */
	case DIVERT_ACCEPT:
		if (_mark) {
			unsigned int mark = 0;

			assert((mark & _mark) == 0);
			nfq_set_verdict_mark(qh, id, NF_REPEAT,
					     htonl(_mark | mark),
					     rlen, rdata);
		} else
			nfq_set_verdict(qh, id, NF_ACCEPT, rlen, rdata);
		break;

	case DIVERT_DROP:
		nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
		break;

	default:
		printf("Unknown verdict %d\n", rc);
		abort();
	}

	return 0;
}