NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: iscsid - lfs and ipv6 issues



kre%munnari.OZ.AU@localhost (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");
 


Home | Main Index | Thread Index | Old Index