Compile Open Source Project: nmap

This chapter will show you how to build an open source project for your DSM system using Package Toolkit.
The open source project that we are going to build in this example is nmap, a network scanning program. We will use x64 as our build environment platform.

If you wish to compile an open source project manually, please refer to Appendix B: Compile Open Source Project Manually.

As we have mentioned in Hello World Package, you have to create the SynoBuildConf/build, SynoBuildConf/install, and SynoBuildConf/depends before using Package Toolkit.

Unlike the previous example, compiling an application on most open source projects may require executing the following three steps:

  1. configure
  2. make
  3. make install

The configure script consists of many lines which are used to check some details about the machine where the software is going to be installed. This script will also check a lot of dependencies on your system. When you run the configure script, you will see a lot of output on the screen, each being some sort of question with a respective yes/no as a reply. If any of the major requirements are missing on your system, the configure script will exit and you will not be able to proceed with the installation until you meet the required conditions. In most cases, compile applications on some particular target machines will require you to modify the configure script manually to provide the correct values.

When running the configure script to configure software packages for cross-compiling, you will need to specify the CC, LD, RANLIB, CFLAGS, LDFLAGS, host, target, and build.

Preparation:

First, you will need to download the nmap source code from the official github site. You will also need to download the libpcap source code since nmap depends on libpcap. The libpcap source code can be found here.

The following commands will download the source code for libpacp and nmap.

wget https://nmap.org/dist/nmap-7.01.tar.bz2
tar xvf nmap-7.01.tar.bz2 -C /toolkit/source 
mv /toolkit/source/nmap-7.01 /toolkit/source/nmap

wget http://www.tcpdump.org/release/libpcap-1.6.2.tar.gz
tar xvf libpcap-1.6.2.tar.gz -C /toolkit/source
mv /toolkit/source/libpcap-1.6.2 /toolkit/source/libpcap

Or use git to download source code

cd /toolkit/source
git clone https://github.com/nmap/nmap

git clone https://github.com/the-tcpdump-group/libpcap
cd libpcap
git checkout origin/libpcap-1.6

Please remember to upgrade the libpacp to version 1.6 or the build package process will fail.

Project Layout:

After you download the source code, your toolkit layout should look like the following figure.

toolkit/
├── build_env/
│   └── ds.${platform}-${version}/
│       └── /usr/syno/
│           ├── bin
│           ├── include
│           └── lib
├── pkgscripts/
└── source/
    ├──nmap/
    │   ├── nmap related source code
    │   ├── INFO.sh
    │   ├── Makefile
    │   ├── Synoscripts/ # nmap has it's own scripts folder
    │   └── SynoBuildConf/
    │       ├── build
    │       ├── depends
    │       └── install
    └──libpcap/
        ├── libpcap related source code
        ├── Makefile
        └── SynoBuildConf/
            ├── build
            ├── depends
            ├── install-dev
            └── install

The file, install-dev, is a special file which we will be covered in the following section.

SynoBuildConf/depends:

The SynoBuildConf/depends for nmap is slightly different from the previous example. Since nmap depends on libpcap, we have to add the value to the BuildDependent field, so that the PkgCreate.py can resolve the dependency and compile the project in the correct order.

The depends file for nmap is as follows.

[BuildDependent]
libpcap

[default]
all="6.0"

However, the SynoBuildConf/depends for libpcap is the same as the Hello World Example.

[BuildDependent]

[default]
all="6.0"

SynoBuildConf/build:

The SynoBuildConf/build script is also different from the previous one.

Here you will have to pass several environment variables to configure, so that nmap can be compiled properly

  • CC
  • CXX
  • LD
  • AR
  • STRIP
  • RANLIB
  • NM
  • CFLAGS
  • CXXFLAGS
  • LDFLAGS

Since nmap will be compiled with many features by default, we will need to disable some of them to make it clean. The following list contains the features that will be disabled:

  • ndiff
  • zenmap
  • nping
  • ncat
  • nmap-update
  • liblua

Note: If you are interested in some of the above features and you want to enable them, just change the --without-${feature} into --with-${feature}.

The following is the SynoBuildConf/build for nmap

#!/bin/sh
# Copyright (c) 2000-2015 Synology Inc. All rights reserved.

include /env.mak

PKG_NAME=nmap
INST_DIR=/tmp/_${PKG_NAME}

case ${MakeClean} in
    [Yy][Ee][Ss])
        make distclean
        ;;
esac

