/*
 *  Author: Samuel Abels <spam debain org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "gui_ipv4_analyzer.h"

//#define _DEBUG_


/******************************************************************************
 * Constructor/Destructor
 ******************************************************************************/
GUIIPv4Analyzer::GUIIPv4Analyzer()
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::GUIIPv4Analyzer(): Called.\n");
#endif
  HBox*        hbox  = NULL;
  Label*       label = NULL;
  SpinButton*  spin  = NULL;
  Entry*       entry = NULL;
  CheckButton* check = NULL;
  Image*       image = NULL;
  string       str;
  
  resize(24, 5);
  set_border_width(12);
  set_row_spacings(3);
  set_col_spacings(12);
  
  // ****************** "Input" section ******************.
  // Add all labels.
  label = new Label("", 0, 0.5);
  str = "<b>";
  str.append(_("Input"));
  str.append("</b>");
  label->set_markup(str);
  attach(*manage(label), 0, 5, 0, 1, FILL, FILL);
  
  image = new Image(PACKAGE_PIXMAPS_DIR "calculator.png");
  image->set_padding(12, 0);
  attach(*manage(image), 0, 1, 1, 4, FILL, FILL);
  
  label = new Label(_("IP address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 1, 2, FILL, FILL);
  
  label = new Label(_("Network mask:"), 0, 0.5);
  attach(*manage(label), 1, 2, 2, 3, FILL, FILL);
  
  label = new Label(_("Prefix length:"), 0, 0.5);
  attach(*manage(label), 1, 2, 3, 4, FILL, FILL);
  
  label = new Label("");
  attach(*manage(label), 0, 5, 4, 5, FILL, FILL);
  
  // Add all spin-buttons.
  spin = new SpinButton;
  spin->set_numeric(FALSE);
  spin->set_range(0, (double)pow((double)2, 32) - 1);
  spin->set_increments(1, 256);
  spin->set_wrap();
  widgets["ip"] = spin;
  attach(*manage(spin), 2, 5, 1, 2, FILL|EXPAND, FILL);
  spin->signal_input().connect(
        sigc::bind(sigc::mem_fun(*this, &GUIIPv4Analyzer::map_ip_input), spin));
  spin->signal_output().connect(
        sigc::bind(sigc::mem_fun(*this, &GUIIPv4Analyzer::map_ip_output), spin));
  spin->signal_value_changed().connect(
        sigc::mem_fun(*this, &GUIIPv4Analyzer::on_ip_changed));
  
  spin = new SpinButton;
  spin->set_numeric(FALSE);
  spin->set_range(0, 32);
  spin->set_increments(1, 10);
  spin->set_wrap();
  widgets["mask"] = spin;
  attach(*manage(spin), 2, 5, 2, 3, FILL|EXPAND, FILL);
  spin->signal_input().connect(
        sigc::bind(sigc::mem_fun(*this, &GUIIPv4Analyzer::map_mask_input), spin));
  spin->signal_output().connect(
        sigc::bind(sigc::mem_fun(*this, &GUIIPv4Analyzer::map_mask_output), spin));
  spin->signal_value_changed().connect(
        sigc::mem_fun(*this, &GUIIPv4Analyzer::on_mask_changed));
  
  spin = new SpinButton;
  spin->set_range(0, 32);
  spin->set_increments(1, 10);
  widgets["pfxlen"] = spin;
  attach(*manage(spin), 2, 5, 3, 4, FILL|EXPAND, FILL);
  spin->signal_value_changed().connect(
        sigc::mem_fun(*this, &GUIIPv4Analyzer::on_pfxlen_changed));
  
  // ****************** "Output" section ******************.
  // Add the "Range" hbox.
  hbox = new HBox;
  hbox->set_spacing(6);
  attach(*manage(hbox), 2, 5, 6, 7, FILL, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_rangefrom"] = label;
  hbox->pack_start(*manage(label), FALSE, TRUE);
  
  label = new Label("-", 0, 0.5);
  hbox->pack_start(*manage(label), FALSE, FALSE);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_rangeto"] = label;
  hbox->pack_start(*manage(label), FALSE, TRUE);
  
  // Add all labels.
  label = new Label("", 0, 0.5);
  str = "<b>";
  str.append(_("Output"));
  str.append("</b>");
  label->set_markup(str);
  label->set_padding(0, 6);
  attach(*manage(label), 0, 5, 5, 6, FILL, FILL);
  
  image = new Image(PACKAGE_PIXMAPS_DIR "netcard.png");
  image->set_padding(12, 0);
  attach(*manage(image), 0, 1, 6, 12, FILL, FILL);
  
  label = new Label(_("Address range:"), 0, 0.5);
  attach(*manage(label), 1, 2, 6, 7, FILL, FILL);
  
  label = new Label(_("Number of subnets:"), 0, 0.5);
  attach(*manage(label), 1, 2, 7, 8, FILL, FILL);
  
  label = new Label(_("Number of hosts:"), 0, 0.5);
  attach(*manage(label), 1, 2, 8, 9, FILL, FILL);
  
  label = new Label(_("Including net/broadcast:"), 0, 0.5);
  attach(*manage(label), 1, 2, 9, 10, FILL, FILL);
  
  label = new Label(_("Network address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 10, 11, FILL, FILL);
  
  label = new Label(_("Broadcast address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 11, 12, FILL, FILL);
  
  label = new Label("");
  attach(*manage(label), 0, 5, 12, 13, FILL, FILL);
  
  // Add all selectable labels.
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_numsubnets"] = label;
  attach(*manage(label), 2, 3, 7, 8, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_numhosts"] = label;
  attach(*manage(label), 2, 3, 8, 9, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_numhosts_all"] = label;
  attach(*manage(label), 2, 3, 9, 10, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_network"] = label;
  attach(*manage(label), 2, 3, 10, 11, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["out_broadcast"] = label;
  attach(*manage(label), 2, 3, 11, 12, FILL|EXPAND, FILL);
  
  // ****************** "Binary Output" section ******************.
  // Add all labels.
  label = new Label("", 0, 0.5);
  str = "<b>";
  str.append(_("Binary Output"));
  str.append("</b>");
  label->set_markup(str);
  label->set_padding(0, 6);
  attach(*manage(label), 0, 5, 13, 14, FILL, FILL);
  
  image = new Image(PACKAGE_PIXMAPS_DIR "gears.png");
  image->set_padding(12, 0);
  attach(*manage(image), 0, 1, 14, 18, FILL, FILL);
  
  label = new Label(_("IP address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 14, 15, FILL, FILL);
  
  label = new Label(_("Network mask:"), 0, 0.5);
  attach(*manage(label), 1, 2, 15, 16, FILL, FILL);
  
  label = new Label(_("Network address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 16, 17, FILL, FILL);
  
  label = new Label(_("Broadcast address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 17, 18, FILL, FILL);
  
  label = new Label("");
  attach(*manage(label), 0, 5, 18, 19, FILL, FILL);
  
  // Add all entry boxes.
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["bin_ip"] = label;
  attach(*manage(label), 2, 5, 14, 15, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["bin_mask"] = label;
  attach(*manage(label), 2, 5, 15, 16, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["bin_network"] = label;
  attach(*manage(label), 2, 5, 16, 17, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["bin_broadcast"] = label;
  attach(*manage(label), 2, 5, 17, 18, FILL|EXPAND, FILL);
  
  // ****************** "Hexadecimal Output" section ******************.
  // Add all labels.
  label = new Label("", 0, 0.5);
  str = "<b>";
  str.append(_("Hexadecimal Output"));
  str.append("</b>");
  label->set_markup(str);
  label->set_padding(0, 6);
  attach(*manage(label), 0, 5, 19, 20, FILL, FILL);
  
  image = new Image(PACKAGE_PIXMAPS_DIR "gears.png");
  image->set_padding(12, 0);
  attach(*manage(image), 0, 1, 20, 24, FILL, FILL);
  
  label = new Label(_("IP address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 20, 21, FILL, FILL);
  
  label = new Label(_("Network mask:"), 0, 0.5);
  attach(*manage(label), 1, 2, 21, 22, FILL, FILL);
  
  label = new Label(_("Network address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 22, 23, FILL, FILL);
  
  label = new Label(_("Broadcast address:"), 0, 0.5);
  attach(*manage(label), 1, 2, 23, 24, FILL, FILL);
  
  // Add all entry boxes.
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["hex_ip"] = label;
  attach(*manage(label), 2, 5, 20, 21, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["hex_mask"] = label;
  attach(*manage(label), 2, 5, 21, 22, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["hex_network"] = label;
  attach(*manage(label), 2, 5, 22, 23, FILL|EXPAND, FILL);
  
  label = new Label("", 0, 0.5);
  label->set_selectable();
  widgets["hex_broadcast"] = label;
  attach(*manage(label), 2, 5, 23, 24, FILL|EXPAND, FILL);
}


GUIIPv4Analyzer::~GUIIPv4Analyzer()
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::~GUIIPv4Analyzer(): Called.\n");
#endif
}


/******************************************************************************
 * Public
 ******************************************************************************/
/* Switch event emissions off. */
void GUIIPv4Analyzer::lock_signals(void)
{
  lock_events = TRUE;
}


/* Switch event emissions on. */
void GUIIPv4Analyzer::unlock_signals(void)
{
  lock_events = FALSE;
}


/* Returns the value of the IP address field. */
unsigned long GUIIPv4Analyzer::get_ip(void)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::get_ip(): Called.\n");
#endif
  SpinButton* spin = (SpinButton*)widgets["ip"];
  return (unsigned long)spin->get_value();
}


/* Sets the value of the IP address field. */
void GUIIPv4Analyzer::set_ip(unsigned long ip)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_ip(): Called.\n");
#endif
  SpinButton* spin = (SpinButton*)widgets["ip"];
  spin->set_value((double)ip);
}


/* Sets the value of the IP netmask field. */
void GUIIPv4Analyzer::set_mask(unsigned long mask)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_mask(): Called.\n");
#endif
  SpinButton*         spin   = (SpinButton*)widgets["mask"];
  unsigned short int  pfxlen = 0;
  ipv4_mask2pfxlen(mask, &pfxlen);
  spin->set_value((double)pfxlen);
}


/* Sets the value of the prefixlength field. */
void GUIIPv4Analyzer::set_pfxlen(unsigned short int pfxlen)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_prefixlength(): Called.\n");
#endif
  SpinButton* spin = (SpinButton*)widgets["pfxlen"];
  spin->set_value((double)pfxlen);
}


/* Sets the value of the range fields. */
void GUIIPv4Analyzer::set_output_range(unsigned long from, unsigned long to)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_range(): Called.\n");
#endif
  Label* labelfrom = (Label*)widgets["out_rangefrom"];
  Label* labelto   = (Label*)widgets["out_rangeto"];
  char text[16];
  if (ipv4_integer2ip(from, text) == 0)
    labelfrom->set_text(text);
  if (ipv4_integer2ip(to, text) == 0)
    labelto->set_text(text);
}


/* Sets the value of the "Output" -> "Number of Subnets" field. */
void GUIIPv4Analyzer::set_output_subnets(unsigned int num)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_subnets(): Called.\n");
#endif
  Label* label = (Label*)widgets["out_numsubnets"];
  char text[100];
  snprintf(text, 99, "%u", num);
  label->set_text(text);
}


/* Sets the value of the "Output" -> "Number of Hosts" field. */
void GUIIPv4Analyzer::set_output_hosts(unsigned int num)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_hosts(): Called.\n");
#endif
  Label* label = (Label*)widgets["out_numhosts"];
  char text[100];
  snprintf(text, 99, "%u", num);
  label->set_text(text);
}


/* Sets the value of the "Output" -> "Number of Hosts, including Net/BC"
 * field.
 */
void GUIIPv4Analyzer::set_output_hosts_all(unsigned int num)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_hosts(): Called.\n");
#endif
  Label* label = (Label*)widgets["out_numhosts_all"];
  char text[100];
  snprintf(text, 99, "%u", num);
  label->set_text(text);
}


/* Sets the value of the "Output" -> "Network" field. */
void GUIIPv4Analyzer::set_output_network(unsigned long network)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_network(): Called.\n");
#endif
  Label* label = (Label*)widgets["out_network"];
  char network_text[16];
  if (ipv4_integer2ip(network, network_text) < 0)
    return;
  label->set_text(network_text);
}


/* Sets the value of the "Output" -> "Network" field. */
void GUIIPv4Analyzer::set_output_broadcast(unsigned long broadcast)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_broadcast(): Called.\n");
#endif
  Label* label = (Label*)widgets["out_broadcast"];
  char broadcast_text[16];
  if (ipv4_integer2ip(broadcast, broadcast_text) < 0)
    return;
  label->set_text(broadcast_text);
}


/* Sets the value of the "Output (Binary)" -> "IP" field. */
void GUIIPv4Analyzer::set_output_bin_ip(unsigned long ip)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_bin_ip(): Called.\n");
#endif
  Label* label = (Label*)widgets["bin_ip"];
  char binary[36];
  if (ipv4_integer2bin(ip, binary) == 0)
    label->set_text(binary);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Binary)" -> "Netmask" field. */
void GUIIPv4Analyzer::set_output_bin_mask(unsigned long mask)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_bin_mask(): Called.\n");
#endif
  Label* label = (Label*)widgets["bin_mask"];
  char binary[36];
  if (ipv4_integer2bin(mask, binary) == 0)
    label->set_text(binary);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Binary)" -> "Network Address" field. */
void GUIIPv4Analyzer::set_output_bin_network(unsigned long net)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_bin_network(): Called.\n");
#endif
  Label* label = (Label*)widgets["bin_network"];
  char binary[36];
  if (ipv4_integer2bin(net, binary) == 0)
    label->set_text(binary);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Binary)" -> "Broadcast Address" field. */
void GUIIPv4Analyzer::set_output_bin_broadcast(unsigned long broadcast)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_bin_broadcast(): Called.\n");
#endif
  Label* label = (Label*)widgets["bin_broadcast"];
  char binary[36];
  if (ipv4_integer2bin(broadcast, binary) == 0)
    label->set_text(binary);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Hexadecimal)" -> "IP" field. */
void GUIIPv4Analyzer::set_output_hex_ip(unsigned long ip)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_hex_ip(): Called.\n");
#endif
  Label* label = (Label*)widgets["hex_ip"];
  char hex[20];
  if (ipv4_integer2hex(ip, hex) == 0)
    label->set_text(hex);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Hexadecimal)" -> "Netmask" field. */
void GUIIPv4Analyzer::set_output_hex_mask(unsigned long mask)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_hex_mask(): Called.\n");
#endif
  Label* label = (Label*)widgets["hex_mask"];
  char hex[20];
  if (ipv4_integer2hex(mask, hex) == 0)
    label->set_text(hex);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Hexadecimal)" -> "Network Address" field. */
void GUIIPv4Analyzer::set_output_hex_network(unsigned long net)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_hex_network(): Called.\n");
#endif
  Label* label = (Label*)widgets["hex_network"];
  char hex[20];
  if (ipv4_integer2hex(net, hex) == 0)
    label->set_text(hex);
  else
    label->set_text("");
}


/* Sets the value of the "Output (Hexadecimal)" -> "Broadcast Address" field. */
void GUIIPv4Analyzer::set_output_hex_broadcast(unsigned long broadcast)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::set_output_hex_broadcast(): Called.\n");
#endif
  Label* label = (Label*)widgets["hex_broadcast"];
  char hex[20];
  if (ipv4_integer2hex(broadcast, hex) == 0)
    label->set_text(hex);
  else
    label->set_text("");
}


/******************************************************************************
 * Private
 ******************************************************************************/
int GUIIPv4Analyzer::map_ip_input(double* value, SpinButton* spin)
{
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_ip_input(): Called.\n");
#endif
  string        ip     = spin->get_text();
  unsigned long ip_int = 0;
  if (ipv4_ip2integer(ip.c_str(), &ip_int) < 0)
    return 0;
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_ip_input(): Value: %s=%i\n", ip.c_str(), ip_int);
#endif
  *value = (double)ip_int;
  return 1;
}


bool GUIIPv4Analyzer::map_ip_output(SpinButton* spin)
{
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_ip_output(): Called.\n");
#endif
  char          ip[36] = "";
  unsigned long ip_int = (unsigned long)spin->get_adjustment()->get_value();
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_ip_output(): Double: %d\n",
         spin->get_adjustment()->get_value());
#endif
  ipv4_integer2ip(ip_int, ip);
  spin->set_text(ip);
  return TRUE;
}


/* This inbound map is used to map IP mask spinbuttons to a mask. */
int GUIIPv4Analyzer::map_mask_input(double* value, SpinButton* spin)
{
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_mask_input(): Called.\n");
#endif
  string             mask     = spin->get_text();
  unsigned long      mask_int = 0;
  unsigned short int pfxlen   = 0;
  if (ipv4_ip2integer(mask.c_str(), &mask_int) < 0)
    return 0;
  if (ipv4_mask2pfxlen(mask_int, &pfxlen) < 0)
    return 0;
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_mask_input(): Value: %s, %i, %i\n",
         mask.c_str(),
         mask_int,
         pfxlen);
#endif
  *value = (double)pfxlen;
  return 1;
}


/* This outbound map is used to map IP mask spinbuttons to a mask. */
bool GUIIPv4Analyzer::map_mask_output(SpinButton* spin)
{
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_mask_output(): Called.\n");
#endif
  char               mask[36] = "";
  unsigned short int pfxlen   = 0;
  unsigned long      mask_int = 0;
  pfxlen = (unsigned short int)spin->get_adjustment()->get_value();
  if (ipv4_pfxlen2mask((unsigned short int)pfxlen, &mask_int) < 0)
    return TRUE;
  ipv4_integer2ip(mask_int, mask);
#ifdef _DEBUG_EXCESSIVE_
  printf("GUIIPv4Analyzer::map_mask_output(): %i is %s\n", pfxlen, mask);
#endif
  spin->set_text(mask);
  return TRUE;
}


void GUIIPv4Analyzer::on_ip_changed(void)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::on_ip_changed(): Called.\n");
#endif
  if (lock_events)
    return;
  SpinButton*         spin_ip   = (SpinButton*)widgets["ip"];
  SpinButton*         spin_mask = (SpinButton*)widgets["mask"];
  unsigned long       ip        = (unsigned long)spin_ip->get_value();
  unsigned short int  pfxlen    = (unsigned long)spin_mask->get_value();
  unsigned long       mask      = 0;
  ipv4_pfxlen2mask(pfxlen, &mask);
  signal_ip_changed.emit(ip, mask);
}


void GUIIPv4Analyzer::on_mask_changed(void)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::on_mask_changed(): Called.\n");
#endif
  if (lock_events)
    return;
  SpinButton*         spin_ip   = (SpinButton*)widgets["ip"];
  SpinButton*         spin_mask = (SpinButton*)widgets["mask"];
  unsigned long       ip        = (unsigned long)spin_ip->get_value();
  unsigned short int  pfxlen    = (unsigned short int)spin_mask->get_value();
  unsigned long       mask      = 0;
  ipv4_pfxlen2mask(pfxlen, &mask);
  signal_mask_changed.emit(ip, mask);
}


void GUIIPv4Analyzer::on_pfxlen_changed(void)
{
#ifdef _DEBUG_
  printf("GUIIPv4Analyzer::on_prefixlength_changed(): Called.\n");
#endif
  if (lock_events)
    return;
  SpinButton*        spin_ip     = (SpinButton*)widgets["ip"];
  SpinButton*        spin_pfxlen = (SpinButton*)widgets["pfxlen"];
  unsigned long      ip          = (unsigned long)spin_ip->get_value();
  unsigned short int pfxlen      = (unsigned short int)spin_pfxlen->get_value();
  signal_pfxlen_changed.emit(ip, pfxlen);
}
