RE: about ipv6...

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

 



Hi Joe,

Thanks for your reply. I wanted to change the address of the input
parameter. Actually, the input addr comes from struct flowi
(/include/net/flow.h).

fl->fl_dst

The funny thing is that using the same function, I was able to modified
another in6_addr in the kernel, but when I used the same function on the
destination address of struct flowi, I got a kernel panic. BTW, is there
anyway of looking at the output just before the kernel panic? I couldn't
see anything in the log after I reboot. 

My thoughts are:
1. There is a lock on the flowi structure which prohibits any
overwriting.
2. The flowi structure is not in the kernel space. (highly impossible)

Does anyone have any experience with flowi?


My second question is as follows:
1. In ip6_xmit and ip6_build_xmit (ip6_output.c), I modified the source
and destination address of the skbuff after the IPSEC portion.

2. In ip6_input (ip6_input.c), I modified the source and destination
address back to the original addresses of the skbuff right at the end of
the function.

3. When I ping using the original address, I noticed that instead of
ICMP_ECHO_REPLY, I got NDISC_REDIRECT. Even when I got the first
ICMP_ECHO_REPLY, I encountered an "ICMPv6 checksum failed" error.

4. Does anyone know how the thing works?

Thanks for any help. :-P

Jon.

-----Original Message-----
From: Joe@orado.localdomain.private
[mailto:Joe@orado.localdomain.private] On Behalf Of Joseph A Knapka
Sent: Monday, January 28, 2002 9:32 PM
To: Jonathan Khoo
Cc: kernelnewbies@nl.linux.org
Subject: Re: about ipv6...

Jonathan Khoo wrote:
> 
> Hi guys,
> 
> I hacked part of the route.c under /net/ipv6. I made modifications to
> ip6_route_output, trying to change the destination address, so that a
> different interface will be chosen. This will then affect the hash_val
> that will be calculated under neigh_lookup (ndisc.c) used for
neighbour
> discovery.
> 
> I tested the codes listed below in the user-land and everything is
okay.
> However, when I merged it into the kernel and it always goes into
kernel
> panic at the memcpy statement. I must apologize as I am not well
versed
> with c and always made silly mistakes over pointers. I would
appreciate
> it if anyone can help point out my errors.
> 
> Thanks in advance.
> Jon.
> 
> The codes are basically:
> 
> struct in6_addr *daddr;
> 
> my_function(daddr);
> 
> ....
> 
> (in another file)
> void my_function(struct in6_addr *addr)
> {
>   struct in6_addr *newaddr;
>   ....
>   memcpy(&(*addr), &(*newaddr), sizeof(struct in6_addr));

This is equivalent to

   memcpy(addr, newaddr, sizeof(struct in6_addr));

Note that with memcpy, the first argument is the *destination*
address. So you are copying the contents of a random memory
block (whatever is pointed to by the uninitialized "newaddr")
over the address passed in "addr". This is certainly not what
you want :-)

First, if you want to make a copy of the struct pointed to
by "addr", you need a place to put it, so you must either
declare a struct in6_addr on the stack, or else declare
a pointer (as you've done) and malloc() storage for it to
point to. I'll do both:

void my_function(struct in6_addr *addr)
{
  struct in6_addr newstruct;
  struct in6_addr *newaddr;

  /* Local copy... */
  memcpy(&newstruct, addr, sizeof(struct in6_addr));
  
  /* Heap copy... */
  newaddr = (struct in6_addr*)malloc(sizeof(struct in6_addr));
  memcpy(newaddr,addr,sizeof(struct in6_addr));

  /*...*/

  /* return &newstruct; WRONG! Don't do this. */
  return newaddr; /* And don't forget to free(newaddr) when you're done.
*/
}


Note that you cannot successfully return &newstruct from
my_function(), since its storage is allocated in the stack
frame in which my_function() executes, and will therefore
be destroyed (logically) when my_function() returns to its
caller (you might get such code to *appear* to work under
a limited set of circumstances, but it's wrong: as soon as
some function call needs to re-use the stack space on which
newstruct was allocated, it will be destroyed). You *can*
return newaddr, the address of an in6_addr allocated on the
heap -- but you must be sure to free the malloc'd memory when
you are done with it, or else you have a memory leak.

A thorough understanding of exactly how functions are
called, stack frames constructed, and free storage
managed is absolutely critical to successful coding
in C, especially at the kernel level. Don't leave home
without it.

HTH,

-- Joe

-- 
"I should like to close this book by sticking out any part of my neck
 which is not yet exposed, and making a few predictions about how the
 problem of quantum gravity will in the end be solved."
 --- Physicist Lee Smolin, "Three Roads to Quantum Gravity"



--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
IRC Channel:   irc.openprojects.net / #kernelnewbies
Web Page:      http://www.kernelnewbies.org/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux