diff --git a/ChangeLog b/ChangeLog index 5e783360d1..d3a1677e81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2004-11-10 Dan Williams + + Patches from j bootlab org + * src/NetworkManagerDevice.c + - (nm_device_activate_wireless): wait 5 seconds before attempting to detect + whether the card has a link or not, some cards are slow + - (nm_device_activation_configure_ip): make ipv6 work a bit better + + * info-daemon/NetworkManagerInfoPassphraseDialog.c + - Disable the "Login" button on the passphrase dialog until the user + enters a valid passphrase or key + + Patches from Tom Parker + * src/backends/NetworkManagerDebian.c + - Add static IP support to the debian backend + + * src/backends/interface_parser.[ch] + - Parse debian interface config files + 2004-11-08 Dan Williams * src/NetworkManagerDevice.c diff --git a/info-daemon/NetworkManagerInfoPassphraseDialog.c b/info-daemon/NetworkManagerInfoPassphraseDialog.c index ab66ded72a..d66374f056 100644 --- a/info-daemon/NetworkManagerInfoPassphraseDialog.c +++ b/info-daemon/NetworkManagerInfoPassphraseDialog.c @@ -46,6 +46,39 @@ enum NMIPassphraseDialogKeyTypes KEY_TYPE_HEX_KEY = 2 }; +static void update_button_cb (GtkWidget *widget, GladeXML *xml) +{ + gboolean enable = TRUE; + + g_return_if_fail (xml != NULL); + + GtkButton *button = GTK_BUTTON (glade_xml_get_widget (xml, "login_button")); + GtkComboBox *combo = GTK_COMBO_BOX (glade_xml_get_widget (xml, "key_type_combo")); + GtkEntry *passphrase_entry = GTK_ENTRY (glade_xml_get_widget (xml, "passphrase_entry")); + const char *passphrase_text = gtk_entry_get_text (passphrase_entry); + + if (passphrase_text[0] == '\000') + enable = FALSE; + else + { + int combo_choice = gtk_combo_box_get_active (combo); + switch (combo_choice) + { + case KEY_TYPE_ASCII_KEY: + if ((strlen (passphrase_text) != 5) && (strlen (passphrase_text) != 13)) + enable = FALSE; + break; + case KEY_TYPE_HEX_KEY: + if ((strlen (passphrase_text) != 10) && (strlen (passphrase_text) != 26)) + enable = FALSE; + break; + default: + break; + } + } + + gtk_widget_set_sensitive (GTK_WIDGET (button), enable); +} /* * nmi_passphrase_dialog_clear @@ -296,6 +329,8 @@ int nmi_passphrase_dialog_init (NMIAppInfo *info) entry = GTK_ENTRY (glade_xml_get_widget (info->passphrase_dialog, "passphrase_entry")); nmi_passphrase_dialog_clear (dialog, GTK_WIDGET (entry)); + gtk_widget_set_sensitive (GTK_WIDGET (ok_button), FALSE); + g_signal_connect (entry, "changed", G_CALLBACK (update_button_cb), info->passphrase_dialog); key_type_combo = GTK_COMBO_BOX (glade_xml_get_widget (info->passphrase_dialog, "key_type_combo")); gtk_combo_box_set_active (key_type_combo, 0); diff --git a/src/NetworkManagerDevice.c b/src/NetworkManagerDevice.c index d40cae861c..e58aa57245 100644 --- a/src/NetworkManagerDevice.c +++ b/src/NetworkManagerDevice.c @@ -1345,7 +1345,7 @@ static gboolean nm_device_activate_wireless (NMDevice *dev, NMAccessPoint *ap, g /* Bring the device up and pause to allow card to associate */ nm_device_bring_up (dev); - g_usleep (G_USEC_PER_SEC * 2); + g_usleep (G_USEC_PER_SEC * 5); nm_device_update_link_active (dev, FALSE); success = TRUE; @@ -1512,6 +1512,12 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev) if (nm_device_config_get_use_dhcp (dev)) { + /* FIXME + * Bringing the device up and then down evidentally helps with + * IPv6 for some reason, according to j bootlab org + */ + nm_device_bring_down (dev); + nm_device_bring_up (dev); if (nm_system_device_run_dhcp (dev)) success = TRUE; else diff --git a/src/backends/NetworkManagerDebian.c b/src/backends/NetworkManagerDebian.c index 0738742924..8d53db8db9 100644 --- a/src/backends/NetworkManagerDebian.c +++ b/src/backends/NetworkManagerDebian.c @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * (C) Copyright 2004 Tom Parker * (C) Copyright 2004 Matthew Garrett * (C) Copyright 2004 Red Hat, Inc. */ @@ -29,7 +30,12 @@ #include "NetworkManagerSystem.h" #include "NetworkManagerUtils.h" #include "NetworkManagerDevice.h" +#include "interface_parser.h" +#define ARPING "/usr/sbin/arping" + +/* hacky, but the redhat one does this as well... */ +#include "interface_parser.c" /* * nm_system_init @@ -54,7 +60,7 @@ void nm_system_init (void) gboolean nm_system_device_run_dhcp (NMDevice *dev) { char *buf; - char *iface; + const char *iface; int err; g_return_val_if_fail (dev != NULL, FALSE); @@ -192,7 +198,7 @@ gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev) guint32 broadcast; char *buf; int err; - char *iface; + const char *iface; g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (!nm_device_config_get_use_dhcp (dev), FALSE); @@ -218,7 +224,7 @@ gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev) * using RFC 2131 Duplicate Address Detection */ temp_addr.s_addr = addr; - buf = g_strdup_printf ("/sbin/arping -q -D -c 1 -I %s %s", + buf = g_strdup_printf ("%s -q -D -c 1 -I %s %s",ARPING, iface, inet_ntoa (temp_addr)); if ((err = nm_spawn_process (buf))) { @@ -248,12 +254,12 @@ gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev) /* Alert other computers of our new address */ temp_addr.s_addr = addr; - buf = g_strdup_printf ("/sbin/arping -q -A -c 1 -I %s %s", iface, + buf = g_strdup_printf ("%s -q -A -c 1 -I %s %s", ARPING,iface, inet_ntoa (temp_addr)); nm_spawn_process (buf); g_free (buf); g_usleep (G_USEC_PER_SEC * 2); - buf = g_strdup_printf ("/sbin/arping -q -U -c 1 -I %s %s", iface, + buf = g_strdup_printf ("%s -q -U -c 1 -I %s %s", ARPING, iface, inet_ntoa (temp_addr)); nm_spawn_process (buf); g_free (buf); @@ -289,8 +295,97 @@ error: */ void nm_system_device_update_config_info (NMDevice *dev) { -} + gboolean use_dhcp = TRUE; + guint32 ip4_address = 0; + guint32 ip4_netmask = 0; + guint32 ip4_gateway = 0; + guint32 ip4_broadcast = 0; + if_block *curr_device; + const char *buf; + g_return_if_fail (dev != NULL); + + /* We use DHCP on an interface unless told not to */ + nm_device_config_set_use_dhcp (dev, TRUE); + nm_device_config_set_ip4_address (dev, 0); + nm_device_config_set_ip4_gateway (dev, 0); + nm_device_config_set_ip4_netmask (dev, 0); + nm_device_config_set_ip4_broadcast (dev, 0); + + + ifparser_init(); + + /* Make sure this config file is for this device */ + curr_device = ifparser_getif(nm_device_get_iface (dev)); + if (curr_device == NULL) + goto out; + + buf = ifparser_getkey(curr_device, "inet"); + if (buf) + { + if (strcmp (buf, "dhcp")!=0) + use_dhcp = FALSE; + } + + buf = ifparser_getkey (curr_device, "address"); + if (buf) + ip4_address = inet_addr (buf); + + buf = ifparser_getkey (curr_device, "gateway"); + if (buf) + ip4_gateway = inet_addr (buf); + + buf = ifparser_getkey (curr_device, "netmask"); + if (buf) + ip4_netmask = inet_addr (buf); + else + { + /* Make a default netmask if we have an IP address */ + if (ip4_address) + { + if (((ntohl (ip4_address) & 0xFF000000) >> 24) <= 127) + ip4_netmask = htonl (0xFF000000); + else if (((ntohl (ip4_address) & 0xFF000000) >> 24) <= 191) + ip4_netmask = htonl (0xFFFF0000); + else + ip4_netmask = htonl (0xFFFFFF00); + } + } + + buf = ifparser_getkey (curr_device, "broadcast"); + if (buf) + ip4_broadcast = inet_addr (buf); + + if (!use_dhcp && (!ip4_address || !ip4_gateway || !ip4_netmask)) + { + syslog (LOG_ERR, "Error: network configuration for device '%s' was invalid (non-DHCP configuration," + " but no address/gateway specificed). Will use DHCP instead.\n", nm_device_get_iface (dev)); + use_dhcp = TRUE; + } + + /* If successful, set values on the device */ + nm_device_config_set_use_dhcp (dev, use_dhcp); + if (ip4_address) + nm_device_config_set_ip4_address (dev, ip4_address); + if (ip4_gateway) + nm_device_config_set_ip4_gateway (dev, ip4_gateway); + if (ip4_netmask) + nm_device_config_set_ip4_netmask (dev, ip4_netmask); + if (ip4_broadcast) + nm_device_config_set_ip4_broadcast (dev, ip4_broadcast); + +#if 0 + syslog (LOG_DEBUG, "------ Config (%s)", nm_device_get_iface (dev)); + syslog (LOG_DEBUG, " DHCP=%d\n", use_dhcp); + syslog (LOG_DEBUG, " ADDR=%d\n", ip4_address); + syslog (LOG_DEBUG, " GW=%d\n", ip4_gateway); + syslog (LOG_DEBUG, " NM=%d\n", ip4_netmask); + syslog (LOG_DEBUG, "---------------------\n"); +#endif + +out: + ifparser_destroy(); +} /* * nm_system_enable_loopback diff --git a/src/backends/interface_parser.c b/src/backends/interface_parser.c new file mode 100644 index 0000000000..219c5c8699 --- /dev/null +++ b/src/backends/interface_parser.c @@ -0,0 +1,183 @@ +/* NetworkManager -- Network link manager + * + * Tom Parker + * + * 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 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. + * + * (C) Copyright 2004 Tom Parker + */ + + +#include "interface_parser.h" + +#include +#include +#include + +if_block* first; +if_block* last; + +if_data* last_data; + +void add_block(const char *type, const char* name) +{ + if_block *ret = (if_block*)calloc(1,sizeof(struct _if_block)); + ret->name = (char*)calloc(strlen(name),sizeof(char)); + strcpy(ret->name, name); + ret->type = (char*)calloc(strlen(type),sizeof(char)); + strcpy(ret->type, type); + if (first == NULL) + first = last = ret; + else + { + last->next = ret; + last = ret; + } + last_data = NULL; + //printf("added block '%s' with type '%s'\n",name,type); +} + +void add_data(const char *key,const char *data) +{ + if_data *ret = (if_data*)calloc(1,sizeof(struct _if_data)); + ret->key = (char*)calloc(strlen(key),sizeof(char)); + strcpy(ret->key,key); + ret->data = (char*)calloc(strlen(data),sizeof(char)); + strcpy(ret->data, data); + + if (last->info == NULL) + { + last->info = ret; + last_data = ret; + } + else + { + last_data->next = ret; + last_data = last_data->next; + } + //printf("added data '%s' with key '%s'\n",data,key); +} + +void ifparser_init() +{ + FILE *inp = fopen(INTERFACES,"r"); + int ret = 0; + first = last = NULL; + while(1) + { + char *line,rline[255],*space; + if (ret == EOF) + break; + ret = fscanf(inp,"%255[^\n]\n",rline); + line = rline; + while(line[0] == ' ') + line++; + if (line[0]=='#' || line[0]=='\0') + continue; + + space = strchr(line,' '); + if (space == NULL) + { + fprintf(stderr,"Can't parse line '%s'\n",line); + continue; + } + space[0] = '\0'; + + + if (strcmp(line,"iface")==0) + { + char *space2 = strchr(space+1,' '); + if (space2 == NULL) + { + fprintf(stderr,"Can't parse iface line '%s'\n",space+1); + continue; + } + space2[0]='\0'; + add_block(line,space+1); + + if (space2[1]!='\0') + { + space = strchr(space2+1,' '); + if (space == NULL) + { + fprintf(stderr,"Can't parse data '%s'\n",space2+1); + continue; + } + space[0] = '\0'; + add_data(space2+1,space+1); + } + } + else if (strcmp(line,"auto")==0) + add_block(line,space+1); + else + add_data(line,space+1); + + //printf("line: '%s' ret=%d\n",rline,ret); + } + fclose(inp); +} + +void _destroy_data(if_data *ifd) +{ + if (ifd == NULL) + return; + _destroy_data(ifd->next); + free(ifd->key); + free(ifd->data); + free(ifd); + return; +} + +void _destroy_block(if_block* ifb) +{ + if (ifb == NULL) + return; + _destroy_block(ifb->next); + _destroy_data(ifb->info); + free(ifb->name); + free(ifb->type); + free(ifb); + return; +} + +void ifparser_destroy() +{ + _destroy_block(first); + first = last = NULL; +} + +if_block *ifparser_getif(const char* iface) +{ + if_block *curr = first; + while(curr!=NULL) + { + if (strcmp(curr->type,"iface")==0 && strcmp(curr->name,iface)==0) + return curr; + curr = curr->next; + } + return NULL; +} + +const char *ifparser_getkey(if_block* iface, const char *key) +{ + if_data *curr = iface->info; + while(curr!=NULL) + { + if (strcmp(curr->key,key)==0) + return curr->data; + curr = curr->next; + } + return NULL; +} diff --git a/src/backends/interface_parser.h b/src/backends/interface_parser.h new file mode 100644 index 0000000000..3cfecfcfd2 --- /dev/null +++ b/src/backends/interface_parser.h @@ -0,0 +1,51 @@ +/* NetworkManager -- Network link manager + * + * Tom Parker + * + * 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 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. + * + * (C) Copyright 2004 Tom Parker + */ + + +#ifndef _INTERFACE_PARSER_H +#define _INTERFACE_PARSER_H + +#define INTERFACES "/etc/network/interfaces" + +typedef struct _if_data +{ + char *key; + char *data; + struct _if_data *next; +} if_data; + +typedef struct _if_block +{ + char *type; + char *name; + if_data *info; + struct _if_block *next; +} if_block; + +void ifparser_init(); +void ifparser_destroy(); + +const char* ifparser_interfaces(); +if_block *ifparser_getif(const char* iface); +const char *ifparser_getkey(if_block* iface, const char *key); + +#endif +