linux-um archives
 help / color / mirror / Atom feed
* Re: [uml-devel] [uml-user] proc filesystem ipaddress
       [not found] <E1GYDno-0007SX-JC@nicferrier.tapsellferrier.co.uk>
@ 2006-10-14  1:46 ` Blaisorblade
  2006-10-14  1:50   ` Blaisorblade
  2006-10-14 11:31   ` Nic James Ferrier
  0 siblings, 2 replies; 5+ messages in thread
From: Blaisorblade @ 2006-10-14  1:46 UTC (permalink / raw)
  To: user-mode-linux-user, user-mode-linux-devel; +Cc: Nic James Ferrier

On Friday 13 October 2006 05:33, Nic James Ferrier wrote:
> I know this is not UML specific... but maybe the kernel hackers here
> can answer this anyway, since I'm doing it to make life with UMLs
> easier.
>
> I've patched the ipv4 stack so that it does proc registration of the
> IP address for an iface.
Take a look at /proc/net/if_inet6, generated by 

> Currently I'm just getting the details for eth0.
>
> I'm using kernel ioctl calls (correctly surrounded by get_fs/set_fs
> calls) to get the interface data.

> All the interface data is returned at 16 bits.
I.e. that's the seq_printf string, right?

> I've put printk's in the kernel side of the code and there I can see
> the values are 32 bit.

The values you pass to seq printf, right? Actually IMHO not - I guess printk() 
used different data.

> So it seems that in the conversion from kernel space to user space
> half the information is being lost.
>
> Anyone know anything about that?
See below, there's the analsys.
> Here's my patch to create /proc/net/ipaddress in case anyone's
> interested in half the data:
I know you're beginning to write kernel code and this is not even a finished 
patch, however I'm commenting _various_ improvable aspects of the work. Do 
not worry for that.

> --- old/linux-2.6.17.1/net/ipv4/proc.c
> +++ new/linux-2.6.17.1/net/ipv4/proc.c
> @@ -44,6 +44,77 @@
>  #include <net/sock.h>
>  #include <net/raw.h>
>
> +
> +//// New IP Address proc interface
> +#include <asm/uaccess.h>
> +#include <linux/if.h>
> +
> +static int ipaddress_dev_ioctl(struct ifreq *ir, unsigned int cmd)
> +{
> +	int res;
> +        mm_segment_t oldfs;
> +
> +	oldfs = get_fs();

> +	set_fs(get_ds());

Nah, this line should be set_fs(KERNEL_DS) - grep for examples, I've always 
used KERNEL_DS there and it's the only one that makes sense.

Also, for mainline acceptance I guess they'd prefer to bypass ioctl and access 
directly the needed fields.
Btw, on linux-kernel@ or on linux-netdev@ (cc'ing here) you might also ask why 
this info is missing.

> +	res = devinet_ioctl(cmd, (struct ifreq __user *) ir);
> +	set_fs(oldfs);
> +	return res;
> +}
> +
> +static int ipaddress_seq_show(struct seq_file *seq, void *v)
> +{
> +        struct ifreq ir;
> +        struct sockaddr_in * if_addr;
> +        struct sockaddr_in * local_addr;
> +        uint32_t local;
> +        uint32_t mask;
> +        uint32_t broadcast;
> +        uint32_t destination;
> +
> +        memset(&ir, 0, sizeof(ir));
> +        strcpy(ir.ifr_ifrn.ifrn_name, "eth0");

Ok, that will be fixed afterwards - that file (the ipv6 one, see above) 
iterates between addrs correctly. Note also that one interface can be 
associated to multiple address, even without using aliases, if you use 
the "ip" command (which uses probably even a different kernel level API - I 
remember that ifconfig and friends use an in-kernel emulation of the old 
API - but since the data model is different it is just an emulation).

> +
> +        ipaddress_dev_ioctl(&ir, SIOCGIFADDR);
> +        local_addr = if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;

But local_addr is redundant, right?
Beyond that, I've found your bug. You can cast a (struct sockaddr*) to a 
(struct sockaddr_in*), but your doing a worse cast; since ifr_addr is a 
struct sockaddr, the _below_ version is correct:

if_addr = (struct sockaddr_in *) ir.ifr_addr;

The way you do it, if_addr is 2 + the correct value - i.e. 16 bit are cut 
away.

Unless in kernel they use different conventions (then show it me and I'll 
agree).

> +        local = if_addr->sin_addr.s_addr;
> +
> +        ipaddress_dev_ioctl(&ir, SIOCGIFNETMASK);
> +        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;
> +        mask = if_addr->sin_addr.s_addr;
> +
> +        ipaddress_dev_ioctl(&ir, SIOCGIFBRDADDR);
> +        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;

Here you should use ifr_broadaddr, and so on... look directly at struct ifreq 
definition. That is an union so what you do happens to work, but this detail 
is not part of the API, so don't cheat ;-).

> +        broadcast = if_addr->sin_addr.s_addr;
> +
> +        ipaddress_dev_ioctl(&ir, SIOCGIFDSTADDR);
> +        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;
> +        destination = if_addr->sin_addr.s_addr;
> +
> +        seq_printf(seq, "ethx: %u %u %u %u\n",
> +                   local,
> +                   mask,
> +                   broadcast,
> +                   destination);
> +        //inet_ntoa(local_addr->sin_addr));
> +        return 0;
> +}
> +
> +static int ipaddress_seq_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, ipaddress_seq_show, NULL);
> +}
> +
> +static struct file_operations ipaddress_seq_fops = {
> +	.owner	 = THIS_MODULE,
> +	.open	 = ipaddress_seq_open,
> +	.read	 = seq_read,
> +	.llseek	 = seq_lseek,
> +	.release = single_release,
> +};
> +
> +//// End new IP Address proc interface
> +
> +
>  static int fold_prot_inuse(struct proto *proto)
>  {
>  	int res = 0;
> @@ -65,7 +136,7 @@
>  		   fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
>  		   tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
>  		   atomic_read(&tcp_memory_allocated));
> -	seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
> + 	seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
>  	seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
>  	seq_printf(seq,  "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
>  		   atomic_read(&ip_frag_mem));
> @@ -365,8 +436,14 @@
>
>  	if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
>  		goto out_sockstat;
> +
> +        if (!proc_net_fops_create("ipaddress", S_IRUGO,
> &ipaddress_seq_fops))
> +                goto out_sockstat; 

This is goto out_ipaddress (the naming is misleading, ok, but compare with the 
above goto).

> +
>  out:
>  	return rc;
> +out_ipadress:
> +        proc_net_remove("sockstat");
>  out_sockstat:
>  	proc_net_remove("snmp");
>  out_snmp:

-- 
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade
http://www.user-mode-linux.org/~blaisorblade
Chiacchiera con i tuoi amici in tempo reale! 
 http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com 


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [uml-devel] [uml-user] proc filesystem ipaddress
  2006-10-14  1:46 ` [uml-devel] [uml-user] proc filesystem ipaddress Blaisorblade
