Ejemplo n.º 1
0
/* --- */
int add_redirect_rule2(
    const char * ifname,
    const char * rhost,
    unsigned short eport,
    const char * iaddr,
    unsigned short iport,
    int proto,
    const char * desc,
    unsigned int timestamp)
{
    struct ip_fw rule;
    int r;

    if (ipfw_validate_protocol(proto) < 0)
        return -1;
    if (ipfw_validate_ifname(ifname) < 0)
        return -1;

    memset(&rule, 0, sizeof(struct ip_fw));
    rule.version = IP_FW_CURRENT_API_VERSION;
#if 0
    rule.fw_number = 1000; /* rule number */
    rule.context = (void *)desc; /* The description is kept in a separate list */
#endif
    rule.fw_prot = proto; /* protocol */
    rule.fw_flg |= IP_FW_F_IIFACE; /* interfaces to check */
    rule.fw_flg |= IP_FW_F_IIFNAME; /* interfaces to check by name */
    rule.fw_flg |= (IP_FW_F_IN | IP_FW_F_OUT); /* packet direction */
    rule.fw_flg |= IP_FW_F_FWD; /* forward action */
#ifdef USE_IFNAME_IN_RULES
    if (ifname != NULL) {
        strlcpy(rule.fw_in_if.fu_via_if.name, ifname, IFNAMSIZ); /* src interface */
        rule.fw_in_if.fu_via_if.unit = -1;
    }
#endif
    if (inet_aton(iaddr, &rule.fw_out_if.fu_via_ip) == 0) {
        syslog(LOG_ERR, "inet_aton(): %m");
        return -1;
    }
    memcpy(&rule.fw_dst,  &rule.fw_out_if.fu_via_ip, sizeof(struct in_addr));
    memcpy(&rule.fw_fwd_ip.sin_addr, &rule.fw_out_if.fu_via_ip, sizeof(struct in_addr));
    rule.fw_dmsk.s_addr = INADDR_BROADCAST;	/* TODO check this */
    IP_FW_SETNDSTP(&rule, 1); /* number of external ports */
    rule.fw_uar.fw_pts[0] = eport; /* external port */
    rule.fw_fwd_ip.sin_port = iport; /* internal port */
    if (rhost && rhost[0] != '\0') {
        inet_aton(rhost, &rule.fw_src);
        rule.fw_smsk.s_addr = htonl(INADDR_NONE);
    }

    r = ipfw_exec(IP_FW_ADD, &rule, sizeof(rule));
    if(r >= 0)
        add_desc_time(eport, proto, desc, timestamp);
    return r;
}
Ejemplo n.º 2
0
int delete_redirect_rule(
    const char * ifname,
    unsigned short eport,
    int proto)
{
    int i, count_rules, total_rules = 0;
    struct ip_fw * rules = NULL;

    if (ipfw_validate_protocol(proto) < 0)
        return -1;
    if (ipfw_validate_ifname(ifname) < 0)
        return -1;

    do {
        count_rules = ipfw_fetch_ruleset(&rules, &total_rules, 10);
        if (count_rules < 0)
            goto error;
    } while (count_rules == 10);

    for (i=0; i<total_rules-1; i++) {
        const struct ip_fw const * ptr = &rules[i];
        if (proto == ptr->fw_prot && eport == ptr->fw_uar.fw_pts[0]) {
            if (ipfw_exec(IP_FW_DEL, (struct ip_fw *)ptr, sizeof(*ptr)) < 0)
                goto error;
            // And what if we found more than 1 matching rule?
            ipfw_free_ruleset(&rules);
            del_desc_time(eport, proto);
            return 0;
        }
    }

error:
    if (rules != NULL)
        ipfw_free_ruleset(&rules);
    return -1;
}
Ejemplo n.º 3
0
/* get_redirect_rule()
 * return value : 0 success (found)
 * -1 = error or rule not found */
int get_redirect_rule(
    const char * ifname,
    unsigned short eport,
    int proto,
    char * iaddr,
    int iaddrlen,
    unsigned short * iport,
    char * desc,
    int desclen,
    char * rhost,
    int rhostlen,
    unsigned int * timestamp,
    u_int64_t * packets,
    u_int64_t * bytes)
{
    int i, count_rules, total_rules = 0;
    struct ip_fw * rules = NULL;

    if (ipfw_validate_protocol(proto) < 0)
        return -1;
    if (ipfw_validate_ifname(ifname) < 0)
        return -1;
    if (timestamp)
        *timestamp = 0;

    do {
        count_rules = ipfw_fetch_ruleset(&rules, &total_rules, 10);
        if (count_rules < 0)
            goto error;
    } while (count_rules == 10);

    for (i=0; i<total_rules-1; i++) {
        const struct ip_fw const * ptr = &rules[i];
        if (proto == ptr->fw_prot && eport == ptr->fw_uar.fw_pts[0]) {
            if (packets != NULL)
                *packets = ptr->fw_pcnt;
            if (bytes != NULL)
                *bytes = ptr->fw_bcnt;
            if (iport != NULL)
                *iport = ptr->fw_fwd_ip.sin_port;
            if (iaddr != NULL && iaddrlen > 0) {
                /* looks like fw_out_if.fu_via_ip is zero */
                //if (inet_ntop(AF_INET, &ptr->fw_out_if.fu_via_ip, iaddr, iaddrlen) == NULL) {
                if (inet_ntop(AF_INET, &ptr->fw_fwd_ip.sin_addr, iaddr, iaddrlen) == NULL) {
                    syslog(LOG_ERR, "inet_ntop(): %m");
                    goto error;
                }
            }
            if (rhost != NULL && rhostlen > 0) {
                if (ptr->fw_src.s_addr == 0)
                    rhost[0] = '\0';
                else if (inet_ntop(AF_INET, &ptr->fw_src.s_addr, rhost, rhostlen) == NULL) {
                    syslog(LOG_ERR, "inet_ntop(): %m");
                    goto error;
                }
            }
            // And what if we found more than 1 matching rule?
            ipfw_free_ruleset(&rules);
            get_desc_time(eport, proto, desc, desclen, timestamp);
            return 0;
        }
    }

error:
    if (rules != NULL)
        ipfw_free_ruleset(&rules);
    return -1;
}