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/