@ 2006-10-14  1:50   ` Blaisorblade
  2006-10-14 11:31   ` Nic James Ferrier
  1 sibling, 0 replies; 5+ messages in thread
From: Blaisorblade @ 2006-10-14  1:50 UTC (permalink / raw)
  To: user-mode-linux-devel; +Cc: Nic James Ferrier, user-mode-linux-user

On Saturday 14 October 2006 03:46, Blaisorblade wrote:
> On Friday 13 October 2006 05:33, Nic James Ferrier wrote:
> > I know this is not UML specific... but maybe the kernel hackers here
> > can answer this anyway, since I'm doing it to make life with UMLs
> > easier.
> >
> > I've patched the ipv4 stack so that it does proc registration of the
> > IP address for an iface.
>
> Take a look at /proc/net/if_inet6, generated by
net/ipv6/addrconf.c
(I forgot this).
-- 
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade
http://www.user-mode-linux.org/~blaisorblade
Chiacchiera con i tuoi amici in tempo reale! 
 http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com 


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [uml-devel] [uml-user] proc filesystem ipaddress
  2006-10-14  1:46 ` [uml-devel] [uml-user] proc filesystem ipaddress Blaisorblade
  2006-10-14  1:50   ` Blaisorblade
@ 2006-10-14 11:31   ` Nic James Ferrier
  2006-10-15 17:24     ` Blaisorblade
  1 sibling, 1 reply; 5+ messages in thread
