/* * PARSER. Field 2 in ARGP. */ static int parse_opt(int key, char *arg, struct argp_state *state) { struct arguments *arguments = state->input; int error = 0; __u16 temp; switch (key) { case ARGP_POOL6: arguments->mode = MODE_POOL6; break; case ARGP_POOL4: arguments->mode = MODE_POOL4; break; case ARGP_BIB: arguments->mode = MODE_BIB; break; case ARGP_SESSION: arguments->mode = MODE_SESSION; break; case ARGP_FILTERING: arguments->mode = MODE_FILTERING; break; case ARGP_TRANSLATE: arguments->mode = MODE_TRANSLATE; break; case ARGP_DISPLAY: arguments->operation = OP_DISPLAY; break; case ARGP_ADD: arguments->operation = OP_ADD; break; case ARGP_REMOVE: arguments->operation = OP_REMOVE; break; case ARGP_UDP: arguments->udp = true; break; case ARGP_TCP: arguments->tcp = true; break; case ARGP_ICMP: arguments->icmp = true; break; case ARGP_ADDRESS: error = str_to_addr4(arg, &arguments->pool4_addr); arguments->pool4_addr_set = true; break; case ARGP_PREFIX: error = str_to_prefix(arg, &arguments->pool6_prefix); arguments->pool6_prefix_set = true; break; // case ARGP_STATIC: // arguments->static_entries = true; // break; // case ARGP_DYNAMIC: // arguments->dynamic_entries = true; // break; // // case ARGP_IPV6: // error = str_to_addr6_port(arg, &arguments->bib_addr6); // arguments->bib_addr6_set = true; // break; // case ARGP_IPV4: // error = str_to_addr4_port(arg, &arguments->bib_addr4); // arguments->bib_addr4_set = true; // break; case ARGP_REMOTE6: error = str_to_addr6_port(arg, &arguments->session_pair6.remote); arguments->session_pair6_remote_set = true; break; case ARGP_LOCAL6: error = str_to_addr6_port(arg, &arguments->session_pair6.local); arguments->session_pair6_local_set = true; break; case ARGP_LOCAL4: error = str_to_addr4_port(arg, &arguments->session_pair4.local); arguments->session_pair4_local_set = true; break; case ARGP_REMOTE4: error = str_to_addr4_port(arg, &arguments->session_pair4.remote); arguments->session_pair4_remote_set = true; break; case ARGP_DROP_ADDR: arguments->mode = MODE_FILTERING; arguments->operation |= DROP_BY_ADDR_MASK; error = str_to_bool(arg, &arguments->filtering.drop_by_addr); break; case ARGP_DROP_INFO: arguments->mode = MODE_FILTERING; arguments->operation |= DROP_ICMP6_INFO_MASK; error = str_to_bool(arg, &arguments->filtering.drop_icmp6_info); break; // case ARGP_DROP_TCP: // arguments->mode = MODE_FILTERING; // arguments->operation |= DROP_EXTERNAL_TCP_MASK; // error = str_to_bool(arg, &arguments->filtering.drop_external_tcp); // break; case ARGP_UDP_TO: arguments->mode = MODE_FILTERING; arguments->operation |= UDP_TIMEOUT_MASK; error = str_to_u16(arg, &temp, UDP_MIN, 0xFFFF); arguments->filtering.to.udp = temp; break; case ARGP_ICMP_TO: arguments->mode = MODE_FILTERING; arguments->operation |= ICMP_TIMEOUT_MASK; error = str_to_u16(arg, &temp, 0, 0xFFFF); arguments->filtering.to.icmp = temp; break; case ARGP_TCP_TO: arguments->mode = MODE_FILTERING; arguments->operation |= TCP_EST_TIMEOUT_MASK; error = str_to_u16(arg, &temp, TCP_EST, 0xFFFF); arguments->filtering.to.tcp_est = temp; break; case ARGP_TCP_TRANS_TO: arguments->mode = MODE_FILTERING; arguments->operation |= TCP_TRANS_TIMEOUT_MASK; error = str_to_u16(arg, &temp, TCP_TRANS, 0xFFFF); arguments->filtering.to.tcp_trans = temp; break; case ARGP_HEAD: arguments->mode = MODE_TRANSLATE; arguments->operation |= SKB_HEAD_ROOM_MASK; error = str_to_u16(arg, &arguments->translate.skb_head_room, 0, 0xFFFF); break; case ARGP_TAIL: arguments->mode = MODE_TRANSLATE; arguments->operation |= SKB_TAIL_ROOM_MASK; error = str_to_u16(arg, &arguments->translate.skb_tail_room, 0, 0xFFFF); break; case ARGP_RESET_TCLASS: arguments->mode = MODE_TRANSLATE; arguments->operation |= RESET_TCLASS_MASK; error = str_to_bool(arg, &arguments->translate.reset_traffic_class); break; case ARGP_RESET_TOS: arguments->mode = MODE_TRANSLATE; arguments->operation |= RESET_TOS_MASK; error = str_to_bool(arg, &arguments->translate.reset_tos); break; case ARGP_NEW_TOS: arguments->mode = MODE_TRANSLATE; arguments->operation |= NEW_TOS_MASK; error = str_to_u8(arg, &arguments->translate.new_tos, 0, 0xFF); break; case ARGP_DF: arguments->mode = MODE_TRANSLATE; arguments->operation |= DF_ALWAYS_ON_MASK; error = str_to_bool(arg, &arguments->translate.df_always_on); break; case ARGP_BUILD_ID: arguments->mode = MODE_TRANSLATE; arguments->operation |= BUILD_IPV4_ID_MASK; error = str_to_bool(arg, &arguments->translate.build_ipv4_id); break; case ARGP_LOWER_MTU_FAIL: arguments->mode = MODE_TRANSLATE; arguments->operation |= LOWER_MTU_FAIL_MASK; error = str_to_bool(arg, &arguments->translate.lower_mtu_fail); break; case ARGP_NEXT_MTU6: arguments->mode = MODE_TRANSLATE; arguments->operation |= IPV6_NEXTHOP_MTU_MASK; error = str_to_u16(arg, &arguments->translate.ipv6_nexthop_mtu, 0, 0xFFFF); break; case ARGP_NEXT_MTU4: arguments->mode = MODE_TRANSLATE; arguments->operation |= IPV4_NEXTHOP_MTU_MASK; error = str_to_u16(arg, &arguments->translate.ipv4_nexthop_mtu, 0, 0xFFFF); break; case ARGP_PLATEAUS: arguments->mode = MODE_TRANSLATE; arguments->operation |= MTU_PLATEAUS_MASK; error = str_to_u16_array(arg, &arguments->translate.mtu_plateaus, &arguments->translate.mtu_plateau_count); break; default: return ARGP_ERR_UNKNOWN; } return error; }
/* * PARSER. Field 2 in ARGP. */ static int parse_opt(int key, char *str, struct argp_state *state) { struct arguments *args = state->input; int error = 0; switch (key) { case ARGP_POOL6: error = update_state(args, MODE_POOL6, POOL6_OPS); break; case ARGP_POOL4: error = update_state(args, MODE_POOL4, POOL4_OPS); break; case ARGP_BIB: error = update_state(args, MODE_BIB, BIB_OPS); break; case ARGP_SESSION: error = update_state(args, MODE_SESSION, SESSION_OPS); break; #ifdef BENCHMARK case ARGP_LOGTIME: error = update_state(args, MODE_LOGTIME, LOGTIME_OPS); break; #endif case ARGP_GENERAL: error = update_state(args, MODE_GENERAL, GENERAL_OPS); break; case ARGP_DISPLAY: error = update_state(args, DISPLAY_MODES, OP_DISPLAY); break; case ARGP_COUNT: error = update_state(args, COUNT_MODES, OP_COUNT); break; case ARGP_ADD: error = update_state(args, ADD_MODES, OP_ADD); break; case ARGP_UPDATE: error = update_state(args, UPDATE_MODES, OP_UPDATE); break; case ARGP_REMOVE: error = update_state(args, REMOVE_MODES, OP_REMOVE); break; case ARGP_FLUSH: error = update_state(args, FLUSH_MODES, OP_FLUSH); break; case ARGP_UDP: error = update_state(args, MODE_BIB | MODE_SESSION, BIB_OPS | SESSION_OPS); args->db.tables.udp = true; break; case ARGP_TCP: error = update_state(args, MODE_BIB | MODE_SESSION, BIB_OPS | SESSION_OPS); args->db.tables.tcp = true; break; case ARGP_ICMP: error = update_state(args, MODE_BIB | MODE_SESSION, BIB_OPS | SESSION_OPS); args->db.tables.icmp = true; break; case ARGP_NUMERIC_HOSTNAME: error = update_state(args, MODE_BIB | MODE_SESSION, OP_DISPLAY); args->db.tables.numeric_hostname = true; break; case ARGP_CSV: error = update_state(args, MODE_BIB | MODE_SESSION, OP_DISPLAY); args->db.tables.csv_format = true; break; case ARGP_ADDRESS: error = update_state(args, MODE_POOL4, OP_ADD | OP_REMOVE); if (error) return error; error = str_to_addr4(str, &args->db.pool4.addr); args->db.pool4.addr_set = true; break; case ARGP_PREFIX: error = update_state(args, MODE_POOL6, OP_ADD | OP_REMOVE); if (error) return error; error = str_to_prefix(str, &args->db.pool6.prefix); args->db.pool6.prefix_set = true; break; case ARGP_QUICK: error = update_state(args, MODE_POOL6 | MODE_POOL4, OP_REMOVE | OP_FLUSH); args->db.quick = true; break; case ARGP_BIB_IPV6: error = update_state(args, MODE_BIB, OP_ADD | OP_REMOVE); if (error) return error; error = str_to_addr6_port(str, &args->db.tables.bib.addr6); args->db.tables.bib.addr6_set = true; break; case ARGP_BIB_IPV4: error = update_state(args, MODE_BIB, OP_ADD | OP_REMOVE); if (error) return error; error = str_to_addr4_port(str, &args->db.tables.bib.addr4); args->db.tables.bib.addr4_set = true; break; case ARGP_DROP_ADDR: error = set_general_bool(args, FILTERING, DROP_BY_ADDR, str); break; case ARGP_DROP_INFO: error = set_general_bool(args, FILTERING, DROP_ICMP6_INFO, str); break; case ARGP_DROP_TCP: error = set_general_bool(args, FILTERING, DROP_EXTERNAL_TCP, str); break; case ARGP_UDP_TO: error = set_general_u64(args, SESSIONDB, UDP_TIMEOUT, str, UDP_MIN, MAX_U32/1000, 1000); break; case ARGP_ICMP_TO: error = set_general_u64(args, SESSIONDB, ICMP_TIMEOUT, str, 0, MAX_U32/1000, 1000); break; case ARGP_TCP_TO: error = set_general_u64(args, SESSIONDB, TCP_EST_TIMEOUT, str, TCP_EST, MAX_U32/1000, 1000); break; case ARGP_TCP_TRANS_TO: error = set_general_u64(args, SESSIONDB, TCP_TRANS_TIMEOUT, str, TCP_TRANS, MAX_U32/1000, 1000); break; case ARGP_STORED_PKTS: error = set_general_u64(args, PKTQUEUE, MAX_PKTS, str, 0, MAX_U64, 1); break; case ARGP_RESET_TCLASS: error = set_general_bool(args, TRANSLATE, RESET_TCLASS, str); break; case ARGP_RESET_TOS: error = set_general_bool(args, TRANSLATE, RESET_TOS, str); break; case ARGP_NEW_TOS: error = set_general_u8(args, TRANSLATE, NEW_TOS, str, 0, MAX_U8); break; case ARGP_DF: error = set_general_bool(args, TRANSLATE, DF_ALWAYS_ON, str); break; case ARGP_BUILD_ID: error = set_general_bool(args, TRANSLATE, BUILD_IPV4_ID, str); break; case ARGP_LOWER_MTU_FAIL: error = set_general_bool(args, TRANSLATE, LOWER_MTU_FAIL, str); break; case ARGP_PLATEAUS: error = set_general_u16_array(args, TRANSLATE, MTU_PLATEAUS, str); break; case ARGP_MIN_IPV6_MTU: error = set_general_u16(args, SENDPKT, MIN_IPV6_MTU, str, 1280, MAX_U16); break; case ARGP_FRAG_TO: error = set_general_u64(args, FRAGMENT, FRAGMENT_TIMEOUT, str, FRAGMENT_MIN, MAX_U32/1000, 1000); break; default: error = ARGP_ERR_UNKNOWN; } return error; }