From patchwork Thu May 24 04:47:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 919572 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40rxkH2t0Lz9s0q for ; Thu, 24 May 2018 14:49:27 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="npPYJglY"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="G3ObZIRn"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40rxkH0rVJzF1Hr for ; Thu, 24 May 2018 14:49:27 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="npPYJglY"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="G3ObZIRn"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.28; helo=out4-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="npPYJglY"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="G3ObZIRn"; dkim-atps=neutral Received: from out4-smtp.messagingengine.com (out4-smtp.messagingengine.com [66.111.4.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40rxhm25cRzF1LK for ; Thu, 24 May 2018 14:48:08 +1000 (AEST) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 9E9A021C2C; Thu, 24 May 2018 00:48:05 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Thu, 24 May 2018 00:48:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=wrvCvfjgs6HPZ5AhVGAALUsijxOOV2xutCtUB2FKzVk=; b=npPYJglY nTpvjcatCb12JjNfsf0TT4vrUkGR6eBP2TRBFMNa7kjFtzC/OPbmXOROMIr+RVGw 8x1zc3SpI6Yci4+yEkfmOaGkcQcWgOmiTDVSwIaMB57wRalbUsMqIa0PLc5/1eB9 vZkVUIZbnKHP6KS18cOJXbsZKFJ0cxlI8bIeSZci5E+cj13DjvnTkJiKOoOgTAVV Eyr5SwtdJVxqjV3coKzQFDqhZ75zAmF1hyTn/pt9prnEIYljtu83SbEXt63CWXNc /3w8UpsIjNg7I6NMVu6AYBFYI0j/rWF3a2/PQ9l1adxphstKMHkTwyxngLmEwpJj ecNa9YC6ZeDH0A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=wrvCvfjgs6HPZ5AhVGAALUsijxOOV2xutCtUB2FKzVk=; b=G3ObZIRn Zu0AH9tahocwsGkar2olB0iOsQM0g3McDUtl4EcoltF7W0F7ThXyJSDpY9Au9onH 3rZ//miqO/HWMdIdjN1bEbm0vljWRBYMwiuIdWRcxUYQ+CSVMZ7syEW5GATcECu8 2hy7sPRcui4taKsZCuO0iV8jTacbrRKXn3M11WLEGAn8WaoV1ORKL6hd/sKyvduo b5MQ4nqbvXJRAvMY0m4INb4ICHI74FKNeDQsvZhqKmnf54szV7raxuX+iWh6N7ys 7g6MPSjX0iUZKPBXkBkj0YsHdVb8wFYeMP3pMKtfbqHFCfN+1idAwMRlqexbNu6F fvL5iFmG7ZEviA== X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Proxy: X-ME-Sender: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 58A651025E; Thu, 24 May 2018 00:48:04 -0400 (EDT) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [PATCH v2 9/9] ui/ncurses: Allow IPv6 addresses in address fields Date: Thu, 24 May 2018 14:47:42 +1000 Message-Id: <20180524044742.25889-10-sam@mendozajonas.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180524044742.25889-1-sam@mendozajonas.com> References: <20180524044742.25889-1-sam@mendozajonas.com> X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Signed-off-by: Samuel Mendoza-Jonas --- ui/ncurses/nc-config.c | 8 +-- ui/ncurses/nc-widgets.c | 115 +++++++++++++++++++++++++++------------- ui/ncurses/nc-widgets.h | 4 +- 3 files changed, 84 insertions(+), 43 deletions(-) diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c index 5c0f23b..5186176 100644 --- a/ui/ncurses/nc-config.c +++ b/ui/ncurses/nc-config.c @@ -1029,8 +1029,8 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_textbox_set_fixed_size(screen->widgets.ip_addr_f); widget_textbox_set_fixed_size(screen->widgets.ip_mask_f); - widget_textbox_set_validator_ipv4(screen->widgets.ip_addr_f); - widget_textbox_set_validator_integer(screen->widgets.ip_mask_f, 1, 31); + widget_textbox_set_validator_ip(screen->widgets.ip_addr_f); + widget_textbox_set_validator_integer(screen->widgets.ip_mask_f, 1, 127); screen->widgets.gateway_l = widget_new_label(set, 0, 0, _("Gateway:")); screen->widgets.gateway_f = widget_new_textbox(set, 0, 0, 16, gw); @@ -1038,7 +1038,7 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_new_label(set, 0, 0, _("(eg. 192.168.0.1)")); widget_textbox_set_fixed_size(screen->widgets.gateway_f); - widget_textbox_set_validator_ipv4(screen->widgets.gateway_f); + widget_textbox_set_validator_ip(screen->widgets.gateway_f); screen->widgets.url_l = widget_new_label(set, 0, 0, _("URL:")); screen->widgets.url_f = widget_new_textbox(set, 0, 0, 32, url); @@ -1059,7 +1059,7 @@ static void config_screen_setup_widgets(struct config_screen *screen, screen->widgets.dns_help_l = widget_new_label(set, 0, 0, _("(eg. 192.168.0.2)")); - widget_textbox_set_validator_ipv4_multi(screen->widgets.dns_f); + widget_textbox_set_validator_ip_multi(screen->widgets.dns_f); screen->widgets.dns_dhcp_help_l = widget_new_label(set, 0, 0, _("(if not provided by DHCP server)")); diff --git a/ui/ncurses/nc-widgets.c b/ui/ncurses/nc-widgets.c index 93c882b..30915a9 100644 --- a/ui/ncurses/nc-widgets.c +++ b/ui/ncurses/nc-widgets.c @@ -44,8 +44,10 @@ # error "Curses form.h not found." #endif -#include +#include #include +#include +#include #include #include @@ -83,7 +85,8 @@ struct nc_widgetset { FIELD *cur_field; /* custom validators */ - FIELDTYPE *ipv4_multi_type; + FIELDTYPE *ip_multi_type; + FIELDTYPE *ip_type; FIELDTYPE *url_type; }; @@ -415,54 +418,88 @@ void widget_textbox_set_validator_url(struct nc_widget_textbox *textbox) set_field_type(textbox->widget.field, textbox->set->url_type); } -void widget_textbox_set_validator_ipv4(struct nc_widget_textbox *textbox) +static bool check_ip_field(FIELD *field, + const void *arg __attribute__((unused))) +{ + char *str; + int rc; + + str = strip_string(field_buffer(field, 0)); + + rc = addr_scheme(str); + + return (rc == AF_INET || rc == AF_INET6); +} + + +static bool check_ipv6_multi_char(int c) { - set_field_type(textbox->widget.field, TYPE_IPV4); + return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || + c == ':' || c == ' '; } -static bool check_ipv4_multi_char(int c, - const void *arg __attribute__((unused))) +static bool check_ipv4_multi_char(int c) { return isdigit(c) || c == '.' || c == ' '; } -static bool check_ipv4_multi_field(FIELD *field, +static bool check_ip_multi_field(FIELD *field, const void *arg __attribute__((unused))) { - char *buf = field_buffer(field, 0); - unsigned int ip[4]; - int n, len; - - while (*buf != '\0') { - n = sscanf(buf, "%u.%u.%u.%u%n", - &ip[0], &ip[1], &ip[2], &ip[3], &len); - if (n != 4) - return false; - - if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255) - return false; - - for (buf += len; *buf != '\0'; buf++) { - if (isspace(*buf)) - continue; - else if (isdigit(*buf)) - break; - else - return false; - } + char *buf, *tok, *saveptr; + bool result; + int type; + + /* Use strdup directly since we can't easily reach a talloc parent */ + buf = strdup(strip_string(field_buffer(field, 0))); + if (!buf) + /* We tried */ + return true; + + result = false; + tok = strtok_r(buf, " ", &saveptr); + if (!tok || *tok == '\0') + goto err; + + while (tok) { + type = addr_scheme(tok); + if (!(type == AF_INET || type == AF_INET6)) + goto err; + + tok = strtok_r(NULL, " ", &saveptr); } + result = true; - return true; +err: + free(buf); + return result; +} + +static bool check_ip_multi_char(int c, const void *arg __attribute__((unused))) +{ + return (check_ipv4_multi_char(c) || check_ipv6_multi_char(c)); } -void widget_textbox_set_validator_ipv4_multi(struct nc_widget_textbox *textbox) +void widget_textbox_set_validator_ip(struct nc_widget_textbox *textbox) +{ + if (!textbox->set->ip_type) { + textbox->set->ip_type = new_fieldtype(check_ip_field, NULL); + } + set_field_type(textbox->widget.field, textbox->set->ip_type); +} + +/* + * In a perfect world we would use link_fieldtype() but segfaults do not + * enhance the user experience. + */ +void widget_textbox_set_validator_ip_multi(struct nc_widget_textbox *textbox) { - if (!textbox->set->ipv4_multi_type) { - textbox->set->ipv4_multi_type = new_fieldtype( - check_ipv4_multi_field, - check_ipv4_multi_char); + if (!textbox->set->ip_multi_type) { + textbox->set->ip_multi_type = new_fieldtype( + check_ip_multi_field, + check_ip_multi_char); } - set_field_type(textbox->widget.field, textbox->set->ipv4_multi_type); + set_field_type(textbox->widget.field, textbox->set->ip_multi_type); } static void subset_update_order(struct nc_widget_subset *subset) @@ -1201,8 +1238,12 @@ static int widgetset_destructor(void *ptr) { struct nc_widgetset *set = ptr; free_form(set->form); - if (set->ipv4_multi_type) - free_fieldtype(set->ipv4_multi_type); + if (set->ip_type) + free_fieldtype(set->ip_type); + if (set->ip_multi_type) + free_fieldtype(set->ip_multi_type); + if (set->url_type) + free_fieldtype(set->url_type); return 0; } diff --git a/ui/ncurses/nc-widgets.h b/ui/ncurses/nc-widgets.h index aa9263f..a946c4f 100644 --- a/ui/ncurses/nc-widgets.h +++ b/ui/ncurses/nc-widgets.h @@ -40,8 +40,8 @@ struct nc_widget_button *widget_new_button(struct nc_widgetset *set, void widget_textbox_set_fixed_size(struct nc_widget_textbox *textbox); void widget_textbox_set_validator_integer(struct nc_widget_textbox *textbox, long min, long max); -void widget_textbox_set_validator_ipv4(struct nc_widget_textbox *textbox); -void widget_textbox_set_validator_ipv4_multi(struct nc_widget_textbox *textbox); +void widget_textbox_set_validator_ip(struct nc_widget_textbox *textbox); +void widget_textbox_set_validator_ip_multi(struct nc_widget_textbox *textbox); void widget_textbox_set_validator_url(struct nc_widget_textbox *textbox); void widget_subset_add_option(struct nc_widget_subset *subset, const char *text);