From: Nic James Ferrier @ 2006-10-14 11:31 UTC (permalink / raw)
  To: Blaisorblade; +Cc: user-mode-linux-devel, user-mode-linux-user

[-- Attachment #1: Type: text/plain, Size: 2483 bytes --]

Blaisorblade <blaisorblade@yahoo.it> writes:

> On Friday 13 October 2006 05:33, Nic James Ferrier wrote:
>> I've patched the ipv4 stack so that it does proc registration of the
>> IP address for an iface.
> Take a look at /proc/net/if_inet6, generated by 

I did take a look at that. It seems to be done a bit
differently. There's what looks like a cleaner interface to config.

I may be a confident C hacker, but I'm not going to start refactoring
the ipv4 stack with my first patch /8->



>> I'm using kernel ioctl calls (correctly surrounded by get_fs/set_fs
>> calls) to get the interface data.
>
>> All the interface data is returned at 16 bits.
> I.e. that's the seq_printf string, right?

Yes. The data passed to the seq_printf string has had 16 bits chopped
off it.

It looks to me like the data is getting lost in the conversion from
kernel space to user space which occurs at the end of the ioctl
wrapper.


> I know you're beginning to write kernel code and this is not even a finished 
> patch, however I'm commenting _various_ improvable aspects of the work. Do 
> not worry for that.

Any comments are *very* welcome.

I've attached a cleaner copy of my patch with my debug and sketch code
removed. It's down to the bear essentials which is a call to ioctl to
retrieve the address only getting 16 bits of the necessary data.


> Also, for mainline acceptance I guess they'd prefer to bypass ioctl and access 
> directly the needed fields.

The ipv4 config and dhcp code uses the ioctl stuff which is why I
did. I wasn't sure about this... I think it makes more sense for the
kernel to be able to access the fields directly as well. And it's the
ioctl that seems to be causing the problem. However, if you don't need
the ioctl why does the ipv4 config code call it?


> Beyond that, I've found your bug. You can cast a (struct sockaddr*) to a 
> (struct sockaddr_in*), but your doing a worse cast; since ifr_addr is a 
> struct sockaddr, 

I don't think I'm doing that:

  ifreq.ifr_addr 

  is the same as:  ifreq.ifr_ifru.ifru_addr 

  which is a:  struct sockaddr

So ifreq.ifr_addr.sa_data is a sockaddr_in right?


> the _below_ version is correct:
> if_addr = (struct sockaddr_in *) ir.ifr_addr;

This doesn't compile.


> This is goto out_ipaddress (the naming is misleading, ok, but compare with the 
> above goto).

Yes... sorry, that is an ommision from a previous edit.

-- 
Nic Ferrier
http://www.tapsellferrier.co.uk   for all your tapsell ferrier needs


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: netaddress_proc_patch --]
[-- Type: text/x-patch, Size: 3026 bytes --]

--- /scp:root@sanders:/var/local/virtualmachine/kernels/linux-2.6.17.1/net/ipv4/proc.c
+++ /var/local/src/linux-2.6.17.1/net/ipv4/proc.c
@@ -44,6 +44,77 @@
 #include <net/sock.h>
 #include <net/raw.h>
 