env CC="${CC}" CXX="${CXX}" LD="${LD}" AR=${AR} STRIP=${STRIP} RANLIB=${RANLIB} NM=${NM} \
    CFLAGS="${CFLAGS}" CXXFLAGS="$CXXFLAGS $CFLAGS" \
    LDFLAGS="${LDFLAGS} -lnl -lnl-genl -ldbus-1" \
    ./configure ${ConfigOpt} \
    --prefix=${INST_DIR} \
    --without-ndiff \
    --without-zenmap \
    --without-nping \
    --without-ncat \
    --without-nmap-update \
    --without-liblua \
    --with-libpcap=/usr/local

make ${MAKE_FLAGS}

In this example,--with-libpcap is assigned with value /usr/local. We need to install libpcap's cross compiled product into "/usr/local" so that nmap's configure can retrieve libpcap correctly.

The following is the SynoBuildConf/build for libpcap.

#!/bin/bash
# Copyright (c) 2000-2012 Synology Inc. All rights reserved.

case ${MakeClean} in
    [Yy][Ee][Ss])
        make distclean
        ;;
esac

case ${CleanOnly} in
    [Yy][Ee][Ss])
        return
        ;;
esac

# prefix with /usr/local, all files will be installed into /usr/local
env CC="${CC}" CXX="${CXX}" LD="${LD}" AR=${AR} STRIP=${STRIP} RANLIB=${RANLIB} NM=${NM} \
    CFLAGS="${CFLAGS} -Os" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" \
    ./configure ${ConfigOpt} \
    --with-pcap=linux --prefix=/usr/local

make ${MAKE_FLAGS}

make install

The above script will install libpcap related files into /usr/local/ in chroot environment. After installing libpcap, nmap can find libpcap's cross compiled products in /usr/local.

Synology toolkit provides libpcap in chroot.

> dpkg -l | grep libpcap
ii  libpcap-x64-dev                  6.0-7274     all        Synology build-time library

nmap can use chroot's libpcap by using ${SysRootPrefix} variable.

--with-libpcap=${SysRootPrefix}

SynoBuildConf/install

Instead of copying the binary to the destination folder, most big projects will use make install to install the binaries and libraries. Since we have used the --prefix flag when configuring the nmap project, we can just execute make install and it will install the nmap related files to the folder specified by --prefix.

#!/bin/bash
# Copyright (c) 2000-2015 Synology Inc. All rights reserved.

PKG_NAME="nmap"
INST_DIR="/tmp/_${PKG_NAME}"
PKG_DIR="/tmp/_${PKG_NAME}_pkg"
PKG_DEST="/image/packages"

PrepareDirs() {
    for dir in $INST_DIR $PKG_DIR; do
        rm -rf "$dir"
    done
    for dir in $INST_DIR $PKG_DIR $PKG_DEST; do
        mkdir -p "$dir"
    done
}

SetupPackageFiles() {
    make install
    ./INFO.sh > INFO
    cp INFO "${PKG_DIR}"
    cp -r scripts/ "${PKG_DIR}"
}

MakePackage() {
    source /pkgscripts/include/pkg_util.sh
    pkg_make_package $INST_DIR $PKG_DIR
    pkg_make_spk $PKG_DIR $PKG_DEST
}

main() {
    PrepareDirs
    SetupPackageFiles
    MakePackage 
}

main "$@"

INFO.sh

As mentioned before, we will use INFO.sh to generate the INFO file.

#!/bin/sh
# Copyright (c) 2000-2015 Synology Inc. All rights reserved.

. /pkgscripts/include/pkg_util.sh
package="nmap"
version="7.01"
displayname="nmap"
arch="$(pkg_get_platform) "
maintainer="Synology Inc."
description="This package will install nmap in your DSM system."
[ "$(caller)" != "0 NULL" ] && return 0
pkg_dump_info

Note: Remember to set the executable bit of INFO.sh file.

Build and Create Package:

Lastly, run the following commands to compile the source code and build the package.

/toolkit/pkgscripts/PkgCreate.py -p x64 -x0 -c nmap

After the build process, you can check the result in /toolkit/result_spk.

Verify the Result

If the packing process was successful, you will see an spk file placed in the result_spk folder. To test the spk file, you can use manual install in DSM Package Center to install your package.

Warning: Remember to import your keys to the DSM system or select Any publisher in Package Center->Settings->General->Trust Level. Otherwise, the installation will fail.

You can then try to connect to the DSM using ssh and type the following command to fully scan your DSM machine.

cd /var/packages/nmap/target/usr/local/bin
./nmap -v -A localhost