示例#1
0
int init_netlink()
{
  h = ipq_create_handle(0, PF_INET);
   if(h == NULL){
     printf("%s\n", ipq_errstr());
     return 0;
   }
   unsigned char mode = IPQ_COPY_PACKET;
   int range = sizeof(buf);
   int ret = ipq_set_mode(h, mode, range);
}
void ipq_perror(const char *s)
{
	if (s)
		fputs(s, stderr);
	else
		fputs("ERROR", stderr);
	if (ipq_errno)
		fprintf(stderr, ": %s", ipq_errstr());
	if (errno)
		fprintf(stderr, ": %s", strerror(errno));
	fputc('\n', stderr);
}
示例#3
0
文件: testApi.c 项目: loler-zuan/ndpi
static int init_netlink()
{
//printf("in netlink\n");
  h = ipq_create_handle(0, PF_INET);
   if(h == NULL){
     printf("%s\n", ipq_errstr());
     return 0;
   }
   //printf("ipq_creat_handle success!\n");
   unsigned char mode = IPQ_COPY_PACKET;
   int range = sizeof(buf);
   int ret = ipq_set_mode(h, mode, range);
   //printf("ipq_set_mode: send bytes =%d, range=%d\n", ret,range);
   signal(SIGINT, sigproc);
//printf("out netlink\n");
}
int main(void)
{
    int status;
    unsigned char buf[BUFSIZE];

    packet_list_t *element;
    ipq_packet_msg_t *pmsg;

    delay_init();

    pthread_t thread;
    pthread_create(&thread, NULL, _pkg_reinject, NULL);

    do {
        /* read packets from buffer */
        status = ipq_read(h, buf, BUFSIZE, 0);
        if (status > 0) {
            switch (ipq_message_type(buf)) {
            case NLMSG_ERROR:
                printf("Received error message %d\n", ipq_get_msgerr(buf));
                break;
            case IPQM_PACKET: {
                /* adding packet to pool */
                ipq_packet_msg_t *m = ipq_get_packet(buf);
                pmsg = (ipq_packet_msg_t*)malloc(sizeof(ipq_packet_msg_t) + m->data_len);
                memcpy(pmsg, m, sizeof(ipq_packet_msg_t) + m->data_len);

                element = (packet_list_t *)malloc(sizeof(packet_list_t));
                element->pmsg = pmsg;
                list_add_tail(&(element->list), &pkg_list);
                count_packet++;
                break;
            }
            default:
                printf("Unknown message type!\n");
                break;
            }
        }
        else
            printf("ipq_read error return: %s\n",ipq_errstr());
    } while (1);
    return 0;
}
示例#5
0
文件: daq_ipq.c 项目: remfalc/vyt-daq
static int ipq_daq_acquire (
    void* handle, int cnt, DAQ_Analysis_Func_t callback, void* user)
{
    IpqImpl* impl = (IpqImpl*)handle;

    int n = 0;
    DAQ_PktHdr_t hdr;

    // If cnt is <= 0, don't limit the packets acquired.  However,
    // impl->count = 0 has a special meaning, so interpret accordingly.
    impl->count = (cnt == 0) ? -1 : cnt;
    hdr.device_index = 0;
    hdr.flags = 0;

    while ( impl->count < 0 || n < impl->count )
    {
        int ipqt, status = ipq_read(
            impl->ipqh, impl->buf, MSG_BUF_SIZE, impl->timeout);

        if ( status <= 0 )
        {
            if ( status < 0 )
            {
                DPE(impl->error, "%s: ipq_read=%d error %s",
                    __FUNCTION__, status, ipq_errstr());
                return DAQ_ERROR;
            }
            return 0;
        }

        ipqt = ipq_message_type(impl->buf);

        if ( ipqt == IPQM_PACKET )
        {
            DAQ_Verdict verdict;
            ipq_packet_msg_t* ipqm = ipq_get_packet(impl->buf);
            SetPktHdr(impl, ipqm, &hdr);
            impl->stats.hw_packets_received++;

            if (
                impl->fcode.bf_insns &&
                sfbpf_filter(impl->fcode.bf_insns, ipqm->payload,
                    hdr.caplen, hdr.caplen) == 0
            ) {
                verdict = DAQ_VERDICT_PASS;
                impl->stats.packets_filtered++;
            }
            else
            {
                verdict = callback(user, &hdr, (uint8_t*)ipqm->payload);
                impl->stats.verdicts[verdict]++;
                impl->stats.packets_received++;
            }
            if ( impl->passive ) verdict = DAQ_VERDICT_PASS;

            switch ( verdict ) {
            case DAQ_VERDICT_BLOCK:
            case DAQ_VERDICT_BLACKLIST:
                status = ipq_set_verdict(
                    impl->ipqh, ipqm->packet_id, NF_DROP, 0, NULL);
                break;

            case DAQ_VERDICT_REPLACE:
                status = ipq_set_verdict(
                    impl->ipqh, ipqm->packet_id, NF_ACCEPT,
                    hdr.pktlen, ipqm->payload);
                break;

            case DAQ_VERDICT_PASS:
            case DAQ_VERDICT_WHITELIST:
            case DAQ_VERDICT_IGNORE:
            default:
                status = ipq_set_verdict(
                    impl->ipqh, ipqm->packet_id, NF_ACCEPT, 0, NULL);
                break;
            }
            if ( status < 0 )
            {
                DPE(impl->error, "%s: ipq_set_verdict=%d error %s",
                    __FUNCTION__, status, ipq_errstr());
                return DAQ_ERROR;
            }
            n++;
        }
        else
        {
            // NLMSG_ERROR is supposed to be the only other valid type
            status = ipq_get_msgerr(impl->buf);
            DPE(impl->error, "%s: ipq_message_type=%d error=%d %s",
                __FUNCTION__, ipqt, status, ipq_errstr());
            // ipq_message_type=2 error=1 Timeout
            // keep looping upon timeout or other errors
        }
    }
    return 0;
}
示例#6
0
文件: daq_ipq.c 项目: remfalc/vyt-daq
static int ipq_daq_initialize (
    const DAQ_Config_t* cfg, void** handle, char* errBuf, size_t errMax)
{
    int status;

    if(cfg->name && *(cfg->name))
    {
        snprintf(errBuf, errMax, "The ipq DAQ module does not support interface or readback mode!");
        return DAQ_ERROR_INVAL;
    }

    IpqImpl* impl = calloc(1, sizeof(*impl));

    if ( !impl )
    {
        snprintf(errBuf, errMax, "%s: failed to allocate the ipq context!",
            __FUNCTION__);
        return DAQ_ERROR_NOMEM;
    }

    if ( ipq_daq_get_setup(impl, cfg, errBuf, errMax) != DAQ_SUCCESS )
    {
        ipq_daq_shutdown(impl);
        return DAQ_ERROR;
    }

    impl->buf = malloc(MSG_BUF_SIZE);

    if ( !impl->buf )
    {
        snprintf(errBuf, errMax, "%s: failed to allocate the ipq buffer!",
            __FUNCTION__);
        ipq_daq_shutdown(impl);
        return DAQ_ERROR_NOMEM;
    }

    // remember to also link in, eg:
    //    iptables -A OUTPUT -p icmp -j QUEUE
    impl->ipqh = ipq_create_handle(0, impl->proto);

    if ( !impl->ipqh )
    {
        snprintf(errBuf, errMax, "%s: ipq_create_handle error %s\n",
            __FUNCTION__, ipq_errstr());
        ipq_daq_shutdown(impl);
        return DAQ_ERROR;
    }

    // copy both packet metadata and packet payload
    // paket payload is limited to IP_MAXPACKET
    status = ipq_set_mode(impl->ipqh, IPQ_COPY_PACKET, IP_MAXPACKET);

    if ( status < 0 )
    {
        snprintf(errBuf, errMax, "%s: ipq_set_mode error %s\n",
            __FUNCTION__, ipq_errstr());
        ipq_daq_shutdown(impl);
        return DAQ_ERROR;
    }
    if ( impl->device && strcasecmp(impl->device, "ip") )
    {
        impl->link = eth_open(impl->device);

        if ( !impl->link )
        {
            snprintf(errBuf, errMax, "%s: can't open %s!\n",
                __FUNCTION__, impl->device);
            ipq_daq_shutdown(impl);
            return DAQ_ERROR;
        }
    }
    else
    {
        impl->net = ip_open();

        if ( !impl->net )
        {
            snprintf(errBuf, errMax, "%s: can't open ip!\n", __FUNCTION__);
            ipq_daq_shutdown(impl);
            return DAQ_ERROR;
        }
    }
    impl->state = DAQ_STATE_INITIALIZED;

    *handle = impl;
    return DAQ_SUCCESS;
}
示例#7
0
static void packet_input(int fd)
#endif
{
    rt_table_t *fwd_rt, *rev_rt, *next_hop_rt = NULL;
    struct in_addr dest_addr, src_addr;
    u_int8_t rreq_flags = 0;
    unsigned int ifindex;
    struct ip_data *ipd = NULL;
    int pkt_flags = 0;

#ifdef NS_PORT
    ifindex = NS_IFINDEX;	/* Always use ns interface */
    fwd_rt = NULL;		/* For broadcast we provide no next hop */
    ipd = NULL;			/* No ICMP messaging */

    struct hdr_cmn *ch = HDR_CMN(p);
    struct hdr_ip *ih = HDR_IP(p);

    src_addr.s_addr = ih->saddr();
    dest_addr.s_addr = ih->daddr();

    /* If this is a TCP packet and we don't have a route, we should
       set the gratuituos flag in the RREQ. */
    if (ch->ptype() == PT_TCP) {
	rreq_flags |= RREQ_GRATUITOUS;
    }
#else
    int status;
    char buf[sizeof(struct nlmsghdr)+sizeof(ipq_packet_msg_t)+BUFSIZE];
    char *dev_name;
    ipq_packet_msg_t *pkt;
    struct iphdr *ip;
    struct udphdr *udp;
    struct icmphdr *icmp = NULL;

    status =  ipq_read(h, buf, sizeof(buf), -1);
    
    if (status < 0) {
	DEBUG(LOG_DEBUG, 0, "%s", ipq_errstr());
	ipq_perror(NULL);
	return;
    }

    if (ipq_message_type(buf) == NLMSG_ERROR) {
	fprintf(stderr,
		"ERROR packet_input: Check that the ip_queue.o module is loaded.\n");
	die(h);
    }

    pkt = ipq_get_packet(buf);

#ifdef DEBUG_PACKET
    DEBUG(LOG_DEBUG, 0, "Protocol %u indev=%s outdev=%s\n",
	  pkt->hw_protocol, pkt->indev_name, pkt->outdev_name);
#endif

    if (pkt->hook == 0)
	dev_name = pkt->indev_name;
    else if (pkt->hook == 3)
	dev_name = pkt->outdev_name;
    else
	dev_name = NULL;

    /* We know from kaodv.c that this is an IP packet */
    ip = (struct iphdr *) pkt->payload;

    dest_addr.s_addr = ip->daddr;
    src_addr.s_addr = ip->saddr;

    switch (ip->protocol) {
	/* Don't process AODV control packets (UDP on port 654). They
	   are accounted for on the aodv socket */
    case IPPROTO_UDP:
	udp = (struct udphdr *) ((char *) ip + (ip->ihl << 2));
	if (ntohs(udp->dest) == AODV_PORT || ntohs(udp->source) == AODV_PORT)
	    goto accept;
	break;
	/* If this is a TCP packet and we don't have a route, we should
	   set the gratuituos flag in the RREQ. */
    case IPPROTO_TCP:
	rreq_flags |= RREQ_GRATUITOUS;
	break;
	/* We set the gratuitous flag also on ICMP ECHO requests, since
	   the destination will also need a route back for the reply... */
    case IPPROTO_ICMP:
	icmp = (struct icmphdr *) ((char *) ip + (ip->ihl << 2));
	if (icmp->type == ICMP_ECHO)
	    rreq_flags |= RREQ_GRATUITOUS;
#ifdef DEBUG_PACKET
	DEBUG(LOG_INFO, 0, "setting G flag for RREQ to %s",
	      ip_to_str(dest_addr));
#endif

	break;
#ifdef CONFIG_GATEWAY
    case IPPROTO_MIPE:
	if (internet_gw_mode) {
	    
	    ip = ip_pkt_decapsulate(ip);

	    if (ip == NULL) {
	      DEBUG(LOG_ERR, 0, "Decapsulation failed...");
	      exit(-1);
	    }
	    pkt_flags |= PKT_DEC;
	}
	break;
#endif /* CONFIG_GATEWAY */
    }

#ifdef DEBUG_PACKET
    DEBUG(LOG_INFO, 0, "pkt to %s", ip_to_str(dest_addr));
#endif

    if (dev_name) {
	ifindex = name2index(dev_name);
	if (ifindex < 0) {
	    DEBUG(LOG_ERR, 0, "name2index error!");
	    return;
	}
    } else
	ifindex = 0;
#endif				/* NS_PORT */

    /* If the packet is not interesting we just let it go through... */
    if (dest_addr.s_addr == AODV_BROADCAST ||
	dest_addr.s_addr == DEV_IFINDEX(ifindex).broadcast.s_addr) {
#ifdef NS_PORT
	/* Limit Non AODV broadcast packets (Rolf Winter
	 * <[email protected]). */
	ih->ttl() = ih->ttl() - 1;                
       
	if(ih->ttl() < 1)        
	    Packet::free(p);                
	else
	    sendPacket(p, dest_addr, 0.0);
	return;
#else
	goto accept;
#endif
    }
    
    /* Find the entry of the neighboring node and the destination  (if any). */
    rev_rt = rt_table_find(src_addr);
    fwd_rt = rt_table_find(dest_addr);

#ifdef CONFIG_GATEWAY
    /* Check if we have a route and it is an Internet destination (Should be
     * encapsulated and routed through the gateway). */
    if (fwd_rt && (fwd_rt->state == VALID) && 
	(fwd_rt->flags & RT_INET_DEST)) {
	/* The destination should be relayed through the IG */

	rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);
#ifdef NS_PORT
	p = pkt_encapsulate(p, fwd_rt->next_hop);

	if (p == NULL) {
	    DEBUG(LOG_ERR, 0, "IP Encapsulation failed!");
	   return;	    
	}
	/* Update pointers to headers */
	ch = HDR_CMN(p);
	ih = HDR_IP(p);
#else
	ip = ip_pkt_encapsulate(ip, fwd_rt->next_hop, BUFSIZE);

	if (ip == NULL) {
	    DEBUG(LOG_ERR, 0, "Minimal IP Encapsulation failed!");
	    exit(-1);	    
	}
#endif
	dest_addr = fwd_rt->next_hop;
	fwd_rt = rt_table_find(dest_addr);
	pkt_flags |= PKT_ENC;
    }
