Debian backend update



Hello everyone. Having seen the havoc (kills network connection) that NetworkManager currently causes on wired Debian systems, I've written some stuff to actually read the debian /etc/network/interfaces config file. Patch to the backends folder enclosed, along with the interface_parser.{c,h} files that also needs to be placed in that folder. The patch also includes some minor fixes to the Debian backend (fix a couple of const char-related warnings, fix the arping location as the debian iputils-arping package doesn't provide /sbin/arping, but /usr/sbin/arping)

This has been tested on my laptop (DHCP configured wired interface + Wifi), and *should* work with static IP configs as well - the structure of the code for the updated nm_system_device_update_config_info() was taken from the Redhat one, so hopefully it should do all the necessary setup things.

Not sure whether I'm liable keep up with providing patches to this project, but glad to provide this little something.

Tom Parker
Index: NetworkManagerDebian.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/backends/NetworkManagerDebian.c,v
retrieving revision 1.8
diff -u -r1.8 NetworkManagerDebian.c
--- NetworkManagerDebian.c	19 Oct 2004 02:27:04 -0000	1.8
+++ NetworkManagerDebian.c	11 Nov 2004 00:15:07 -0000
@@ -29,7 +29,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 +59,7 @@
 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 +197,7 @@
         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 +223,7 @@
          * 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 +253,12 @@
 
         /* 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 +294,97 @@
  */
 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
#include "interface_parser.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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;
}

#ifndef _INTERFACE_PARSER
#define _INTERFACE_PARSER 1

#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
	


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]