k...@munnari.oz.au (Robert Elz) writes: > | The address parser looks broken. >It certainly is, it is horrid.
>and the relevant function is get_address() Maybe the patch below. It's still a bit naive (you can bracket anything, not just ipv6 literals). The address string is later used in iscsid_driverif.c, a name is resolved with gethostbyname(), so while an ipv6 address might be accepted, the code lacks ipv6 support. Index: sbin/iscsictl/iscsic_parse.c =================================================================== RCS file: /cvsroot/src/sbin/iscsictl/iscsic_parse.c,v retrieving revision 1.4 diff -p -u -r1.4 iscsic_parse.c --- sbin/iscsictl/iscsic_parse.c 3 Dec 2021 13:27:38 -0000 1.4 +++ sbin/iscsictl/iscsic_parse.c 18 Nov 2023 10:35:17 -0000 @@ -48,50 +48,55 @@ STATIC void get_address(iscsi_portal_address_t * portal, char *str, char *arg) { - char *sp, *sp2; + char *sp; int val; if (!str || !*str) arg_error(arg, "Address is missing"); - /* is there a port? don't check inside square brackets (IPv6 addr) */ - for (sp = str + 1, val = 0; *sp && (*sp != ':' || val); sp++) { - if (*sp == '[') - val = 1; - else if (*sp == ']') - val = 0; - } - - /* */ - if (*sp) { - for (sp2 = sp + 1; *sp2 && *sp2 != ':'; sp2++); - /* if there's a second colon, assume it's an unbracketed IPv6 address */ - if (!*sp2) { - /* truncate source, that's the address */ - *sp++ = '\0'; - if (sscanf(sp, "%d", &val) != 1) - arg_error(arg, "Bad address format: Expected port number"); - if (val < 0 || val > 0xffff) - arg_error(arg, "Bad address format: Port number out of range"); - portal->port = (uint16_t) val; - } - /* is there a group tag? */ - for (; isdigit((unsigned char)*sp); sp++); - if (*sp && *sp != ',') - arg_error(arg, "Bad address format: Extra character(s) '%c'", *sp); - } else - for (sp = str + 1; *sp && *sp != ','; sp++); - - if (*sp) { + /* parse and strip trailing group tag */ + sp = strchr(str, ','); + if (sp != NULL) { if (sscanf(sp + 1, "%d", &val) != 1) arg_error(arg, "Bad address format: Expected group tag"); if (val < 0 || val > 0xffff) arg_error(arg, "Bad address format: Group tag out of range"); portal->group_tag = (uint16_t) val; - /* truncate source, that's the address */ *sp = '\0'; } - /* only check length, don't verify correct format (too many possibilities) */ + + /* parse and strip trailing port number */ + sp = strchr(str, ':'); + if (sp != NULL) { + if (strchr(sp + 1, ':') != NULL) { + /* + * if there's a second colon, assume + * it's an unbracketed IPv6 address. + */ + portal->port = 0; + } else { + if (sscanf(sp + 1, "%d", &val) != 1) + arg_error(arg, "Bad address format: Expected port number"); + if (val < 0 || val > 0xffff) + arg_error(arg, "Bad address format: Port number out of range"); + portal->port = (uint16_t) val; + *sp = '\0'; + } + } + + /* remove brackets */ + if (*str == '[') { + sp = strchr(str, ']'); + if (sp != NULL && !*(sp+1)) { + str = str + 1; + *sp = '\0'; + } + } + + /* + * only check length, don't verify correct format + * (too many possibilities) + */ if (strlen(str) >= sizeof(portal->address)) arg_error(arg, "Bad address format: Address string too long");