static void parse_hostnetworkmask(const char *name, struct in_addr **addrpp, struct in_addr *maskp, unsigned int *naddrs) { struct in_addr *addrp; char buf[256]; char *p; int i, j, k, n; strncpy(buf, name, sizeof(buf) - 1); if ((p = strrchr(buf, '/')) != NULL) { *p = '\0'; addrp = parse_mask(p + 1); } else addrp = parse_mask(NULL); inaddrcpy(maskp, addrp); /* if a null mask is given, the name is ignored, like in "any/0" */ if (maskp->s_addr == 0L) strcpy(buf, "0.0.0.0"); addrp = *addrpp = parse_hostnetwork(buf, naddrs); n = *naddrs; for (i = 0, j = 0; i < n; i++) { addrp[j++].s_addr &= maskp->s_addr; for (k = 0; k < j - 1; k++) { if (addrp[k].s_addr == addrp[j - 1].s_addr) { (*naddrs)--; j--; break; } } } }
static int parse(int c, char **argv, int invert, unsigned int *flags, const struct arpt_entry *e, struct arpt_entry_target **t) { struct arpt_mangle *mangle = (struct arpt_mangle *)(*t)->data; struct in_addr *ipaddr; struct ether_addr *macaddr; int ret = 1; switch (c) { case MANGLE_IPS: /* if (e->arp.arpln_mask == 0) exit_error(PARAMETER_PROBLEM, "no pln defined"); if (e->arp.invflags & ARPT_INV_ARPPLN) exit_error(PARAMETER_PROBLEM, "! pln not allowed for --mangle-ip-s"); */ /* if (e->arp.arpln != 4) exit_error(PARAMETER_PROBLEM, "only pln=4 supported"); */ { unsigned int nr; ipaddr = parse_hostnetwork(argv[optind-1], &nr); } mangle->u_s.src_ip.s_addr = ipaddr->s_addr; free(ipaddr); mangle->flags |= ARPT_MANGLE_SIP; break; case MANGLE_IPT: /* if (e->arp.arpln_mask == 0) exit_error(PARAMETER_PROBLEM, "no pln defined"); if (e->arp.invflags & ARPT_INV_ARPPLN) exit_error(PARAMETER_PROBLEM, "! pln not allowed for --mangle-ip-d"); */ /* if (e->arp.arpln != 4) exit_error(PARAMETER_PROBLEM, "only pln=4 supported"); */ { unsigned int nr; ipaddr = parse_hostnetwork(argv[optind-1], &nr); } mangle->u_t.tgt_ip.s_addr = ipaddr->s_addr; free(ipaddr); mangle->flags |= ARPT_MANGLE_TIP; break; case MANGLE_DEVS: if (e->arp.arhln_mask == 0) exit_error(PARAMETER_PROBLEM, "no --h-length defined"); if (e->arp.invflags & ARPT_INV_ARPHLN) exit_error(PARAMETER_PROBLEM, "! --h-length not allowed for " "--mangle-mac-s"); if (e->arp.arhln != 6) exit_error(PARAMETER_PROBLEM, "only --h-length 6 " "supported"); macaddr = ether_aton(argv[optind-1]); if (macaddr == NULL) exit_error(PARAMETER_PROBLEM, "invalid source MAC"); memcpy(mangle->src_devaddr, macaddr, e->arp.arhln); mangle->flags |= ARPT_MANGLE_SDEV; break; case MANGLE_DEVT: if (e->arp.arhln_mask == 0) exit_error(PARAMETER_PROBLEM, "no --h-length defined"); if (e->arp.invflags & ARPT_INV_ARPHLN) exit_error(PARAMETER_PROBLEM, "! hln not allowed for --mangle-mac-d"); if (e->arp.arhln != 6) exit_error(PARAMETER_PROBLEM, "only --h-length 6 " "supported"); macaddr = ether_aton(argv[optind-1]); if (macaddr == NULL) exit_error(PARAMETER_PROBLEM, "invalid target MAC"); memcpy(mangle->tgt_devaddr, macaddr, e->arp.arhln); mangle->flags |= ARPT_MANGLE_TDEV; break; case MANGLE_TARGET: if (!strcmp(argv[optind-1], "DROP")) mangle->target = NF_DROP; else if (!strcmp(argv[optind-1], "ACCEPT")) mangle->target = NF_ACCEPT; else if (!strcmp(argv[optind-1], "CONTINUE")) mangle->target = ARPT_CONTINUE; else exit_error(PARAMETER_PROBLEM, "bad target for " "--mangle-target"); break; default: ret = 0; } return ret; }
static void mangle_parse(struct xt_option_call *cb) { const struct arpt_entry *e = cb->xt_entry; struct arpt_mangle *mangle = cb->data; struct in_addr *ipaddr; struct ether_addr *macaddr; /* mangle target is by default "ACCEPT". Setting it here, * since original arpt_mangle.c init() no longer exists*/ mangle->target = NF_ACCEPT; xtables_option_parse(cb); switch (cb->entry->id) { case MANGLE_IPS: /* if (e->arp.arpln_mask == 0) xtables_error(PARAMETER_PROBLEM, "no pln defined"); if (e->arp.invflags & ARPT_INV_ARPPLN) xtables_error(PARAMETER_PROBLEM, "! pln not allowed for --mangle-ip-s"); */ /* if (e->arp.arpln != 4) xtables_error(PARAMETER_PROBLEM, "only pln=4 supported"); */ { unsigned int nr; ipaddr = parse_hostnetwork(cb->arg, &nr); } mangle->u_s.src_ip.s_addr = ipaddr->s_addr; free(ipaddr); mangle->flags |= ARPT_MANGLE_SIP; break; case MANGLE_IPT: /* if (e->arp.arpln_mask == 0) xtables_error(PARAMETER_PROBLEM, "no pln defined"); if (e->arp.invflags & ARPT_INV_ARPPLN) xtables_error(PARAMETER_PROBLEM, "! pln not allowed for --mangle-ip-d"); */ /* if (e->arp.arpln != 4) xtables_error(PARAMETER_PROBLEM, "only pln=4 supported"); */ { unsigned int nr; ipaddr = parse_hostnetwork(cb->arg, &nr); } mangle->u_t.tgt_ip.s_addr = ipaddr->s_addr; free(ipaddr); mangle->flags |= ARPT_MANGLE_TIP; break; case MANGLE_DEVS: if (e->arp.arhln_mask == 0) xtables_error(PARAMETER_PROBLEM, "no --h-length defined"); if (e->arp.invflags & ARPT_INV_ARPHLN) xtables_error(PARAMETER_PROBLEM, "! --h-length not allowed for " "--mangle-mac-s"); if (e->arp.arhln != 6) xtables_error(PARAMETER_PROBLEM, "only --h-length 6 supported"); macaddr = ether_aton(cb->arg); if (macaddr == NULL) xtables_error(PARAMETER_PROBLEM, "invalid source MAC"); memcpy(mangle->src_devaddr, macaddr, e->arp.arhln); mangle->flags |= ARPT_MANGLE_SDEV; break; case MANGLE_DEVT: if (e->arp.arhln_mask == 0) xtables_error(PARAMETER_PROBLEM, "no --h-length defined"); if (e->arp.invflags & ARPT_INV_ARPHLN) xtables_error(PARAMETER_PROBLEM, "! hln not allowed for --mangle-mac-d"); if (e->arp.arhln != 6) xtables_error(PARAMETER_PROBLEM, "only --h-length 6 supported"); macaddr = ether_aton(cb->arg); if (macaddr == NULL) xtables_error(PARAMETER_PROBLEM, "invalid target MAC"); memcpy(mangle->tgt_devaddr, macaddr, e->arp.arhln); mangle->flags |= ARPT_MANGLE_TDEV; break; case MANGLE_TARGET: if (!strcmp(cb->arg, "DROP")) mangle->target = NF_DROP; else if (!strcmp(cb->arg, "ACCEPT")) mangle->target = NF_ACCEPT; else if (!strcmp(cb->arg, "CONTINUE")) mangle->target = ARPT_CONTINUE; else xtables_error(PARAMETER_PROBLEM, "bad target for --mangle-target"); break; } }