+
+//// New IP Address proc interface
+#include <asm/uaccess.h>
+#include <linux/if.h>
+
+static int ipaddress_dev_ioctl(struct ifreq *ir, unsigned int cmd)
+{
+	int res;
+        mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+	res = devinet_ioctl(cmd, (struct ifreq __user *) ir);
+	set_fs(oldfs);
+	return res;
+}
+
+static int ipaddress_seq_show(struct seq_file *seq, void *v)
+{
+        struct ifreq ir;
+        struct sockaddr_in * if_addr;
+        uint32_t local;
+
+        memset(&ir, 0, sizeof(ir));
+        strcpy(ir.ifr_ifrn.ifrn_name, "eth0");
+
+        ipaddress_dev_ioctl(&ir, SIOCGIFADDR);
+
+        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;
+        local = if_addr->sin_addr.s_addr;
+
+        seq_printf(seq, "eth0: %u\n", local);        
+
+        /*
+        ipaddress_dev_ioctl(&ir, SIOCGIFNETMASK);
+        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;
+        mask = if_addr->sin_addr.s_addr;
+
+        ipaddress_dev_ioctl(&ir, SIOCGIFBRDADDR);
+        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;
+        broadcast = if_addr->sin_addr.s_addr;
+
+        ipaddress_dev_ioctl(&ir, SIOCGIFDSTADDR);
+        if_addr = (struct sockaddr_in *) ir.ifr_addr.sa_data;
+        destination = if_addr->sin_addr.s_addr;
+
+        seq_printf(seq, "ethx: %u %u %u %u\n",
+                   local,
+                   mask,
+                   broadcast,
+                   destination);
+        */
+        return 0;
+}
+
+static int ipaddress_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ipaddress_seq_show, NULL);
+}
+
+static struct file_operations ipaddress_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = ipaddress_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release,
+};
+
+//// End new IP Address proc interface
+
+
 static int fold_prot_inuse(struct proto *proto)
 {
 	int res = 0;
@@ -65,7 +136,7 @@
 		   fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
 		   tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
 		   atomic_read(&tcp_memory_allocated));
-	seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
+ 	seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
 	seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
 	seq_printf(seq,  "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
 		   atomic_read(&ip_frag_mem));
@@ -365,8 +436,14 @@
 
 	if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
 		goto out_sockstat;
+
+        if (!proc_net_fops_create("ipaddress", S_IRUGO, &ipaddress_seq_fops))
+                goto out_ipaddress;
+
 out:
 	return rc;
+out_ipadress:
+        proc_net_remove("sockstat");
 out_sockstat:
 	proc_net_remove("snmp");
 out_snmp:

Diff finished.  Sat Oct 14 12:29:27 2006

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 194 bytes --]