#endif /* CONFIG_GATEWAY */

    /* UPDATE TIMERS on active forward and reverse routes...  */

    /* When forwarding a packet, we update the lifetime of the
       destination's routing table entry, as well as the entry for the
       next hop neighbor (if not the same). AODV draft 10, section
       6.2. */
    if (fwd_rt && fwd_rt->state == VALID &&
	dest_addr.s_addr != DEV_IFINDEX(ifindex).ipaddr.s_addr) {

	rt_table_update_timeout(fwd_rt, ACTIVE_ROUTE_TIMEOUT);

	next_hop_rt = rt_table_find(fwd_rt->next_hop);
	
	if (next_hop_rt && next_hop_rt->state == VALID && 
	    next_hop_rt->dest_addr.s_addr != fwd_rt->dest_addr.s_addr)
	    rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);

    }
    /* Also update the reverse route and reverse next hop along the
       path back, since routes between originators and the destination
       are expected to be symmetric. */
    if (rev_rt && rev_rt->state == VALID) {
	
	rt_table_update_timeout(rev_rt, ACTIVE_ROUTE_TIMEOUT);

	next_hop_rt = rt_table_find(rev_rt->next_hop);

	if (next_hop_rt && next_hop_rt->state == VALID &&
	    rev_rt && next_hop_rt->dest_addr.s_addr != rev_rt->dest_addr.s_addr)
	    rt_table_update_timeout(next_hop_rt, ACTIVE_ROUTE_TIMEOUT);

	/* Update HELLO timer of next hop neighbor if active */   
	if (!llfeedback && next_hop_rt->hello_timer.used) {
	    struct timeval now;
	
	    gettimeofday(&now, NULL);
	    hello_update_timeout(next_hop_rt, &now, 
				 ALLOWED_HELLO_LOSS * HELLO_INTERVAL);
	}
    }

    /* OK, the timeouts have been updated. Now see if either: 1. The
       packet is for this node -> ACCEPT. 2. The packet is not for this
       node -> Send RERR (someone want's this node to forward packets
       although there is no route) or Send RREQ. */

    /* If the packet is destined for this node, then just accept it. */
    if (memcmp(&dest_addr, &DEV_IFINDEX(ifindex).ipaddr, 
	       sizeof(struct in_addr)) == 0) {

#ifdef NS_PORT
	ch->size() -= IP_HDR_LEN;    // cut off IP header size 4/7/99 -dam
	target_->recv(p, (Handler*)0);
	p = 0;
	return;
#else
	goto accept;
#endif
    }
    if (!fwd_rt || fwd_rt->state == INVALID ||
	(fwd_rt->hcnt == 1 && (fwd_rt->flags & RT_UNIDIR))) {

	/* Check if the route is marked for repair or is INVALID. In
	 * that case, do a route discovery. */
	if (fwd_rt && (fwd_rt->flags & RT_REPAIR))
	    goto route_discovery;

	/* If a packet is received on the NF_IP_PRE_ROUTING hook,
	   i.e. inbound on the interface and we don't have a route to
	   the destination, we should send an RERR to the source and
	   then drop the package... */
	/* NF_IP_PRE_ROUTING = 0 */
#ifdef NS_PORT
#define PACKET_IS_INBOUND ch->direction() == hdr_cmn::UP
#else
#define PACKET_IS_INBOUND pkt->hook == 0
#endif

	if (PACKET_IS_INBOUND) {

	    struct in_addr rerr_dest;
	    RERR *rerr;
#ifdef NS_PORT
	    struct in_addr nh;
	    nh.s_addr = ch->prev_hop_;
	    
	    DEBUG(LOG_DEBUG, 0,
		  "No route, src=%s dest=%s prev_hop=%s - DROPPING!",
		  ip_to_str(src_addr), ip_to_str(dest_addr),
		  ip_to_str(nh));
#endif
	    if (fwd_rt) {
		rerr = rerr_create(0, fwd_rt->dest_addr,
				   fwd_rt->dest_seqno);

		rt_table_update_timeout(fwd_rt, DELETE_PERIOD);
	    } else
		rerr = rerr_create(0, dest_addr, 0);
	    
	    DEBUG(LOG_DEBUG, 0, "Sending RERR to prev hop %s for unknown dest %s", ip_to_str(src_addr), ip_to_str(dest_addr));
	    
	    /* Unicast the RERR to the source of the data transmission
	     * if possible, otherwise we broadcast it. */
	    
	    if (rev_rt && rev_rt->state == VALID)
		rerr_dest = rev_rt->next_hop;
	    else
		rerr_dest.s_addr = AODV_BROADCAST;

	    aodv_socket_send((AODV_msg *) rerr, rerr_dest,
			     RERR_CALC_SIZE(rerr), 1, &DEV_IFINDEX(ifindex));

	    if (wait_on_reboot) {
		DEBUG(LOG_DEBUG, 0, "Wait on reboot timer reset.");
		timer_set_timeout(&worb_timer, DELETE_PERIOD);
	    }
#ifdef NS_PORT
	    /* DEBUG(LOG_DEBUG, 0, "Dropping pkt uid=%d", ch->uid()); */
	    drop(p, DROP_RTR_NO_ROUTE);
#else
	    status = ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);
	    
	    if (status < 0)
		die(h);
#endif
	    return;
	}

      route_discovery:
	/* Buffer packets... Packets are queued by the ip_queue.o
	   module already. We only need to save the handle id, and
	   return the proper verdict when we know what to do... */

