Compiling C code failed

Hi, newbie here. I'm trying to compile notsodeep, which is an active deep packet inspection circumvention utility for Linux. It works well in my testing (with Debian x86), but since there are no binaries for openwrt I decided to compile it. However, I ran into the following issue:

rickz@rickz-deb:~/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/bin$ ./mips-openwrt-linux-musl-gcc-7.4.0 -Wall -Wextra -Wformat-security -O3 -fstack-protector-all -lnetfilter-queue -lnfnetlink notsodeep.c -o notsodeep
mips-openwrt-linux-musl-gcc-7.4.0: warning: environment variable 'STAGING_DIR' not defined
notsodeep.c: In function 'tcp_synack_segment':
notsodeep.c:13:12: error: 'struct tcphdr' has no member named 'urg'
  if (tcphdr->urg == 0 &&
            ^~
notsodeep.c:14:11: error: 'struct tcphdr' has no member named 'ack'; did you mean 'th_ack'?
   tcphdr->ack == 1 &&
           ^~~
           th_ack
notsodeep.c:15:9: error: 'struct tcphdr' has no member named 'psh'
   tcphdr->psh == 0 &&
         ^~
notsodeep.c:16:9: error: 'struct tcphdr' has no member named 'rst'
   tcphdr->rst == 0 &&
         ^~
notsodeep.c:17:9: error: 'struct tcphdr' has no member named 'syn'
   tcphdr->syn == 1 &&
         ^~
notsodeep.c:18:9: error: 'struct tcphdr' has no member named 'fin'
   tcphdr->fin == 0) {
         ^~
notsodeep.c: In function 'tcp_checksum':
notsodeep.c:35:14: error: 'struct tcphdr' has no member named 'check'; did you mean 'th_ack'?
     tcphdrp->check = 0;
              ^~~~~
              th_ack
notsodeep.c:48:14: error: 'struct tcphdr' has no member named 'check'; did you mean 'th_ack'?
     tcphdrp->check = (unsigned short)sum;
              ^~~~~
              th_ack
notsodeep.c: In function 'rewrite_win_size':
notsodeep.c:58:8: error: 'struct tcphdr' has no member named 'window'
  tcphdr->window = htons(new_window);
        ^~
>

From what I read, it is because of different C libraries. Is that so? Is there anything I could do to compile it properly? And I tried to set the staging_dir, but it results in:

rickz@rickz-deb:~/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/bin$ export STAGING_DIR=/home/rickz/openwrt/staging_dir
rickz@rickz-deb:~/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/bin$ ./mips-openwrt-linux-musl-gcc-7.4.0 -Wall -Wextra -Wformat-security -O3 -fstack-protector-all -lnetfilter-queue -lnfnetlink notsodeep.c -o notsodeep
notsodeep.c:8:10: fatal error: libnetfilter_queue/libnetfilter_queue.h: No such file or directory
 #include <libnetfilter_queue/libnetfilter_queue.h>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

Any pointers? Thanks before, much appreciated.

You should craft a proper Openwrt Makefile for the package. That would set the needed options for compiler.

Thank you. I have read the wiki, but I am completely unfamiliar with the options (and the build system in general), also documentation on this program is scarce. Can I have a dumbed-down example of a makefile?

In my case I set STAGING_DIR to something like myopenwrt/staging_dir/target-arm_cortex-a8+vfpv3_musl_eabi, you must add the last directory, of course adapted to your target.

Some references I have found useful include:

https://openwrt.org/docs/guide-developer/packages

https://openwrt.org/docs/guide-developer/single.package

Not knowing what the "usual" build process is for "notsodeep", I can't directly recommend an example Makefile, but there are many examples in ./package/ and ./feeds/

@jan I have set the staging_dir to the toolchain directory, same result. Thanks anyway!

@jeff

Not knowing what the "usual" build process is for "notsodeep", I can't directly recommend an example Makefile, but there are many examples in ./package/ and ./feeds/

If its any help, this is the makefile that comes with notsodeep. I tried to find settings regarding compiling in Makefiles in ./package, but to no avail.

CC      ?= gcc
CFLAGS   = -Wall -Wextra -Wformat-security -O3 -fstack-protector-all
LIBS  = -lnetfilter_queue -lnfnetlink
PROGRAM  = notsodeep
SOURCE   = notsodeep.c

all: notsodeep 

notsodeep: notsodeep.c
	$(CC) $(SOURCE) $(CFLAGS) $(LIBS) -o $(PROGRAM)

clean:
	@rm -rf $(PROGRAM)

You need to build with -D_GNU_SOURCE or even better, with -std=gnu99 in TARGET_CFLAGS. The struct tcphdr fields mentioned in your error message are protected by an #ifdef _GNU_SOURCE feature test macro in musl libc.

2 Likes

@jow Yes, I stumbled upon the commented define _GNU_SOURCE 1 in include/features.h. I simply uncommented it, and it looks like the struct tcphdr errors have gone. Probably not a good practice, hehe.

However I am now facing a new problem. When attempting to compile, this came out:

rickz@rickz-deb:~/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/bin$ ./mips-openwrt-linux-musl-gcc -Wall -Wextra -Wformat-security -O3 -fstack-protector-all -lnetfilter-queue -lnfnetlink notsodeep.c -o notsodeep
mips-openwrt-linux-musl-gcc: warning: environment variable 'STAGING_DIR' not defined
mips-openwrt-linux-musl-gcc: warning: environment variable 'STAGING_DIR' not defined
mips-openwrt-linux-musl-gcc: warning: environment variable 'STAGING_DIR' not defined
/home/rickz/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/lib/gcc/mips-openwrt-linux-musl/7.4.0/../../../../mips-openwrt-linux-musl/bin/ld: cannot find -lnetfilter-queue
/home/rickz/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/lib/gcc/mips-openwrt-linux-musl/7.4.0/../../../../mips-openwrt-linux-musl/bin/ld: cannot find -lnfnetlink
collect2: error: ld returned 1 exit status

It seems that the libraries are missing. How can I add them?