_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [uml-devel] [uml-user] proc filesystem ipaddress
  2006-10-14 11:31   ` Nic James Ferrier
@ 2006-10-15 17:24     ` Blaisorblade
  2006-10-15 23:32       ` Nic James Ferrier
  0 siblings, 1 reply; 5+ messages in thread
From: Blaisorblade @ 2006-10-15 17:24 UTC (permalink / raw)
  To: Nic James Ferrier; +Cc: user-mode-linux-devel, user-mode-linux-user

On Saturday 14 October 2006 13:31, Nic James Ferrier wrote:
> Blaisorblade <blaisorblade@yahoo.it> writes:
> > On Friday 13 October 2006 05:33, Nic James Ferrier wrote:
> >> I've patched the ipv4 stack so that it does proc registration of the
> >> IP address for an iface.
> >
> > Take a look at /proc/net/if_inet6, generated by
>
> I did take a look at that. It seems to be done a bit
> differently. There's what looks like a cleaner interface to config.
>
> I may be a confident C hacker, but I'm not going to start refactoring
> the ipv4 stack with my first patch /8->

Agreed - I started kernel coding with much more stupid work (I've never coded 
_large_ programs _in C_ before working on Linux).

> > I know you're beginning to write kernel code and this is not even a
> > finished patch, however I'm commenting _various_ improvable aspects of
> > the work. Do not worry for that.

> Any comments are *very* welcome.

> I've attached a cleaner copy of my patch with my debug and sketch code
> removed. It's down to the bear essentials which is a call to ioctl to
> retrieve the address only getting 16 bits of the necessary data.

> > Also, for mainline acceptance I guess they'd prefer to bypass ioctl and
> > access directly the needed fields.

> The ipv4 config and dhcp code uses the ioctl stuff which is why I
> did. I wasn't sure about this... I think it makes more sense for the
> kernel to be able to access the fields directly as well. And it's the
> ioctl that seems to be causing the problem. However, if you don't need
> the ioctl why does the ipv4 config code call it?

Ok, that was _my_ guess, and that code _does_ skip ioctl - but if you found 
code which uses it, then there are reasons for it.

> > Beyond that, I've found your bug. You can cast a (struct sockaddr*) to a
> > (struct sockaddr_in*), but your doing a worse cast; since ifr_addr is a
> > struct sockaddr,
>
> I don't think I'm doing that:
>
>   ifreq.ifr_addr
>
>   is the same as:  ifreq.ifr_ifru.ifru_addr
>
>   which is a:  struct sockaddr

Yes, what I said.

> So ifreq.ifr_addr.sa_data is a sockaddr_in right?

Not at all. This explains the 2 missing bytes.

Both struct sockaddr and struct sockaddr_in have the first member 
(sa_family_t), which is 2 bytes wide - that's because this is like 
inheritance but in C: sockaddr_{un,in,*} are all casted to struct sockaddr 
when passing them to generic APIs (look for a bind() or connect() example to 
see this).

I can find a bind example in libc docs (having libc's info pages) with

info libc socket "internet namespace" "inet example"
it's also at:
http://www.fifi.org/doc/glibc-doc/html/chapters_16.html#SEC327

> > the _below_ version is correct:
> > if_addr = (struct sockaddr_in *) ir.ifr_addr;
>
> This doesn't compile.

Very possible, I didn't test it - I guess I forgot an &:
if_addr = (struct sockaddr_in *) &ir.ifr_addr;
I also forgot that if_addr is in bigendian order, so before printing it as an 
unsigned integer you should convert it (you'll anyway convert it to dotted 
representation I guess, when the problem will be fixed).

You can also see it in include/linux/in.h:
struct in_addr {
        __be32  s_addr;
};
__be32 is a plain 32bit integer, however sparse (a static checking tool) makes 
conversions between __be32 and __le32 or u32 impossible (it will only warn 
for that, actually). Much like it warns for conversion between __user 
pointers and normal ones.

> > This is goto out_ipaddress (the naming is misleading, ok, but compare
> > with the above goto).

> Yes... sorry, that is an ommision from a previous edit.
You also forgot to replace get_ds() with KERNEL_DS.

$ grep '\(get_ds\|KERNEL_DS\)' kernel/*.c mm/*.c
finds only examples of KERNEL_DS.

-- 
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade
http://www.user-mode-linux.org/~blaisorblade
Chiacchiera con i tuoi amici in tempo reale! 
 http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com 


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [uml-devel] [uml-user] proc filesystem ipaddress
  2006-10-15 17:24     ` Blaisorblade
