extern in C

Deepak Saxena deepak@csociety.purdue.edu
Wed, 7 Mar 2001 01:48:48 -0500


--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


I'm assuming that demo.c is a user space prog? If so, there is _no_ possible
way for it to call add_to_cache directly.  add_to_cache is in the kernel
symbol table, it can only be called by kernel functions.  To call it from
user space, you need to either:

- Add a system call
  This is HIGHLY NOT recomended unless the function is extremely speed
  sensitive.  From the function name, I'm assuming no.
- Provide a device/driver specific ioctl that is accessed through a /dev
  entry
- Provide an entry in /proc that can be write()n to for changing parameters.
- Provide a sysctl() interface

In all of the above cases, you can, and I highly reccomend you do, create
a user space library wrapper add_to_cache function that performs the actual
kernel call to abstract your users from the low level details.

If demo.c is meant to be run by the kernel, you have to build it, but
not attempt to link it and than insmod the resulting .o into the kernel
and have the init_module() function do the magic.

BTW, it looks like you're writing code to add something to the kernel
ARP cache from user space. If that's what you want to do, this already 
exists.  I ran the following

  /sbin/arp -s 192.168.0.40 00:10:20:30:40:51

And did an strace (output attached).  If you create a socket and do 
a SIOCSARP on it, you can alter the arp table from user space. Again,
a add_to_cache() library call that wraps this is probably the best 
way to go.

~Deepak

On Mar 06 2001, at 16:19, Brad Bonkoski was caught saying:
> Hello,
> 
> I have a large project in which I have multiple .c files that I am
> making a Linux Module out of.  I am trying to create an API for it, and
> thought that an easy way would be to extern some of the functions that I
> would allow "users" to include in their programs.  I thought I good
> place to start is to make a demo package of the functionality, or make a
> program myself using the *API*
> So, the grunt of it:
> 
> I have three basic files that need to be used:
> demo.c --> which calls the function add_to_cache( )
> api.h --> which has the function prototype: extern int add_to_cache(
> MAC_Value, IP_ADDR)
> arp.c --> which has the function definition of add_to_cache( )
> 
> so, arp.c is part of the actual module, which builds and registers with
> Linux.
> 
> Then I try to build demo.c seperately, linking only with the header file
> (api.h) which is also included in arp.c
> When compiling demo.c I get a linking error from 'ld' which says that
> add_to_cache is an unresolved symbol.
> What am I doing wrong?  when running "ksyms" the function appears to be
> registered, so should it link, or is there somethine else I should do?
> 
> Any help would be appreciated.
> Thanks,
> Brad
> 
> 
> _______________________________________________
> Plug-devel mailing list  -  Plug-devel@lists.PLUG.phoenix.az.us
> http://lists.PLUG.phoenix.az.us/mailman/listinfo/plug-devel

-- 
Deepak Saxena - deepak@csociety.purdue.edu - phone://602.790.0500

call me 'evil' call me 'tide is on your side' anything that you want
anybody knows you can conjure anything by the dark of the moon
  - Tori Amos, "Suede"

--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=arp

execve("/sbin/arp", ["/sbin/arp", "-s", "192.168.0.40", "00:10:20:30:40:51"], [/* 25 vars */]) = 0
brk(0)                                  = 0x805230c
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40014000
open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26453, ...}) = 0
old_mmap(NULL, 26453, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=4101324, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\210\212"..., 4096) = 4096
old_mmap(NULL, 1001564, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x4001c000
mprotect(0x40109000, 30812, PROT_NONE)  = 0
old_mmap(0x40109000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xec000) = 0x40109000
old_mmap(0x4010d000, 14428, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4010d000
close(3)                                = 0
mprotect(0x4001c000, 970752, PROT_READ|PROT_WRITE) = 0
mprotect(0x4001c000, 970752, PROT_READ|PROT_EXEC) = 0
munmap(0x40015000, 26453)               = 0
personality(PER_LINUX)                  = 0
getpid()                                = 24971
brk(0)                                  = 0x805230c
brk(0x805232c)                          = 0x805232c
brk(0x8053000)                          = 0x8053000
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
fstat64(0x3, 0xbfffb680)                = -1 ENOSYS (Function not implemented)
fstat(3, {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2265
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x40015000, 4096)                = 0
open("/usr/share/i18n/locale.alias", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/net-tools.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
ioctl(3, SIOCSARP, 0xbffff874)          = 0
_exit(0)                                = ?

--C7zPtVaVf+AK4Oqc--