int add_filter_rule2(const char * ifname, const char * iaddr, unsigned short eport, int proto, const char * desc) { return add_filter_rule(proto, iaddr, eport); }
int add_filter_rule2(const char * ifname, const char * rhost, const char * iaddr, unsigned short eport, unsigned short iport, int proto, const char * desc) { UNUSED(ifname); UNUSED(eport); UNUSED(desc); return add_filter_rule(proto, rhost, iaddr, iport); }
int main(int argc, char ** argv) { unsigned short eport, iport; const char * iaddr; printf("Usage %s <ext_port> <internal_ip> <internal_port>\n", argv[0]); if(argc<4) return -1; openlog("testiptcrdr", LOG_PERROR|LOG_CONS, LOG_LOCAL0); eport = (unsigned short)atoi(argv[1]); iaddr = argv[2]; iport = (unsigned short)atoi(argv[3]); printf("trying to redirect port %hu to %s:%hu\n", eport, iaddr, iport); if(addnatrule(IPPROTO_TCP, eport, iaddr, iport, NULL) < 0) return -1; if(add_filter_rule(IPPROTO_TCP, NULL, iaddr, iport) < 0) return -1; /* test */ { unsigned short p1, p2; char addr[16]; int proto2; char desc[256]; char rhost[256]; unsigned int timestamp; u_int64_t packets, bytes; desc[0] = '\0'; if(get_redirect_rule_by_index(0, "", &p1, addr, sizeof(addr), &p2, &proto2, desc, sizeof(desc), rhost, sizeof(rhost), ×tamp, &packets, &bytes) < 0) { printf("rule not found\n"); } else { printf("redirected port %hu to %s:%hu proto %d packets=%" PRIu64 " bytes=%" PRIu64 "\n", p1, addr, p2, proto2, packets, bytes); } } printf("trying to list nat rules :\n"); list_redirect_rule(argv[1]); printf("deleting\n"); delete_redirect_and_filter_rules(eport, IPPROTO_TCP); return 0; }
static int parse_filter(struct filter *filt, char *expr, int operators) { /* Filter is a chain of sym@lib rules separated by '-' or '+'. * If the filter expression starts with '-', the missing * initial rule is implicitly *@*. */ enum filter_rule_type type = FR_ADD; while (*expr != 0) { size_t s = strcspn(expr, "-+@" + (operators ? 0 : 2)); char *symname = expr; char *libname; char *next = expr + s + 1; enum filter_rule_type this_type = type; if (expr[s] == 0) { libname = "*"; expr = next - 1; } else if (expr[s] == '-' || expr[s] == '+') { type = expr[s] == '-' ? FR_SUBTRACT : FR_ADD; expr[s] = 0; libname = "*"; expr = next; } else { assert(expr[s] == '@'); expr[s] = 0; s = strcspn(next, "-+" + (operators ? 0 : 2)); if (s == 0) { libname = "*"; expr = next; } else if (next[s] == 0) { expr = next + s; libname = next; } else { assert(next[s] == '-' || next[s] == '+'); type = next[s] == '-' ? FR_SUBTRACT : FR_ADD; next[s] = 0; expr = next + s + 1; libname = next; } } assert(*libname != 0); char *symend = symname + strlen(symname) - 1; char *libend = libname + strlen(libname) - 1; int sym_is_re = 0; int lib_is_re = 0; /* * /xxx/@... and ...@/xxx/ means that xxx are regular * expressions. They are globs otherwise. * * /xxx@yyy/ is the same as /xxx/@/yyy/ * * @/xxx matches library path name * @.xxx matches library relative path name */ if (symname[0] == '/') { if (symname != symend && symend[0] == '/') { ++symname; *symend-- = 0; sym_is_re = 1; } else { sym_is_re = 1; lib_is_re = 1; ++symname; /* /XXX@YYY/ is the same as * /XXX/@/YYY/. */ if (libend[0] != '/') fprintf(stderr, "Unmatched '/'" " in symbol name.\n"); else *libend-- = 0; } } /* If libname ends in '/', then we expect '/' in the * beginning too. Otherwise the initial '/' is part * of absolute file name. */ if (!lib_is_re) lib_is_re = grok_libname_pattern(&libname, &libend); if (*symname == 0) /* /@AA/ */ symname = "*"; if (*libname == 0) /* /aa@/ */ libname = "*"; add_filter_rule(filt, expr, this_type, symname, sym_is_re, libname, lib_is_re); } return 0; }