[LWN Logo]

Date:	Thu, 1 Jul 1999 09:46:12 +0200
From:	Martin Neumann <mne@mne.de>
To:	linux-kernel@vger.rutgers.edu
Subject: [PATCH] /proc/net/dev_hwaddr


--UugvWAfsgieZRqgk
Content-Type: text/plain; charset=us-ascii

I attached a patch against 2.2.10 which adds "dev_hwaddr" to
/proc/net/. Here an example:

% cat /proc/net/dev_hwaddr 
lo 00:00:00:00:00:00
eth0 00:E0:7D:00:55:67
ippp0 -

I did this to avoid parsing ifconfig's output. I have a box which
has two network interfaces - one is connected to the part of
the intranet which is considered to be "trusted", the other is
considered "untrusted".

This two interfaces are configured differently concerning
ipchains-setup etc. I could have used the device name for
distinguishing the two interfaces, but it depends on the card
initialization order which one gets eth0 and which one is eth1.
So if I change one of the NICs one day, the two devices perhaps
swap their names and my scripts would the configure the wrong to
be trusted. That would really be fatal.

But of course I can distinguish both by the NIC hardware address.
But to get the hwaddr I would have to parse ifconfig's output.
I don't want to rely on that. So I did the patch so that I can
easily lookup which device name refers to which NIC hwaddr.

This could be also useful for those having need for a "unique
system identifier" - now they can easily lookup whether a
specific NIC hwaddr is present in the system.

[Note]
All hwaddr get formated like an (ethernet|tokenring|..) NIC's
hwaddr. If you want to have the right format for other NIC
types like ARCnet you have to reformat it. But I consider
this reformating not to be a kernel job. Instead this should
be done in userland.

[Disclaimer]
I never did any kernel patch before and I don't claim to have
superb kernel knowledge. If I did something braindead, tell me.

But if this patch is considered useful, I would be glad if this
gets into the official kernel source.

-- 
`Unser Kopf ist rund, damit das Denken die Richtung wechseln kann.'
  ~ Francis Picabia

--UugvWAfsgieZRqgk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="patch.dev_hwaddr"

--- linux/net/core/dev.c	Thu Mar 25 18:23:34 1999
+++ linux-changed/net/core/dev.c	Thu Jul  1 08:49:39 1999
@@ -56,6 +56,7 @@
  *					A network device unload needs to purge
  *					the backlog queue.
  *	Paul Rusty Russel	:	SIOCSIFNAME
+ *              Martin Neumann  :       Added support for /proc/net/dev_hwaddr
  */
 
 #include <asm/uaccess.h>
@@ -1221,6 +1222,64 @@
 	return len;
 }
 
+/*
+ *	The following two procedures create the output for /proc/net/dev_hwaddr
+ *      The code was mostly cloned from dev_get_info and sprintf_stats
+ */
+
+static int sprintf_hwaddr(char *buffer, struct device *dev)
+{
+    int size;
+
+    if (dev->addr_len) { /* Some devices have a hw address, some don't */
+      int i;
+      char addr_byte_buf[dev->addr_len * 3], tmpbuf[4];
+
+      for (i=0; i < dev->addr_len; i++) {
+	sprintf(tmpbuf, "%02X:", (dev->dev_addr[i] & 0377));
+	memcpy(&addr_byte_buf[i*3], tmpbuf, 3);
+      };
+
+      addr_byte_buf[dev->addr_len * 3 - 1] = 0;
+      size = sprintf(buffer, "%s %s\n", dev->name, addr_byte_buf);
+    }
+    else
+      size = sprintf(buffer, "%s -\n", dev->name);
+
+    return size;
+};
+
+int dev_hwaddr_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
+{
+	int len=0;
+	off_t begin=0;
+	off_t pos=0;
+	int size;
+	
+	struct device *dev;
+
+       	for (dev = dev_base; dev != NULL; dev = dev->next) 
+	{
+		size = sprintf_hwaddr(buffer+len, dev);
+		len+=size;
+		pos=begin+len;
+				
+		if(pos<offset)
+		{
+			len=0;
+			begin=pos;
+		}
+		if(pos>offset+length)
+			break;
+	}
+	
+	*start=buffer+(offset-begin);	/* Start of wanted data */
+	len-=(offset-begin);		/* Start slop */
+	if(len>length)
+		len=length;		/* Ending slop */
+	return len;
+};
+
 static int dev_proc_stats(char *buffer, char **start, off_t offset,
 			  int length, int *eof, void *data)
 {
@@ -1867,6 +1926,13 @@
 	0, &proc_net_inode_operations,
 	dev_get_info
 };
+
+static struct proc_dir_entry proc_net_dev_hwaddr = {
+        PROC_NET_DEV, 10, "dev_hwaddr",
+        S_IFREG | S_IRUGO, 1, 0, 0,
+        0, &proc_net_inode_operations,
+        dev_hwaddr_get_info
+};
 #endif
 
 #ifdef CONFIG_NET_RADIO
@@ -2003,6 +2069,8 @@
 		struct proc_dir_entry *ent = create_proc_entry("net/dev_stat", 0, 0);
 		ent->read_proc = dev_proc_stats;
 	}
+
+	proc_net_register(&proc_net_dev_hwaddr);
 #endif
 
 #ifdef CONFIG_NET_RADIO
--- linux/include/linux/proc_fs.h	Tue May 11 19:36:09 1999
+++ linux-changed/include/linux/proc_fs.h	Mon Jun 28 13:38:11 1999
@@ -146,6 +146,7 @@
 	PROC_NET_IPFW_CHAIN_NAMES,
 	PROC_NET_AT_AARP,
 	PROC_NET_BRIDGE,
+	PROC_NET_HWADDR,
 	PROC_NET_LAST
 };
 

--UugvWAfsgieZRqgk--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/