diff options
Diffstat (limited to 'extensions/libxt_sctp.c')
-rw-r--r-- | extensions/libxt_sctp.c | 116 |
1 files changed, 82 insertions, 34 deletions
diff --git a/extensions/libxt_sctp.c b/extensions/libxt_sctp.c index 140de265..6e2b2745 100644 --- a/extensions/libxt_sctp.c +++ b/extensions/libxt_sctp.c @@ -50,7 +50,7 @@ static void sctp_help(void) " --dport ...\n" "[!] --chunk-types (all|any|none) (chunktype[:flags])+ match if all, any or none of\n" " chunktypes are present\n" -"chunktypes - DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE ASCONF ASCONF_ACK FORWARD_TSN ALL NONE\n"); +"chunktypes - DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE I_DATA RE_CONFIG PAD ASCONF ASCONF_ACK FORWARD_TSN I_FORWARD_TSN ALL NONE\n"); } static const struct option sctp_opts[] = { @@ -69,7 +69,7 @@ parse_sctp_ports(const char *portstring, char *buffer; char *cp; - buffer = strdup(portstring); + buffer = xtables_strdup(portstring); DEBUGP("%s\n", portstring); if ((cp = strchr(buffer, ':')) == NULL) { ports[0] = ports[1] = xtables_parse_port(buffer, "sctp"); @@ -92,28 +92,33 @@ struct sctp_chunk_names { const char *name; unsigned int chunk_type; const char *valid_flags; + const char *nftname; }; /*'ALL' and 'NONE' will be treated specially. */ static const struct sctp_chunk_names sctp_chunk_names[] -= { { .name = "DATA", .chunk_type = 0, .valid_flags = "----IUBE"}, - { .name = "INIT", .chunk_type = 1, .valid_flags = "--------"}, - { .name = "INIT_ACK", .chunk_type = 2, .valid_flags = "--------"}, - { .name = "SACK", .chunk_type = 3, .valid_flags = "--------"}, - { .name = "HEARTBEAT", .chunk_type = 4, .valid_flags = "--------"}, - { .name = "HEARTBEAT_ACK", .chunk_type = 5, .valid_flags = "--------"}, - { .name = "ABORT", .chunk_type = 6, .valid_flags = "-------T"}, - { .name = "SHUTDOWN", .chunk_type = 7, .valid_flags = "--------"}, - { .name = "SHUTDOWN_ACK", .chunk_type = 8, .valid_flags = "--------"}, - { .name = "ERROR", .chunk_type = 9, .valid_flags = "--------"}, - { .name = "COOKIE_ECHO", .chunk_type = 10, .valid_flags = "--------"}, - { .name = "COOKIE_ACK", .chunk_type = 11, .valid_flags = "--------"}, - { .name = "ECN_ECNE", .chunk_type = 12, .valid_flags = "--------"}, - { .name = "ECN_CWR", .chunk_type = 13, .valid_flags = "--------"}, - { .name = "SHUTDOWN_COMPLETE", .chunk_type = 14, .valid_flags = "-------T"}, - { .name = "ASCONF", .chunk_type = 193, .valid_flags = "--------"}, - { .name = "ASCONF_ACK", .chunk_type = 128, .valid_flags = "--------"}, - { .name = "FORWARD_TSN", .chunk_type = 192, .valid_flags = "--------"}, += { { .name = "DATA", .chunk_type = 0, .valid_flags = "----IUBE", .nftname = "data" }, + { .name = "INIT", .chunk_type = 1, .valid_flags = "--------", .nftname = "init" }, + { .name = "INIT_ACK", .chunk_type = 2, .valid_flags = "--------", .nftname = "init-ack" }, + { .name = "SACK", .chunk_type = 3, .valid_flags = "--------", .nftname = "sack" }, + { .name = "HEARTBEAT", .chunk_type = 4, .valid_flags = "--------", .nftname = "heartbeat" }, + { .name = "HEARTBEAT_ACK", .chunk_type = 5, .valid_flags = "--------", .nftname = "heartbeat-ack" }, + { .name = "ABORT", .chunk_type = 6, .valid_flags = "-------T", .nftname = "abort" }, + { .name = "SHUTDOWN", .chunk_type = 7, .valid_flags = "--------", .nftname = "shutdown" }, + { .name = "SHUTDOWN_ACK", .chunk_type = 8, .valid_flags = "--------", .nftname = "shutdown-ack" }, + { .name = "ERROR", .chunk_type = 9, .valid_flags = "--------", .nftname = "error" }, + { .name = "COOKIE_ECHO", .chunk_type = 10, .valid_flags = "--------", .nftname = "cookie-echo" }, + { .name = "COOKIE_ACK", .chunk_type = 11, .valid_flags = "--------", .nftname = "cookie-ack" }, + { .name = "ECN_ECNE", .chunk_type = 12, .valid_flags = "--------", .nftname = "ecne" }, + { .name = "ECN_CWR", .chunk_type = 13, .valid_flags = "--------", .nftname = "cwr" }, + { .name = "SHUTDOWN_COMPLETE", .chunk_type = 14, .valid_flags = "-------T", .nftname = "shutdown-complete" }, + { .name = "I_DATA", .chunk_type = 64, .valid_flags = "----IUBE", .nftname = "i-data"}, + { .name = "RE_CONFIG", .chunk_type = 130, .valid_flags = "--------", .nftname = "re-config"}, + { .name = "PAD", .chunk_type = 132, .valid_flags = "--------", .nftname = "pad"}, + { .name = "ASCONF", .chunk_type = 193, .valid_flags = "--------", .nftname = "asconf" }, + { .name = "ASCONF_ACK", .chunk_type = 128, .valid_flags = "--------", .nftname = "asconf-ack" }, + { .name = "FORWARD_TSN", .chunk_type = 192, .valid_flags = "--------", .nftname = "forward-tsn" }, + { .name = "I_FORWARD_TSN", .chunk_type = 194, .valid_flags = "--------", .nftname = "i-forward-tsn" }, }; static void @@ -139,10 +144,8 @@ save_chunk_flag_info(struct xt_sctp_flag_info *flag_info, } if (*flag_count == XT_NUM_SCTP_FLAGS) { - xtables_error (PARAMETER_PROBLEM, - "Number of chunk types with flags exceeds currently allowed limit." - "Increasing this limit involves changing IPT_NUM_SCTP_FLAGS and" - "recompiling both the kernel space and user space modules\n"); + xtables_error(PARAMETER_PROBLEM, + "Number of chunk types with flags exceeds currently allowed limit. Increasing this limit involves changing IPT_NUM_SCTP_FLAGS and recompiling both the kernel space and user space modules"); } flag_info[*flag_count].chunktype = chunktype; @@ -163,7 +166,7 @@ parse_sctp_chunk(struct xt_sctp_info *einfo, int found = 0; char *chunk_flags; - buffer = strdup(chunks); + buffer = xtables_strdup(chunks); DEBUGP("Buffer: %s\n", buffer); SCTP_CHUNKMAP_RESET(einfo->chunkmap); @@ -214,7 +217,8 @@ parse_sctp_chunk(struct xt_sctp_info *einfo, isupper(chunk_flags[j])); } else { xtables_error(PARAMETER_PROBLEM, - "Invalid flags for chunk type %d\n", i); + "Invalid flags for chunk type %d", + i); } } } @@ -485,41 +489,85 @@ static void sctp_save(const void *ip, const struct xt_entry_match *match) } } +static void sctp_xlate_chunk(struct xt_xlate *xl, + const struct xt_sctp_info *einfo, + const struct sctp_chunk_names *scn) +{ + bool inv = einfo->invflags & XT_SCTP_CHUNK_TYPES; + const struct xt_sctp_flag_info *flag_info = NULL; + int i; + + if (!scn->nftname) + return; + + if (!SCTP_CHUNKMAP_IS_SET(einfo->chunkmap, scn->chunk_type)) { + if (einfo->chunk_match_type != SCTP_CHUNK_MATCH_ONLY) + return; + + xt_xlate_add(xl, "sctp chunk %s %s", + scn->nftname, inv ? "exists" : "missing"); + return; + } + + for (i = 0; i < einfo->flag_count; i++) { + if (einfo->flag_info[i].chunktype == scn->chunk_type) { + flag_info = &einfo->flag_info[i]; + break; + } + } + + if (!flag_info) { + xt_xlate_add(xl, "sctp chunk %s %s", + scn->nftname, inv ? "missing" : "exists"); + return; + } + + xt_xlate_add(xl, "sctp chunk %s flags & 0x%x %s 0x%x", + scn->nftname, flag_info->flag_mask, + inv ? "!=" : "==", flag_info->flag); +} + static int sctp_xlate(struct xt_xlate *xl, const struct xt_xlate_mt_params *params) { const struct xt_sctp_info *einfo = (const struct xt_sctp_info *)params->match->data; - char *space = ""; if (!einfo->flags) return 0; - xt_xlate_add(xl, "sctp "); - if (einfo->flags & XT_SCTP_SRC_PORTS) { if (einfo->spts[0] != einfo->spts[1]) - xt_xlate_add(xl, "sport%s %u-%u", + xt_xlate_add(xl, "sctp sport%s %u-%u", einfo->invflags & XT_SCTP_SRC_PORTS ? " !=" : "", einfo->spts[0], einfo->spts[1]); else - xt_xlate_add(xl, "sport%s %u", + xt_xlate_add(xl, "sctp sport%s %u", einfo->invflags & XT_SCTP_SRC_PORTS ? " !=" : "", einfo->spts[0]); - space = " "; } if (einfo->flags & XT_SCTP_DEST_PORTS) { if (einfo->dpts[0] != einfo->dpts[1]) - xt_xlate_add(xl, "%sdport%s %u-%u", space, + xt_xlate_add(xl, "sctp dport%s %u-%u", einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", einfo->dpts[0], einfo->dpts[1]); else - xt_xlate_add(xl, "%sdport%s %u", space, + xt_xlate_add(xl, "sctp dport%s %u", einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", einfo->dpts[0]); } + if (einfo->flags & XT_SCTP_CHUNK_TYPES) { + int i; + + if (einfo->chunk_match_type == SCTP_CHUNK_MATCH_ANY) + return 0; + + for (i = 0; i < ARRAY_SIZE(sctp_chunk_names); i++) + sctp_xlate_chunk(xl, einfo, &sctp_chunk_names[i]); + } + return 1; } |