#ifdef NS_PORT
	packet_queue_add(p, dest_addr);
#else
	packet_queue_add(pkt->packet_id, dest_addr, ip);
	
#ifdef CONFIG_GATEWAY
	/* In gateway mode we handle packets in userspace */
	ipq_set_verdict(h, pkt->packet_id, NF_DROP, 0, NULL);
#endif
	/* Already seeking the destination? Then do not allocate any
	   memory or generate a RREQ. */
	if (seek_list_find(dest_addr))
	    return;

	/* If the request is generated locally by an application, we save
	   the IP header + 64 bits of data for sending an ICMP Destination
	   Host Unreachable in case we don't find a route... */
	if (src_addr.s_addr == DEV_IFINDEX(ifindex).ipaddr.s_addr && ip &&
	    pkt->data_len >= (ip->ihl << 2) + 8) {
	    ipd = (struct ip_data *) malloc(sizeof(struct ip_data));
	    if (ipd == NULL) {
		perror("Malloc for IP data failed!");
		exit(-1);
	    }
	    /* IP header + 64 bits data (8 bytes) */
	    ipd->len = (ip->ihl << 2) + 8;
	    memcpy(ipd->data, ip, ipd->len);
	} else
	    ipd = NULL;
#endif
	if (fwd_rt && (fwd_rt->flags & RT_REPAIR))
	    rreq_local_repair(fwd_rt, src_addr, ipd);
	else
	    rreq_route_discovery(dest_addr, rreq_flags, ipd);

	return;

    } else {

#ifdef NS_PORT
	/* DEBUG(LOG_DEBUG, 0, "Sending pkt uid=%d", ch->uid()); */
	sendPacket(p, fwd_rt->next_hop, 0.0);
#else	
      accept:

	if (pkt_flags & PKT_ENC || (pkt_flags & PKT_DEC))
	    status = ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 
				     ntohs(ip->tot_len), (unsigned char *)ip);
	else
	    status = ipq_set_verdict(h, pkt->packet_id, NF_ACCEPT, 0, NULL);
	
	if (status < 0)
	    die(h);

