RADIUS_PDU *radius_pdu_unpack(Octstr *data_without_len) { RADIUS_PDU *pdu; int type, ident; long len, pos; ParseContext *context; Octstr *authenticator; len = octstr_len(data_without_len); if (len < 20) { error(0, "RADIUS: PDU was too short (%ld bytes).", octstr_len(data_without_len)); return NULL; } context = parse_context_create(data_without_len); type = parse_get_char(context); ident = parse_get_char(context); pdu = radius_pdu_create(type, NULL); if (pdu == NULL) return NULL; len = decode_integer(data_without_len, 2, 2) - 19; parse_skip(context, 2); debug("radius", 0, "RADIUS: Attributes len is %ld", len); authenticator = parse_get_octets(context, 16); octstr_dump_short(authenticator, 0, "RADIUS: Authenticator (md5) is:"); /* skipping back to context start for macro magic */ parse_context_destroy(context); context = parse_context_create(data_without_len); switch (type) { #define INTEGER(name, octets) \ pos = octstr_len(data_without_len) - parse_octets_left(context); \ p->name = decode_integer(data_without_len, pos, octets); \ parse_skip(context, octets); #define OCTETS(name, field_giving_octets) \ p->name = parse_get_octets(context, field_giving_octets); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields; \ radius_attr_unpack(&context, &pdu); } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while unpacking."); } parse_context_destroy(context); octstr_destroy(authenticator); return pdu; }
/* * Parse command line arguments. */ static int parse_command_line(int ac, char **av, idncheck_option_t *option) { ac--; av++; while (ac > 0 && **av == '-') { if (strcmp(*av, "--") == 0) { ac--; av++; break; } else if (strcmp(*av, "-in") == 0 || strcmp(*av, "-i") == 0) { if (ac < 2) { errormsg("option '%s' requires an argument.\n", *av); return (0); } option->in_code = av[1]; ac--; av++; } else if (strcmp(*av, "-conf") == 0 || strcmp(*av, "-c") == 0) { if (ac < 2) { errormsg("option '%s' requires an argument.\n", *av); return (0); } option->conf_file = av[1]; ac--; av++; } else if (strcmp(*av, "-noconf") == 0 || strcmp(*av, "-C") == 0) { option->no_conf = 1; } else if (strcmp(*av, "-registration") == 0 || strcmp(*av, "-g") == 0) { option->protocol = idncheck_registration; } else if (strcmp(*av, "-lookup") == 0 || strcmp(*av, "-l") == 0) { option->protocol = idncheck_lookup; } else if (strcmp(*av, "-nomap") == 0 || strcmp(*av, "-M") == 0) { if (!parse_skip("map", &option->skip_actions)) return (0); } else if (strcmp(*av, "-skip") == 0) { if (ac < 2) { errormsg("option '%s' requires an argument.\n", *av); return (0); } if (!parse_skip(av[1], &option->skip_actions)) { errormsg("invalid argument to option '-skip'.\n", *av); return (0); } ac--; av++; } else if (strcmp(*av, "-localcheck") == 0 || strcmp(*av, "-e") == 0) { if (ac < 2) { errormsg("option '%s' requires an argument.\n", *av); return (0); } option->localcheck_file = av[1]; ac--; av++; } else if (strcmp(*av, "-quiet") == 0 || strcmp(*av, "-q") == 0) { option->quiet = 1; } else if (strcmp(*av, "-test") == 0 || strcmp(*av, "-t") == 0) { option->test = 1; } else if (strcmp(*av, "-version") == 0 || strcmp(*av, "-v") == 0) { print_version(); exit(IDNCHECK_EXITCODE_SUCCESS); } else if (strcmp(*av, "-help") == 0 || strcmp(*av, "-h") == 0) { print_usage(); exit(IDNCHECK_EXITCODE_SUCCESS); } else { errormsg("unrecognized option '%s'.\n", *av); return (0); } ac--; av++; } if (option->test) { option->name = ""; } else if (ac > 1) { errormsg("too many arguments.\n"); return (0); } else if (ac < 1) { errormsg("too few argument.\n"); return (0); } else { option->name = av[0]; } /* * Resolve conflicts between options. */ if (option->no_conf && option->conf_file != NULL) option->conf_file = NULL; return (1); }