# Add a new system call at FreeBSD-11 for calculating sum of two values



## suraty (Feb 13, 2017)

Hello, I am a beginner in FreeBSD. I installed FreeBSD-11.0-RELEASE-amd64 on VM. I want to add first new system call that it is for calculating sum of two values.
I read a sample in https://www.nostarch.com/rootkits.htm.

```
struct sc_example_args {
char *str;
};
static int
sc_example(struct thread *td, void *syscall_args)
{
struct sc_example_args *uap;
uap = (struct sc_example_args *)syscall_args;
printf("%s\n", uap->str);
return(0);
}
Notice that the system call’s arguments are declared within a structure
(sc_example_args). Also, notice that these arguments are accessed within the
system call function by first declaring a struct sc_example_args pointer (uap)
and then assigning the coerced void pointer (syscall_args) to that pointer.
```
But my function has errors!
myfile.c

```
#include <sys/sysproto.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysent.h>

#ifndef _SYS_SYSPROTO_H_
  struct myargs {
       unsigned int k0;
       unsigned int k1;
};
#endif

int func (struct thread *td, void *args)
{
     struct myargs *uap;
     unsigned int a,b,c;
     uap = (struct myargs *)args;
     a = uap->k0;
     b = uap->k1;
     c = a + b;
     printf("%u + %u = %u\n",a,b,c);
     return (0);
}
```

Errors:

```
note: forward declaration of 'struct myargs' 
struct myargs *uap;
error: incomplete definition of type 'struct myargs'
a = uap->k0;
```


----------



## ASX (Feb 13, 2017)

look like _SYS_SYSPROTO_H_ is defined and therefore "myargs" is not.


----------



## kafka0 (Feb 13, 2017)

Why are you enclosing the declaration of the struct myargs in the ifndef/endif guard block? It reads like you expect the sys/sysproto.h header to contain the declaration...


----------



## ShelLuser (Feb 13, 2017)

Instead of trying to follow 10 year old examples from want-to-be scriptkiddies (personal opinion) why don't you study the official documentation instead? The developers handbook gives you a good and complete overview on the whole FreeBSD hierarchy and also explains the whole kernel model.

Then there's the FreeBSD wiki which provides a ready to use example.

I'd trust those sources over "how to write a rootkit" any day of the week.


----------



## suraty (Feb 13, 2017)

Thanks, without `#ifndef _SYS_SYSPROTO_H_` it worked!
But, when I call
`syscall(550,1,1);`
output is:
`1 + 0 = 1`
But, I send 1+1. I tested it with other numbers again.
Why k1 is zero, always?


----------



## kafka0 (Feb 13, 2017)

Why is the second argument of func() a void* and not explicitly a struct myargs*?

Take the time to read the wiki page (and the additional documentation) ShelLuser just mentioned, that should put you on the right tracks and clear up any misunderstanding.


----------



## suraty (Feb 14, 2017)

kafka0 said:


> Why is the second argument of func() a void* and not explicitly a struct myargs*?
> 
> Take the time to read the wiki page (and the additional documentation) ShelLuser just mentioned, that should put you on the right tracks and clear up any misunderstanding.



Hello,
my edited code:


```
#include <sys/sysproto.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysent.h>

  struct myargs {
       unsigned int k0;
       unsigned int k1;
};

int sys_func(struct thread *td, struct myargs *uap);

int sys_func (struct thread *td, struct myargs *uap)
{
     unsigned int a,b,c;
     a = uap->k0;
     b = uap->k1;
     c = a + b;
     printf("%u + %u = %u\n",a,b,c);
     return (0);
}
```

But, Errro!

```
usr/src/sys/kern/mykern.c:17:5: error: conflicting types for 'sys_func'
int sys_func(struct thread *td, struct myargs *uap)

/usr/src/sys/sys/sysproto.h:2180:5: note: previous declaration is here 
int sys_func(struct thread *, struct func_args *);
```
I read a part from https://wiki.freebsd.org/AddingSyscalls

```
After adding an entry to sys/kern/syscalls.master, you must regenerate the generated files in sys/kern and sys/sys:
$ make -C sys/kern/ sysent
mv -f init_sysent.c init_sysent.c.bak
mv -f syscalls.c syscalls.c.bak
mv -f systrace_args.c systrace_args.c.bak
mv -f ../sys/syscall.h ../sys/syscall.h.bak
mv -f ../sys/syscall.mk ../sys/syscall.mk.bak
mv -f ../sys/sysproto.h ../sys/sysproto.h.bak
sh makesyscalls.sh syscalls.master
```
I checked sysproto.h file and in it:

```
struct func_args {
char uap_l_[PADL_(struct myargs *)]; struct myargs * uap; char uap_r_[PADR_(struct myargs *)];
};



sys_func(struct thread *, struct func_args*);
```

What is func_args?
Is there any solution?


----------



## ASX (Feb 14, 2017)

suraty said:


> Hello,
> What is func_args?
> Is there any solution?



suraty, by asking things like these, you expose a lack of knowledge of C basics.... which then lead to a next question: why are you trying to writing kernel code at this stage ?

Writing kernel code is more complex than writing userland programs, due to a variety of rules and restrictions, it seems you want to skip some essential steps ... but that will lead you to frustration only.

You may want to reconsider your learning approach. That said, I'm not a teacher and you are free to proceed as you like.


----------



## suraty (Feb 16, 2017)

I edited my code, so it has no error. I hope it will be useful for others.

```
#include <sys/sysproto.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/sysent.h>

#ifndef _SYS_SYSPROTO_H_
  struct func_args {
       unsigned int k0;
       unsigned int k1;
};
#endif


int sys_func (struct thread *td, struct func_args *uap)
{
     unsigned int a,b,c;
     a = uap->k0;
     b = uap->k1;
     c = a + b;
     printf("%u + %u = %u\n",a,b,c);
     return (0);
}
```


----------