#endif
	/* When forwarding data, make sure we are sending HELLO messages */
	gettimeofday(&this_host.fwd_time, NULL);

	if (!llfeedback && optimized_hellos)
	    hello_start();
    }
}
示例#8
0
文件: main.c 项目: ebichu/dd-wrt
// Main entry point to application
int main(int argc, char *argv[])
{
	BYTE MsgBuff[MAXIPQMSG];
	struct sigaction SigAction;
	int i;

	// Read config & parameters
	if(!ReadConfig(argc, argv))
		return EXIT_FAILURE;

	// If we should act as neither a master nor a client (config error)
	if(!(Config.Flags & CONFIGFLAGS_MASTER) && !(Config.Flags & CONFIGFLAGS_CLIENT)){
		printf(APPTITLE": not configured to run as a master nor client\n");
		return EXIT_FAILURE;
	}

	// If we're to be a client, check we have an IP
	if(Config.Flags & CONFIGFLAGS_CLIENT && Config.MasterIp[0] == 0x00){
		printf(APPTITLE": Can not run as a client, no master IP specified 0x%02X\n", Config.Flags);
		return EXIT_FAILURE;
	}

	// Let the user know we're thinking of them
	if(Config.Flags & CONFIGFLAGS_MASTER)
		Log(LOG_NOTICE, "Acting as a master on port %d", Config.MasterPort);
	if(Config.Flags & CONFIGFLAGS_SELFCLIENT)
		Log(LOG_NOTICE, "Acting as a self-client with %d packet queues", Config.Queue);
	if(Config.Flags & CONFIGFLAGS_CLIENT)
		Log(LOG_NOTICE, "Acting as a client to %s:%d with %d packet queues", Config.MasterIp, Config.MasterPort, Config.Queue);
	else
		Log(LOG_NOTICE, "Acting stupid");

	// If we should daemonise
	if(Config.Flags & CONFIGFLAGS_DAEMON)
		// Daemonise
		Daemon();

	// If we should act as a master
	if(Config.Flags & CONFIGFLAGS_MASTER){

		// If we should act as _only_ a master
		if(!(Config.Flags & CONFIGFLAGS_CLIENT) && !(Config.Flags & CONFIGFLAGS_SELFCLIENT)){

			// Jump to main function in master.c which will perform this function
			MasterRun(NULL);

			return EXIT_SUCCESS;
		}
		// If we should act as a client as well
		else{

			// Start main thread in master.c which will perform this function
			pthread_create(&idMasterThread, NULL, &MasterRun, NULL);
		}
	}

	// Create an IPQ handle
	hIpq = ipq_create_handle(0, PF_INET);
	if(hIpq == NULL){

		// If we're running a master thread
		if(idMasterThread){

			// Set flag & wait for master thread to exit
			ExitMasterThread = 1;
			pthread_join(idMasterThread, NULL);
		}

		// Log it
		Log(LOG_ERR, "Failed to initialise IPQ (%s)", ipq_errstr());

		return EXIT_FAILURE;
	}

	// Set mode. Note: We set to packet mode so that we get to see the
	// number of bytes in the payload, the payload itself is ignored
	if (ipq_set_mode(hIpq, IPQ_COPY_PACKET, 0) == -1){

		// If we're running a master thread
		if(idMasterThread){

			// Set flag & wait for master thread to exit
			ExitMasterThread = 1;
			pthread_join(idMasterThread, NULL);
		}

		// Release IPQ
		ipq_destroy_handle(hIpq);

		// Tell the user
		Log(LOG_ERR, "Failed to configure IPQ (%s)", ipq_errstr());

		return EXIT_FAILURE;
	}

	// Allocate Packet queue memory
	for(i = 0; i < PacketQueues; i++)
		PacketQueue[i] = malloc(Config.Queue * sizeof(struct ipq_packet_msg));

	// Check allocations worked
	if(!PacketQueue){

		// Free anything that was allocated
		if(PacketQueue)
			free(PacketQueue);

		// If we're running a master thread
		if(idMasterThread){

			// Set flag & wait for master thread to exit
			ExitMasterThread = 1;
			pthread_join(idMasterThread, NULL);
		}

		// Release IPQ
		ipq_destroy_handle(hIpq);

		// Tell the user
		Log(LOG_ERR, "Failed to allocate sufficant memory");

		return EXIT_FAILURE;
	}

	// Inititalise the PacketQueue mutex
	pthread_mutex_init(&PacketQueueMutex, NULL);

	// If we're acting as a normal client
	if(Config.Flags & CONFIGFLAGS_CLIENT)
		// Start control thread
		pthread_create(&idControlThread, NULL, &ControlRun, NULL);

	// Install SIGTERM/etc handler to get out of 'while(!ExitMain)'
	memset(&SigAction, 0, sizeof(SigAction));
	SigAction.sa_handler = SignalHandler;
	sigaction(SIGINT, &SigAction, NULL);
	sigaction(SIGQUIT, &SigAction, NULL);
	sigaction(SIGTERM, &SigAction, NULL);
	// Install SIGHUP handler to reread config
	sigaction(SIGHUP, &SigAction, NULL);

	// Tell user
	Log(LOG_INFO, "Client up and running");

	// Enter main loop
	while(!ExitMain){

		// Wait up to 100mS to recieve a message
		int MsgSize = ipq_read(hIpq, MsgBuff, MAXIPQMSG, 100);

		// Error getting message
		if(MsgSize == -1){

			// TODO: This has started to happen occasionally. Don't know why.
			// ipq_errstr() = "Failed to receive netlink message"

			// Tell the user
			Log(LOG_ERR, "Error reading message from IPQ (%s)", ipq_errstr());
		}

		// Timeout getting message
		else if(MsgSize == 0){

			// Do background processing
			BackgroundProcessing();
		}

		// Got a message
		else{

			// Switch on message type
			switch (ipq_message_type(MsgBuff)){

			case NLMSG_ERROR:

				// Apparently we should call this (to clear the error?)
				ipq_get_msgerr(MsgBuff);

				// Tell the user
				Log(LOG_ERR, "Error reading message type from IPQ (%s)", ipq_errstr());
				break;

			case IPQM_PACKET:

				// Call a function to process the packet
				ProcessPacketMessage(ipq_get_packet(MsgBuff));

				// Do background processing
				BackgroundProcessing();
				break;

			default:

				// Tell the user
				Log(LOG_WARNING, "Undefined message type from IPQ");
				break;
			}
		}
	}

	// If we're running a control thread
	if(idControlThread){

		// Set flag & wait for control thread to exit
		ExitControlThread = 1;
		pthread_join(idControlThread, NULL);
	}

	// If we're running a master thread
	if(idMasterThread){

		// Set flag & wait for master thread to exit
		ExitMasterThread = 1;
		pthread_join(idMasterThread, NULL);
	}

	// Release IPQ
	ipq_destroy_handle(hIpq);

	// Release Packet queue memory
	for(i = 0; i < PacketQueues; i++)
		free(PacketQueue[i]);

	// Let the user know we're thinking of them
	Log(LOG_INFO, "Exited cleanly");

	return EXIT_SUCCESS;
}
示例#9
0
文件: sock.c 项目: armedpot/honeytrap
/* returns a bound socket matching a connection request *
 * sets verdict on request packet if ipq or nfq was used and the port is already bound *
 * in the latter case, -1 is returned */
int get_boundsock(struct sockaddr_in *server_addr, uint16_t port, int type) {
    int fd, sockopt;
#ifdef USE_IPQ_MON
    int status;
#endif

    if ((type != SOCK_DGRAM) && (type != SOCK_STREAM)) {
        logmsg(LOG_ERR, 1, "Error - Socket type %d not supported.\n", type);
        exit(EXIT_FAILURE);
    }

    if (!(fd = socket(AF_INET, type, 0))) {
        logmsg(LOG_ERR, 1, "Error - Could not create socket: %m.\n");
        exit(EXIT_FAILURE);
    }

    sockopt = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) < 0)
        logmsg(LOG_WARN, 1, "Warning - Unable to set SO_REUSEADDR for server socket.\n");

    bzero((char *) server_addr, sizeof(struct sockaddr_in));
    server_addr->sin_family		= AF_INET;
    server_addr->sin_addr.s_addr	= bind_address.s_addr;
    server_addr->sin_port		= port;
    if ((bind(fd, (struct sockaddr *) server_addr, sizeof(struct sockaddr_in))) != 0) {
        /* we already got one server process */
        logmsg(LOG_DEBUG, 1, "Unable to bind to port %u/tcp: %m.\n", ntohs(port));
#ifdef USE_IPQ_MON
        /* hand packet processing back to the kernel */
        if ((status = ipq_set_verdict(h, packet->packet_id, NF_ACCEPT, 0, NULL)) < 0) {
            logmsg(LOG_ERR, 1, "Error - Could not set verdict on packet: %s.\n", ipq_errstr());
            ipq_destroy_handle(h);
            exit(EXIT_FAILURE);
        }
        logmsg(LOG_DEBUG, 1, "IPQ - Successfully set verdict on packet.\n");
        return(-1);
#else
#ifdef USE_NFQ_MON
        /* hand packet processing back to the kernel */
        /* nfq_set_verdict()'s return value is undocumented,
         * but digging the source of libnetfilter_queue and libnfnetlink reveals
         * that it's just the passed-through value of a sendmsg() */
        if (nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL) == -1) {
            logmsg(LOG_ERR, 1, "Error - Could not set verdict on packet.\n");
            nfq_destroy_queue(qh);
            exit(EXIT_FAILURE);
        }
        logmsg(LOG_DEBUG, 1, "NFQ - Successfully set verdict on packet.\n");

        /* a dynamic server is already present */
        close(fd);
        return(-1);
#else
        /* if bind() did not fail for 'port already in use' but for some other reason,
         *  we're in troubles and want a verbose error message */
        if (errno != 98) logmsg(LOG_NOISY, 1, "Warning - Could not bind to port %u/tcp: %m.\n", ntohs(port));
        exit(EXIT_FAILURE);
#endif
#endif
    }
    logmsg(LOG_DEBUG, 1, "Socket created, file descriptor is %d.\n", fd);

    return(fd);
}