static void iprange_mt4_print(const void *ip, const struct xt_entry_match *match, int numeric) { const struct xt_iprange_mtinfo *info = (const void *)match->data; if (info->flags & IPRANGE_SRC) { printf("source IP range "); if (info->flags & IPRANGE_SRC_INV) printf("! "); /* * ipaddr_to_numeric() uses a static buffer, so cannot * combine the printf() calls. */ printf("%s", xtables_ipaddr_to_numeric(&info->src_min.in)); printf("-%s ", xtables_ipaddr_to_numeric(&info->src_max.in)); } if (info->flags & IPRANGE_DST) { printf("destination IP range "); if (info->flags & IPRANGE_DST_INV) printf("! "); printf("%s", xtables_ipaddr_to_numeric(&info->dst_min.in)); printf("-%s ", xtables_ipaddr_to_numeric(&info->dst_max.in)); } }
static void SAME_save(const void *ip, const struct xt_entry_target *target) { unsigned int count; const struct ipt_same_info *mr = (const void *)target->data; int random_selection = 0; for (count = 0; count < mr->rangesize; count++) { const struct nf_nat_range *r = &mr->range[count]; struct in_addr a; a.s_addr = r->min_ip; printf(" --to %s", xtables_ipaddr_to_numeric(&a)); a.s_addr = r->max_ip; if (r->min_ip != r->max_ip) printf("-%s", xtables_ipaddr_to_numeric(&a)); if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) random_selection = 1; } if (mr->info & IPT_SAME_NODST) printf(" --nodst"); if (random_selection) printf(" --random"); }
static int iprange_mt4_xlate(const void *ip, const struct xt_entry_match *match, struct xt_xlate *xl, int numeric) { const struct xt_iprange_mtinfo *info = (const void *)match->data; char *space = ""; if (info->flags & IPRANGE_SRC) { if (info->flags & IPRANGE_SRC_INV) xt_xlate_add(xl, "!= "); xt_xlate_add(xl, "ip saddr %s", xtables_ipaddr_to_numeric(&info->src_min.in)); xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&info->src_max.in)); space = " "; } if (info->flags & IPRANGE_DST) { if (info->flags & IPRANGE_DST_INV) { xt_xlate_add(xl, "%s!= ", space); space = ""; } xt_xlate_add(xl, "%sip daddr %s", space, xtables_ipaddr_to_numeric(&info->dst_min.in)); xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&info->dst_max.in)); } return 1; }
static void ipaddr_mt4_print(const void *entry, const struct xt_entry_match *match, int numeric) { const struct xt_ipaddr_mtinfo *info = (const void *)match->data; if (info->flags & XT_IPADDR_SRC) { printf("src IP "); if (info->flags & XT_IPADDR_SRC_INV) printf("! "); if (numeric) printf("%s ", numeric ? xtables_ipaddr_to_numeric(&info->src.in) : xtables_ipaddr_to_anyname(&info->src.in)); } if (info->flags & XT_IPADDR_DST) { printf("dst IP "); if (info->flags & XT_IPADDR_DST_INV) printf("! "); printf("%s ", numeric ? xtables_ipaddr_to_numeric(&info->dst.in): xtables_ipaddr_to_anyname(&info->dst.in)); } }
static void brip_print(const void *ip, const struct xt_entry_match *match, int numeric) { struct ebt_ip_info *info = (struct ebt_ip_info *)match->data; struct in_addr *addrp, *maskp; if (info->bitmask & EBT_IP_SOURCE) { printf("--ip-src "); if (info->invflags & EBT_IP_SOURCE) printf("! "); addrp = (struct in_addr *)&info->saddr; maskp = (struct in_addr *)&info->smsk; printf("%s%s ", xtables_ipaddr_to_numeric(addrp), xtables_ipmask_to_numeric(maskp)); } if (info->bitmask & EBT_IP_DEST) { printf("--ip-dst "); if (info->invflags & EBT_IP_DEST) printf("! "); addrp = (struct in_addr *)&info->daddr; maskp = (struct in_addr *)&info->dmsk; printf("%s%s ", xtables_ipaddr_to_numeric(addrp), xtables_ipmask_to_numeric(maskp)); } if (info->bitmask & EBT_IP_TOS) { printf("--ip-tos "); if (info->invflags & EBT_IP_TOS) printf("! "); printf("0x%02X ", info->tos); } if (info->bitmask & EBT_IP_PROTO) { struct protoent *pe; printf("--ip-proto "); if (info->invflags & EBT_IP_PROTO) printf("! "); pe = getprotobynumber(info->protocol); if (pe == NULL) { printf("%d ", info->protocol); } else { printf("%s ", pe->p_name); } } if (info->bitmask & EBT_IP_SPORT) { printf("--ip-sport "); if (info->invflags & EBT_IP_SPORT) printf("! "); print_port_range(info->sport); } if (info->bitmask & EBT_IP_DPORT) { printf("--ip-dport "); if (info->invflags & EBT_IP_DPORT) printf("! "); print_port_range(info->dport); } }
void nat64_tg4_save(const void *entry, const struct xt_entry_target *target) { const struct xt_nat64_tginfo *info = (const void *)target->data; printf("--ipsrc %s ", xtables_ipaddr_to_numeric(&info->ipsrc.in)); if (info ->flags & XT_NAT64_IP_SRC) { printf("--ipsrc %s ", xtables_ipaddr_to_numeric(&info->ipsrc.in)); } if (info->flags & XT_NAT64_IP_DST) { printf("--ipdst %s ", xtables_ipaddr_to_numeric(&info->ipdst.in)); } }
static void conntrack_dump_addr(const union nf_inet_addr *addr, const union nf_inet_addr *mask, unsigned int family, bool numeric) { if (family == NFPROTO_IPV4) { if (!numeric && addr->ip == 0) { printf("anywhere "); return; } if (numeric) printf("%s ", xtables_ipaddr_to_numeric(&addr->in)); else printf("%s ", xtables_ipaddr_to_anyname(&addr->in)); } else if (family == NFPROTO_IPV6) { if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 && addr->ip6[2] == 0 && addr->ip6[3] == 0) { printf("anywhere "); return; } if (numeric) printf("%s ", xtables_ip6addr_to_numeric(&addr->in6)); else printf("%s ", xtables_ip6addr_to_anyname(&addr->in6)); } }
/* Shamelessly copied from libxt_conntrack.c */ static void ipvs_mt_dump_addr(const union nf_inet_addr *addr, const union nf_inet_addr *mask, unsigned int family, bool numeric) { char buf[BUFSIZ]; if (family == NFPROTO_IPV4) { if (!numeric && addr->ip == 0) { printf("anywhere "); return; } if (numeric) strcpy(buf, xtables_ipaddr_to_numeric(&addr->in)); else strcpy(buf, xtables_ipaddr_to_anyname(&addr->in)); strcat(buf, xtables_ipmask_to_numeric(&mask->in)); printf("%s ", buf); } else if (family == NFPROTO_IPV6) { if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 && addr->ip6[2] == 0 && addr->ip6[3] == 0) { printf("anywhere "); return; } if (numeric) strcpy(buf, xtables_ip6addr_to_numeric(&addr->in6)); else strcpy(buf, xtables_ip6addr_to_anyname(&addr->in6)); strcat(buf, xtables_ip6mask_to_numeric(&mask->in6)); printf("%s ", buf); } }
static void tee_tg_save(const void *ip, const struct xt_entry_target *target) { const struct xt_tee_tginfo *info = (const void *)target->data; printf(" --gateway %s", xtables_ipaddr_to_numeric(&info->gw.in)); if (*info->oif != '\0') printf(" --oif %s", info->oif); }
static void NETMAP_print(const void *ip, const struct xt_entry_target *target, int numeric) { const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data; const struct nf_nat_ipv4_range *r = &mr->range[0]; struct in_addr a; int bits; a.s_addr = r->min_ip; printf("%s", xtables_ipaddr_to_numeric(&a)); a.s_addr = ~(r->min_ip ^ r->max_ip); bits = netmask2bits(a.s_addr); if (bits < 0) printf("/%s", xtables_ipaddr_to_numeric(&a)); else printf("/%d", bits); }
static void iprange_mt4_save(const void *ip, const struct xt_entry_match *match) { const struct xt_iprange_mtinfo *info = (const void *)match->data; if (info->flags & IPRANGE_SRC) { if (info->flags & IPRANGE_SRC_INV) printf("! "); printf("--src-range %s", xtables_ipaddr_to_numeric(&info->src_min.in)); printf("-%s ", xtables_ipaddr_to_numeric(&info->src_max.in)); } if (info->flags & IPRANGE_DST) { if (info->flags & IPRANGE_DST_INV) printf("! "); printf("--dst-range %s", xtables_ipaddr_to_numeric(&info->dst_min.in)); printf("-%s ", xtables_ipaddr_to_numeric(&info->dst_max.in)); } }
static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target, int numeric) { const struct xt_tproxy_target_info *info = (const void *)target->data; printf("TPROXY redirect %s:%u mark 0x%x/0x%x", xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr), ntohs(info->lport), (unsigned int)info->mark_value, (unsigned int)info->mark_mask); }
/* * Prints the rule. */ static void ipaddr_mt4_save(const void *entry, const struct xt_entry_match *match) { const struct xt_ipaddr_mtinfo *info = (const void *)match->data; if (info ->flags & XT_IPADDR_SRC) { if (info->flags & XT_IPADDR_SRC_INV) printf("! "); printf("--ipsrc %s ", xtables_ipaddr_to_numeric(&info->src.in)); } if (info->flags & XT_IPADDR_DST) { if (info->flags & XT_IPADDR_DST_INV) printf("! "); printf("--ipdst %s ", xtables_ipaddr_to_numeric(&info->dst.in)); } }
static void print_range_xlate(const struct nf_nat_ipv4_range *r, struct xt_xlate *xl) { if (r->flags & NF_NAT_RANGE_MAP_IPS) { struct in_addr a; a.s_addr = r->min_ip; xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&a)); if (r->max_ip != r->min_ip) { a.s_addr = r->max_ip; xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&a)); } } if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { xt_xlate_add(xl, ":%hu", ntohs(r->min.tcp.port)); if (r->max.tcp.port != r->min.tcp.port) xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port)); } }
static void print_range(const struct nf_nat_range *r) { if (r->flags & IP_NAT_RANGE_MAP_IPS) { struct in_addr a; a.s_addr = r->min_ip; printf("%s", xtables_ipaddr_to_numeric(&a)); if (r->max_ip != r->min_ip) { a.s_addr = r->max_ip; printf("-%s", xtables_ipaddr_to_numeric(&a)); } } if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) { printf(":"); printf("%hu", ntohs(r->min.tcp.port)); if (r->max.tcp.port != r->min.tcp.port) printf("-%hu", ntohs(r->max.tcp.port)); } }
static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target) { const struct xt_tproxy_target_info *info = (const void *)target->data; printf("--on-port %u ", ntohs(info->lport)); printf("--on-ip %s ", xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr)); printf("--tproxy-mark 0x%x/0x%x ", (unsigned int)info->mark_value, (unsigned int)info->mark_mask); }
const char *xtables_ipaddr_to_anyname(const struct in_addr *addr) { const char *name; if ((name = ipaddr_to_host(addr)) != NULL || (name = ipaddr_to_network(addr)) != NULL) return name; return xtables_ipaddr_to_numeric(addr); }
static void print_entry(const char *prefix, const struct xt_policy_elem *e, bool numeric, uint8_t family) { if (e->match.reqid) { PRINT_INVERT(e->invert.reqid); printf("%sreqid %u ", prefix, e->reqid); } if (e->match.spi) { PRINT_INVERT(e->invert.spi); printf("%sspi 0x%x ", prefix, e->spi); } if (e->match.proto) { PRINT_INVERT(e->invert.proto); print_proto(prefix, e->proto, numeric); } if (e->match.mode) { PRINT_INVERT(e->invert.mode); print_mode(prefix, e->mode, numeric); } if (e->match.daddr) { PRINT_INVERT(e->invert.daddr); if (family == NFPROTO_IPV6) printf("%stunnel-dst %s%s ", prefix, xtables_ip6addr_to_numeric(&e->daddr.a6), xtables_ip6mask_to_numeric(&e->dmask.a6)); else printf("%stunnel-dst %s%s ", prefix, xtables_ipaddr_to_numeric(&e->daddr.a4), xtables_ipmask_to_numeric(&e->dmask.a4)); } if (e->match.saddr) { PRINT_INVERT(e->invert.saddr); if (family == NFPROTO_IPV6) printf("%stunnel-src %s%s ", prefix, xtables_ip6addr_to_numeric(&e->saddr.a6), xtables_ip6mask_to_numeric(&e->smask.a6)); else printf("%stunnel-src %s%s ", prefix, xtables_ipaddr_to_numeric(&e->saddr.a4), xtables_ipmask_to_numeric(&e->smask.a4)); } }
static void tee_tg_print(const void *ip, const struct xt_entry_target *target, int numeric) { const struct xt_tee_tginfo *info = (const void *)target->data; if (numeric) printf(" TEE gw:%s", xtables_ipaddr_to_numeric(&info->gw.in)); else printf(" TEE gw:%s", xtables_ipaddr_to_anyname(&info->gw.in)); if (*info->oif != '\0') printf(" oif=%s", info->oif); }
/* iptables-save将按照该函数的实现来罗列规则 */ static void static_2_way_nat_tg_save(const void *entry, const struct xt_entry_target *target) { u_int32_t addr; const struct xt_static_nat_tginfo *info = (const void *)target->data; if (!info) { return; } addr = info->addr[0]; printf(" --mapaddr %s-", xtables_ipaddr_to_numeric((struct in_addr *)&addr)); addr = info->addr[1]; printf("%s --type %s --proto %s --mapport %d-%d --dev %s", xtables_ipaddr_to_numeric((struct in_addr *)&addr), (info->dir == DIR_SNAT)?"src":"dst", (info->proto == IPPROTO_TCP)?"tcp": ((info->proto == IPPROTO_UDP)?"udp":"all"), ntohs(info->port[0]), ntohs(info->port[1]), !strcmp(info->dev, "")?"all":info->dev); }
void nat64_tg4_print(const void *entry, const struct xt_entry_target *target, int numeric) { const struct xt_nat64_tginfo *info = (const void *)target->data; if (info->flags & XT_NAT64_IP_SRC) { printf("src IP "); if (numeric) printf("%s ", numeric ? xtables_ipaddr_to_numeric(&info->ipsrc.in) : xtables_ipaddr_to_anyname(&info->ipsrc.in)); } if (info->flags & XT_NAT64_IP_DST) { printf("dst IP "); printf("%s ", numeric ? xtables_ipaddr_to_numeric(&info->ipdst.in): xtables_ipaddr_to_anyname(&info->ipdst.in)); } }
static int tee_tg_xlate(const void *ip, const struct xt_entry_target *target, struct xt_xlate *xl, int numeric) { const struct xt_tee_tginfo *info = (const void *)target->data; if (numeric) xt_xlate_add(xl, "dup to %s", xtables_ipaddr_to_numeric(&info->gw.in)); else xt_xlate_add(xl, "dup to %s", xtables_ipaddr_to_anyname(&info->gw.in)); if (*info->oif != '\0') xt_xlate_add(xl, " device %s", info->oif); return 1; }
const char *xtables_ipmask_to_numeric(const struct in_addr *mask) { static char buf[20]; uint32_t cidr; cidr = xtables_ipmask_to_cidr(mask); if (cidr < 0) { /* mask was not a decent combination of 1's and 0's */ sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); return buf; } else if (cidr == 32) { /* we don't want to see "/32" */ return ""; } sprintf(buf, "/%d", cidr); return buf; }
static void print_addr(struct in_addr *addr, struct in_addr *mask, int inv, int numeric) { char buf[BUFSIZ]; if (inv) printf("! "); if (mask->s_addr == 0L && !numeric) printf("%s ", "anywhere"); else { if (numeric) strcpy(buf, xtables_ipaddr_to_numeric(addr)); else strcpy(buf, xtables_ipaddr_to_anyname(addr)); strcat(buf, xtables_ipmask_to_numeric(mask)); printf("%s ", buf); } }
static struct in_addr *host_to_ipaddr(const char *name, unsigned int *naddr) { struct in_addr *addr; struct addrinfo hints; struct addrinfo *res, *p; int err; unsigned int i; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_RAW; *naddr = 0; if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { #ifdef DEBUG fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); #endif return NULL; } else { for (p = res; p != NULL; p = p->ai_next) ++*naddr; #ifdef DEBUG fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, xtables_ipaddr_to_numeric(&((struct sockaddr_in *)res->ai_addr)->sin_addr)); #endif addr = xtables_calloc(*naddr, sizeof(struct in_addr)); for (i = 0, p = res; p != NULL; p = p->ai_next) memcpy(&addr[i++], &((const struct sockaddr_in *)p->ai_addr)->sin_addr, sizeof(struct in_addr)); freeaddrinfo(res); return addr; } return NULL; }
const char *xtables_ipmask_to_numeric(const struct in_addr *mask) { static char buf[20]; uint32_t maskaddr, bits; int i; maskaddr = ntohl(mask->s_addr); if (maskaddr == 0xFFFFFFFFL) /* we don't want to see "/32" */ return ""; i = 32; bits = 0xFFFFFFFEL; while (--i >= 0 && maskaddr != bits) bits <<= 1; if (i >= 0) sprintf(buf, "/%d", i); else /* mask was not a decent combination of 1's and 0's */ sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); return buf; }