[Bro] Notes on compiling bro for Linksys

Jim Mellander jmellander at lbl.gov
Tue Jul 26 14:38:17 PDT 2005

Here's a log of my cross-compiling effort of the latest public Bro 
distribution to run on a linksys wireless router using the openwrt.org 
distribution.  The goal here was not to cross compile the whole bro 
environment, but to create a bro binary that will function as expected 
on the box.  The scripts, etc. are copied over from a working installation.

The log appears to be one interrupted path of forward progress, whereas 
in reality, there were numerous false starts, blind alleys, 
head-scratching, and dumb luck involved.

Hopefully, this will be of use to others attempting porting, etc. to odd 
platforms.  BTW the shell used is bash, if you're using another one, YMMV

Still to be compiled are utilities (cf, etc.)


1. Download latest bro 0.9a9 from broids.org
2. compile for host system (linux) and save compiled program 'bifcl' away
3. delete tree & recreate from tarball (all we wanted from step 2 was bifcl)
4. Download openwrt buildroot, see 
5. Build in home directory - we are really just interested in the 
cross-compile toolkit. (note: you may need to be running GNU Make 3.80, 
older versions sometimes fail - OTOH, this version fails in different 
ways - I compiled & put v3.80 in /usr/local/bin, the original make on my 
distro is 3.79.1 - so if strange make problems occur, try modifying PATH 
so that other make is found first).  Note that only the cross compile 
tools in openwrt/staging_dir_mipsel/bin really need to be built, as well 
as the uclibc stuff (all should be there if you got thru most of the 

6. Set PATH to have <basedir>/openwrt/staging_dir_mipsel/bin before 
other stuff, so cross compile will work. Go into that directory and run:

for i in mipsel-linux-*; do ln -s $i `echo $i|sed s/mipsel-linux-//`; done

to create gcc, etc. links (running the above probably isn't really 

7. go into bro directory
8. execute ./configure --build=mipsel-linux to perform cross-compile 
9. Go into src directory, edit Makefile, comment out stuff unpacking & 
building libedit, edit ../config.h, uncomment line: #undef HAVE_READLINE
10. copy back in previously compiled bifcl

11. Now we a going to need libpcap - so create a new directory & 
download libpcap-0.8.3.tar.gz to it. unpack & go into libpcap-0.8.3
11a. Remember that PATH still needs to have the cross compile tools 
before compiling,etc.
12. execute:
ac_cv_linux_vers=2 ./configure --host=mipsel-linux --with-pcap=linux
  to perform cross-compile configure
13. run make, should complete, and produce a libpcap.a
14. copy libpcap.a and *.h to bro src directory
15. go back into bro src directory, edit Makefile, modify INCLS and LIBS 
as follows:


INCLS =  -I${top_srcdir}/linux-include -I${top_srcdir}/aux/libpcap-0.7.2
-L${top_srcdir}/aux/libpcap-0.7.2 -lpcap -lresolv  -ltermcap -lm


INCLS =  -I${top_srcdir}/linux-include -I${top_srcdir}/src
LIBS = $(LIBEDIT_LIBS) $(LIBIDMEF_LIBS) -L${top_srcdir}/src -lpcap 
-lresolv  -ltermcap -lm

16. Now remember, you've copied in the precompiled bifcl

17. Edit SerialObj.h add line

before message squawking about it.

18. more modifications to Makefile:

19. In util.cc need gettimeofday() - modified code to just use /dev/urandom

         // Gather up some entropy.
         gettimeofday((struct timeval *)(buf + pos), 0);
         pos += sizeof(struct timeval) / sizeof(uint32);

#if defined(O_NONBLOCK)
         int fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
#elif defined(O_NDELAY)
         int fd = open("/dev/random", O_RDONLY | O_NDELAY);
         int fd = open("/dev/random", O_RDONLY);

	// Gather up some entropy.
	int fd = open("/dev/urandom", O_RDONLY);

19a. Change util.cc to always include sys/time.h - previous change not 
necessary, but not problematic either.

20 Compile continues until final link, then get error message:
ld: cannot find -ledit

which indicates looking for libedit which we (supposedly) disabled - 
edit Makefile, change LIBS, per below:

#LIBS = $(LIBEDIT_LIBS) $(LIBIDMEF_LIBS) -L${top_srcdir}/src -lpcap 
-lresolv  -ltermcap -lm
LIBS = $(LIBIDMEF_LIBS) -L${top_srcdir}/src -lpcap -lresolv  -ltermcap -lm

Next error, cannot find -ltermcap, solution: take out of LIBS above

Next error, missing Bind functions:

nb_dns.o(.text+0x3f0): In function `_nb_dns_mkquery':
/tmp/bro-0.9a9/src/nb_dns.c:293: undefined reference to `__res_mkquery'
nb_dns.o(.text+0x9b4): In function `nb_dns_activity':
/tmp/bro-0.9a9/src/nb_dns.c:476: undefined reference to `__ns_initparse'
nb_dns.o(.text+0xb9c):/tmp/bro-0.9a9/src/nb_dns.c:519: undefined 
reference to `_ns_flagdata'
nb_dns.o(.text+0xc94):/tmp/bro-0.9a9/src/nb_dns.c:561: undefined 
reference to `__ns_parserr'

21. Since these are name server functions, download BIND 9.3.1 source 
from http://www.isc.org/index.pl?/sw/bind/ to separate directory.

go into lib/bind, run:
./configure --host=mipsel-linux --enable-threads 

run make until error,
go into each subdir
run make until error

22. Now lets see if we have enough compiled to resolve the undefined 

$ find . -name '*.o'|xargs egrep -i 
'res_mkquery|ns_initparse|ns_flagdata|ns_parserr' /dev/null
Binary file ./nameser/ns_parse.o matches

$ nm ./nameser/ns_parse.o

          U __dn_expand
          U __dn_skipname
          U __errno_location
          U _gp_disp
          U memset
00000000 D _ns_flagdata
000001a8 T __ns_initparse
00000000 T __ns_msg_getflag
00000384 T __ns_parserr
00000044 T __ns_skiprr
00000174 t setsection

cp /home/jmel/bind/bind-9.3.1/lib/bind/nameser/ns_parse.o /tmp/bro-0.9a9/src

Add ns_parse.o to LIBS in Makefile

Now tackling res_mkquery, source is in lib/bind/resolv, make fails:
/home/jmel/bind/bind-9.3.1/lib/bind/port_after.h:384: error: conflicting 
types for 'getnetgrent_r'
./../include/netdb.h:528: error: previous declaration of 'getnetgrent_r' 
was here

in ../include/netdb.h getnetgrent_r is defined here:

#ifdef __GLIBC__
int             getnetgrent_r __P((char **, char **, char **, char *, 

Disable definition by wrapping in #if 0 / #endif
Compiled far enough to compile res_mkquery, so copy res_mkquery.o to 
bro/src directory, and add to LIBS

I actually ended up going into the top level directory of the bind build 
tree, and running
ar rs libbind.a `find . -name '*.o' -print`
ranlib libbind.a

then copy into the bro/src directory, and add -lbind to LIBS

Compile still fails, with missing pthread stuff, so:

Building dietlibc
20. pthread & friends can be gotten from another small C library: 
dietlibc, so download dietlibc-0.29 (search web for location) and 
compile in its own dir by:

make -n ARCH=mipsel CROSS=mipsel-linux- all >x
edit x and globallly remove -fno-pic
Also, globally modify -Os to -O0

Then 'sh x'

(These steps are necessary to ensure that the code is PIC, which is how 
Bro is compiled, and to turn off optimization, which is buggy)

cd bin-mipsel
ar rs libdiet.a *.o
ranlib libdiet.a

Then copy libdiet.a to bro/src directory, and add to LIBS in Makefile

When make is run in bro/src directory, errors in linking are:

Func.o(.text+0x8798): In function `bro_system(ValPList*)':
/tmp/bro-0.9a9/src/bro.bif:1138: warning: warning: system() is a 
security risk.  Use fork and execvp instead!
../src/libdiet.a(vfscanf.o)(.text+0x24): In function `vfscanf':
vfscanf.c: warning: warning: the scanf functions add several kilobytes 
of bloat.
../src/libdiet.a(vprintf.o)(.text+0x68): In function `vprintf':
vprintf.c: warning: warning: the printf functions add several kilobytes 
of bloat.
../src/libdiet.a(abort.o)(.text+0x8): In function `abort':
abort.c: undefined reference to `__stdio_flushall'
../src/libdiet.a(fclose.o)(.text+0x34): In function `fclose_unlocked':
fclose.c: undefined reference to `__stdio_root'
../src/libdiet.a(fclose.o)(.text+0x38):fclose.c: undefined reference to 
../src/libdiet.a(fclose.o)(.text+0x84):fclose.c: undefined reference to 
../src/libdiet.a(fgetc_unlocked.o)(.text+0x58): In function 
fgetc_unlocked.c: undefined reference to `__fflush4'
../src/libdiet.a(fputc_unlocked.o)(.text+0x24): In function 
fputc_unlocked.c: undefined reference to `__fflush4'
../src/libdiet.a(pthread_sys_alloc.o)(.text+0x68): In function `free':
pthread_sys_alloc.c: undefined reference to `__libc_free'
../src/libdiet.a(pthread_sys_alloc.o)(.text+0x148): In function `malloc':
pthread_sys_alloc.c: undefined reference to `__libc_malloc'
../src/libdiet.a(pthread_sys_alloc.o)(.text+0x23c): In function `realloc':
pthread_sys_alloc.c: undefined reference to `__libc_realloc'
../src/libdiet.a(pthread_sys_sigsuspend.o)(.text+0x28): In function 
pthread_sys_sigsuspend.c: undefined reference to `__libc_sigsuspend'
../src/libdiet.a(localtime_r.o)(.text+0x14): In function `localtime_r':
localtime_r.c: undefined reference to `__maplocaltime'
../src/libdiet.a(localtime_r.o)(.text+0x2c):localtime_r.c: undefined 
reference to `__tzfile_map'

So, lets just delete some functions from the library, go back in 
dietlibc directory, then into bin/mipsel, then delete the following files:


delete libdiet.a, then rebuild libdiet.a as indicated above, copy back 
into bro/src directory, run make

BTW- Final LIBS in Makefile is:

LIBS = $(LIBIDMEF_LIBS) -L${top_srcdir}/src -lpcap -lresolv -lm -lbind 

Bro compiles!!

$ ls -l bro
-rwxrwxr-x    1 jmel     jmel     10562750 Jul 26 14:23 bro
$ strip bro
$ ls -l bro
-rwxrwxr-x    1 jmel     jmel      2722728 Jul 26 14:23 bro

Jim Mellander
Incident Response Manager
Computer Protection Program
Lawrence Berkeley National Laboratory
(510) 486-7204

Your fortune for today is:

You may be recognized soon.  Hide.

More information about the Bro mailing list