@ 2006-10-15 23:32       ` Nic James Ferrier
  0 siblings, 0 replies; 5+ messages in thread
From: Nic James Ferrier @ 2006-10-15 23:32 UTC (permalink / raw)
  To: Blaisorblade; +Cc: user-mode-linux-user, user-mode-linux-devel

[-- Attachment #1: Type: text/plain, Size: 1591 bytes --]

Blaisorblade <blaisorblade@yahoo.it> writes:

>> > Beyond that, I've found your bug. You can cast a (struct sockaddr*) to a
>> > (struct sockaddr_in*), but your doing a worse cast; since ifr_addr is a
>> > struct sockaddr,
>>
>> I don't think I'm doing that:
>>
>>   ifreq.ifr_addr
>>
>>   is the same as:  ifreq.ifr_ifru.ifru_addr
>>
>>   which is a:  struct sockaddr
>
> Yes, what I said.
>
>> So ifreq.ifr_addr.sa_data is a sockaddr_in right?
>
> Not at all. This explains the 2 missing bytes.
>
> Both struct sockaddr and struct sockaddr_in have the first member 
> (sa_family_t), which is 2 bytes wide - that's because this is like 
> inheritance but in C: sockaddr_{un,in,*} are all casted to struct sockaddr 
> when passing them to generic APIs (look for a bind() or connect() example to 
> see this).

Ok. My confusion was to do with what exactly is contained in:

   struct sockaddr.sa_data

since it's typed at char[14].

I *thought* that it contained a ptr to a struct sockaddr_in.

Of course, I was wrong and this page led me to understand my mistake:

  http://www.comsc.ucok.edu/~mcdaniel/sockets/beej/sockaddr_structures.html

I should have read the Stephens in my bookshelf.

Thanks for putting me on the right track.


This is now fit for my purpose. I'm going to release an interesting
little service based on this code (I'll let the list know when it goes
live).


I will also add the necessary to the patch so that it can be submitted
to the kernel hackers (eg: interface iteration).

-- 
Nic Ferrier
http://www.tapsellferrier.co.uk   for all your tapsell ferrier needs


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: netaddress_proc_patch --]
[-- Type: text/x-patch, Size: 2519 bytes --]

--- /scp:root@sanders:/var/local/virtualmachine/kernels/linux-2.6.17.1/net/ipv4/proc.c
+++ /var/local/src/linux-2.6.17.1/net/ipv4/proc.c
@@ -44,6 +44,62 @@
 #include <net/sock.h>
 #include <net/raw.h>
 
+
+//// New IP Address proc interface
+#include <asm/uaccess.h>
+#include <linux/if.h>
+
+static int ipaddress_dev_ioctl(struct ifreq *ir, unsigned int cmd)
+{
+	int res;
+        mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	res = devinet_ioctl(cmd, (struct ifreq __user *) ir);
+	set_fs(oldfs);
+	return res;
+}
+
+static int ipaddress_seq_show(struct seq_file *seq, void *v)
+{
+        struct ifreq ir;
+        struct sockaddr_in* sa;
+        uint32_t addr;
+
+        memset(&ir, 0, sizeof(ir));
+        strcpy(ir.ifr_ifrn.ifrn_name, "eth0");
+
+        ipaddress_dev_ioctl(&ir, SIOCGIFADDR);
+        sa = (struct sockaddr_in *) &(ir.ifr_addr);
+        addr = sa->sin_addr.s_addr;
+        
+        seq_printf(seq,
+                   "eth0: %u.%u.%u.%u\n",
+                   (addr & 0xff),
+                   (addr & 0xff00) >>8,
+                   (addr & 0x00ff0000) >> 16,
+                   (addr & 0xff000000) >> 24);
+
+        return 0;
+}
+
+static int ipaddress_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ipaddress_seq_show, NULL);
+}
+
+static struct file_operations ipaddress_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = ipaddress_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release,
+};
+
+//// End new IP Address proc interface
+
+
 static int fold_prot_inuse(struct proto *proto)
 {
 	int res = 0;
@@ -65,7 +121,7 @@
 		   fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
 		   tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
 		   atomic_read(&tcp_memory_allocated));
-	seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
+ 	seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
 	seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
 	seq_printf(seq,  "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
 		   atomic_read(&ip_frag_mem));
@@ -365,8 +421,14 @@
 
 	if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
 		goto out_sockstat;
+
+        if (!proc_net_fops_create("ipaddress", S_IRUGO, &ipaddress_seq_fops))
+                goto out_ipaddress;
+
 out:
 	return rc;
+out_ipaddress:
+        proc_net_remove("sockstat");
 out_sockstat:
 	proc_net_remove("snmp");
 out_snmp:

Diff finished.  Mon Oct 16 00:30:02 2006

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 194 bytes --]

_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-10-15 23:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <E1GYDno-0007SX-JC@nicferrier.tapsellferrier.co.uk>
2006-10-14  1:46 ` [uml-devel] [uml-user] proc filesystem ipaddress Blaisorblade
2006-10-14  1:50   ` Blaisorblade
2006-10-14 11:31   ` Nic James Ferrier
2006-10-15 17:24     ` Blaisorblade
2006-10-15 23:32       ` Nic James Ferrier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox