Example #1
0
int get_source_ipv4(int protocol, struct sockaddr_in * address)
{
    /* Voir la section NOTES du man(2) de gethostname pour la taille
     * du buffer.
     */
    char buffer[HOST_NAME_MAX+1];
    gethostname(buffer, HOST_NAME_MAX+1);

    int success = get_ipv4(buffer, protocol, address);

    /* Workaround pour obtenir une adresse de la machine.
     *
     * Sur certaines machines getaddrinfo retourne pour unique adresse 127.0.0.1
     * lorsqu'on donne le hostname de la machine...
     * Sur d'autres elle retourne bien les adresses des interfaces
     * de la machine.
     *
     * De même avec les « vrais » ping et traceroute:
     * `ping localhost` et `ping <hostname de la machine>` vont tous deux se faire sur
     * 127.0.0.1, mais sur d'autres machines se feront sur deux adresses différentes.
     * Configuration des machines ? Versions des logiciels ? ...?
     *
     * Avec ça, ça fonctionne partout :
     */
    const in_addr_t REFUSED_IPV4 = inet_addr("127.0.0.1");
    if (address->sin_addr.s_addr == REFUSED_IPV4)
        success = get_interface_ipv4(address);

    return success;
}
Example #2
0
int pf_block_probe(char *incoming_ip, int portnum, struct opt *opts) 
{
	struct pfioc_rule pr;
	struct pfioc_pooladdr paddr;
	struct sockaddr ifr;
	char curr_ipv4[16];
	char *ifname = opts->ifname;
	short test_result = 0;
	int pf_dev_fd, ret = 1, sockfd;
	static int num_rules_added = 0; /* the rule number to add the next rule after */

	memset(&pr, 0, sizeof(struct pfioc_rule));
	memset(&pr.rule, 0, sizeof(struct pf_rule));
	memset(&paddr, 0, sizeof(struct pfioc_pooladdr));

	if((sockfd = get_dgram_socket()) < 0) {
		(void)logmsg("get_dgram_socket() no socket for getipv4()");
		(void)report_status_and_bail(BAIL_OUT, errno);
	}
		
	if(! (get_interface_ipv4(sockfd, ifname, &ifr, curr_ipv4))) {
		(void)logmsg("Unable to obtain ipv4 for interface %s\n", ifname);
		(void)close(sockfd);
		(void)report_status_and_bail(BAIL_OUT, errno);
	}
	else 
		(void)close(sockfd); 

	/* init rule structure */
	pr.rule.action = PF_DROP;	
	pr.rule.quick = 1;
	pr.rule.log = 1;
	pr.rule.af = AF_INET;
	pr.rule.proto = IPPROTO_TCP;
	pr.rule.src.addr.type = PF_ADDR_ADDRMASK;
	memset(&pr.rule.src.addr.v.a.mask.v4, 255, 4); /* match only this host:port */
	inet_pton(AF_INET, incoming_ip, &pr.rule.src.addr.v.a.addr.v4);
	pr.rule.src.addr.type = PF_ADDR_ADDRMASK;
	memset(&pr.rule.dst.addr.v.a.mask.v4, 255, 4);
	inet_pton(AF_INET, curr_ipv4, &pr.rule.dst.addr.v.a.addr.v4); 
	pr.rule.dst.port_op = PF_OP_EQ;
	pr.rule.keep_state = 0;
	pr.rule.flags = TH_SYN;
	pr.rule.flagset = (TH_SYN | TH_ACK | TH_FIN | TH_RST);
	pr.rule.dst.port[0] = htons(portnum);
		
	pf_dev_fd = open("/dev/pf", O_RDWR); 
	
	if(pf_dev_fd < 0) {
		(void)logmsg("failed to open /dev/pf, *not* adding rule\n");
		(void)logmsg("connection attempt from %s on port %d _NOT_ BLOCKED\n", incoming_ip, portnum);
		(void)report_status_and_bail(DO_NOT_BAIL, errno);
		(void)close(pf_dev_fd);
		ret = 0;
	}

	/* check the rule doesn't already exist in rules added so far */
	if(ret)
		test_result = test_rule(incoming_ip, &pf_dev_fd, portnum, num_rules_added, opts->flags);

	if(test_result && ret) {

		if((ioctl(pf_dev_fd, DIOCBEGINADDRS, &paddr)) < 0) 
			logmsg("err: ioctl DIOCBEGINADDRS");

		pr.action = PF_CHANGE_GET_TICKET;
		pr.pool_ticket = paddr.ticket;
	
		if((ioctl(pf_dev_fd, DIOCCHANGERULE, &pr)) < 0)
			logmsg("err: ioctl DIOCCHANGERULE");

		pr.action = PF_CHANGE_ADD_AFTER;
		pr.nr = num_rules_added;
		
		if((ioctl(pf_dev_fd, DIOCCHANGERULE, &pr)) < 0)
			logmsg("err: ioctl DIOCCHANGERULE");

		num_rules_added++; /* static */

		(void)logmsg("added blocking filter rule for remote host %s on port %d", incoming_ip, portnum); 
		
	} else if(test_result == 0) 
		/* some moron may attempt to fill up the log file! 
	         * this *may* become an issue during testing. 
		 * Here, a zero tolerance response could be taken 
		 * for repeat offenders; for now, just ignore and log */ 
		(void)logmsg("rule already exists, ignoring");
	else {
		(void)logmsg("connection %s on port %d", incoming_ip, portnum);
		(void)logmsg("ioctl: error searching current ruleset - *no* rule added");
	}

	(void)close(pf_dev_fd);
return ret;
}