NetworkManager Conflict with DNS Caching?

NetworkManager is a program for providing detection and configuration for systems to automatically connect to network. Your network can easily be shared to others using it. But If you want to implement DNS caching on your machine, you will find it annoying. I used to face conflict between NetworkManager/ConnectionSharing and DNS Caching, but now I find a workaround.


My DNS Caching Configure

/etc/NetworkManager/NetworkManager.conf
[main]
dhcp=dhclient
dns=dnsmasq

It works, but you need root privilege to start networksharing, like this: sudo nmcli con up xxxx. I have also tried using systemd/dnsmasq, but it doesn’t work at all.


When you start a shared network, NetworkManager will start dnsmasq listening on port 53.
Type pgrep -a dnsmasq, you will get:

/usr/bin/dnsmasq --conf-file --no-hosts --keep-in-foreground --bind-interfaces --except-interface=lo --clear-on-reload --strict-order --listen-address=10.42.0.1 --dhcp-range=10.42.0.10,10.42.0.254,60m --dhcp-option=option:router,10.42.0.1 --dhcp-lease-max=50 --pid-file=/var/run/nm-dnsmasq-xxxx.pid`

At first I tried disable the dnsmasq’s dns function, but finally I found these arguements in the source code of NetworkManager.

/* dnsmasq may read from it's default config file location, which if that
 * location is a valid config file, it will combine with the options here
 * and cause undesirable side-effects.  Like sending bogus IP addresses
 * as the gateway or whatever.  So tell dnsmasq not to use any config file
 * at all.
 */
nm_cmd_line_add_string (cmd, "--conf-file");
nm_cmd_line_add_string (cmd, "--no-hosts");
nm_cmd_line_add_string (cmd, "--keep-in-foreground");
nm_cmd_line_add_string (cmd, "--bind-interfaces");
nm_cmd_line_add_string (cmd, "--except-interface=lo");
nm_cmd_line_add_string (cmd, "--clear-on-reload");

You can recompile NetworkManager to solve the problem. But as the comment implies, you can add some arguements in dnsmasq’s default config file and hope it works.

Update: It doesn't work!!


I chose an another solution. If the arguements above couldn’t be changed, I could change the config files of DNS caching.
In /etc/NetworkManager/dnsmasq.d/, you should have:

listen-address=127.0.0.1 # no other listen addresses
no-dhcp-interface=lo
no-dhcp-interface=......
no-dhcp-interface=......

For IPv6:

listen-address=::1

Result:

pgrep -a dnsmasq
2393 /usr/bin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/var/run/NetworkManager/dnsmasq.pid --listen-address=127.0.0.1 --conf-file=/var/run/NetworkManager/dnsmasq.conf --cache-size=400 --proxy-dnssec --conf-dir=/etc/NetworkManager/dnsmasq.d
2512 /usr/bin/dnsmasq --conf-file --no-hosts --keep-in-foreground --bind-interfaces --except-interface=lo --clear-on-reload --strict-order --listen-address=10.42.0.1 --dhcp-range=10.42.0.10,10.42.0.254,60m --dhcp-option=option:router,10.42.0.1 --dhcp-lease-max=50 --pid-file=/var/run/nm-dnsmasq-xxxx.pid

It seems there is no conflict in NetworkManager ... The wrong configure causes this case.

C Tips

The reminder operator (%) in C

I’ve found the reminder operator in C very annoying. For example, if you have a ≡ 1 (mod n), then there are three kinds of result in c:

a%n == n+1 // if a < 0 && n < 0
a%n == 1-n // if a < 0 && n > 0
a%n == 1 // if a > 0 

The color in c

ANSC escape code

bash:

txtblk='\e[0;30m' # Black - Regular
txtred='\e[0;31m' # Red
txtgrn='\e[0;32m' # Green
txtylw='\e[0;33m' # Yellow
txtblu='\e[0;34m' # Blue
txtpur='\e[0;35m' # Purple
txtcyn='\e[0;36m' # Cyan
txtwht='\e[0;37m' # White
bldblk='\e[1;30m' # Black - Bold
bldred='\e[1;31m' # Red
bldgrn='\e[1;32m' # Green
bldylw='\e[1;33m' # Yellow
bldblu='\e[1;34m' # Blue
bldpur='\e[1;35m' # Purple
bldcyn='\e[1;36m' # Cyan
bldwht='\e[1;37m' # White
unkblk='\e[4;30m' # Black - Underline
undred='\e[4;31m' # Red
undgrn='\e[4;32m' # Green
undylw='\e[4;33m' # Yellow
undblu='\e[4;34m' # Blue
undpur='\e[4;35m' # Purple
undcyn='\e[4;36m' # Cyan
undwht='\e[4;37m' # White
bakblk='\e[40m'   # Black - Background
bakred='\e[41m'   # Red
bakgrn='\e[42m'   # Green
bakylw='\e[43m'   # Yellow
bakblu='\e[44m'   # Blue
bakpur='\e[45m'   # Purple
bakcyn='\e[46m'   # Cyan
bakwht='\e[47m'   # White
txtrst='\e[0m'    # Text Reset

in C:

#include <stdio.h>

#define ANSI_COLOR_RED     "\x1b[31m"
#define ANSI_COLOR_GREEN   "\x1b[32m"
#define ANSI_COLOR_YELLOW  "\x1b[33m"
#define ANSI_COLOR_BLUE    "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN    "\x1b[36m"
#define ANSI_COLOR_RESET   "\x1b[0m"

int main (int argc, char const *argv[]) {

  printf(ANSI_COLOR_RED     "This text is RED!"     ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_GREEN   "This text is GREEN!"   ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_YELLOW  "This text is YELLOW!"  ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_BLUE    "This text is BLUE!"    ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_MAGENTA "This text is MAGENTA!" ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_CYAN    "This text is CYAN!"    ANSI_COLOR_RESET "\n");

  return 0;
}

Determine System Type Using Compiler Predefined Macros

How to list compiler predefined macros

Clang/LLVM:
clang -dM -E -x c /dev/null     
clang++ -dM -E -x c++ /dev/null
GNU GCC/G++:
gcc -dM -E -x c /dev/null   
g++ -dM -E -x c++ /dev/null 

How to detect the operating system type using compiler predefined macros

Linux

#if defined(__linux__)
    /* Linux. --------------------------------------------------- */

#endif

BSD

#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <sys/param.h>
#if defined(BSD)
    /* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD). ----------- */

#endif
#endif

Reference

http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system

Linux ramdom syscall not found

According linux man page, I wrote codes as below:

#include <linux/random.h>
......
#ifdef __linux__
    unsigned char buf[2 * LOOP_MAX * sizeof(int)];
    int *p = (int *)buf;
    result = getrandom(buf, LOOP_MAX * sizeof(int), 0);
#else
    srand((unsigned) time(0));
#endif

When compiling with gcc, I got this error message:

......c: In functionmain’:
......c:43:5: warning: implicit declaration of functiongetrandom’ [-Wimplicit-function-declaration]
     getrandom( buf, LOOP_MAX * sizeof(int), 0);
     ^
/tmp/ccng3Ckd.o: In function `main':
/......c:43: undefined reference to `getrandom'

I’m using the newest kernel and I’m sure that the syscall exists. I haven’t find the reason yet. But a workaroud:

#ifdef __linux__
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/random.h>
#else
......
#endif
......
#ifdef __linux__
    unsigned char buf[2 * LOOP_MAX * sizeof(int)];
    int *p = (int *)buf;
    result = syscall(SYS_getrandom, buf, LOOP_MAX * sizeof(int), 0);
#else
......

References:

http://man7.org/linux/man-pages/man2/getrandom.2.html

https://stackoverflow.com/questions/30800331/getrandom-syscall-in-c-not-found

Linux Tips

Under construction

Linux port usage:

Update: netstat has replaced by 'ip -s' or ss in newer system.

netstat - a command-line tool that displays network connections,
 routing tables, and a number of network interface statistics.

fuser - a command line tool to identify processes using files or sockets.

lsof - a command line tool to list open files under Linux / UNIX to report
 a list of all open files and the processes that opened them.

/proc/$pid/ file system - Under Linux /proc includes a directory for
 each running process (including kernel processes) at /proc/PID, 
containing information about that process, notably including 
the processes name that opened port.

eg:

sudo lsof -i
sudo netstat -lptu
sudo netstat -tulpn

ld Path

export LD_LIBRARY_PATH=
ld -L DIRECTORY, --library-path DIRECTORY

eg:

ld: cannot find -lc
install glibc-static or add glibc.a location to LD_LIBRARY_PATH

How to debug stripped binaries with GDB

references: https://reverseengineering.stackexchange.com/questions/1935/how-to-handle-stripped-binaries-with-gdb-no-source-no-symbols-and-gdb-only-sho

Tricks you should know

Press return/enter will run last command

Commands can be abbreviated as long as they are unambiguous.

eg:

b for break (despite bt and backtrace)
c or cont for continue (despite catch, call and so on)
n for next (despite ni and nexti)

You can call a function with “call”

You can toggle sources, registers and asm view using layout `src/regs/asm’

GDB debug processing

run the command

$ gdb commands_to_run

Look for entry point

> info file
        `.......', file type elf64-x86-64.h
        Entry point: 0x402350
        0x0000000000400200 - 0x000000000040021c is .interp) group(s) only
        0x000000000040021c - 0x000000000040023c is .note.ABI-tag
        0x000000000040023c - 0x0000000000400260 is .note.gnu.build-id
        0x0000000000400260 - 0x0000000000400294 is .gnu.hash
        0x0000000000400298 - 0x0000000000400a78 is .dynsym
        0x0000000000400a78 - 0x0000000000400d54 is .dynstr

set breakpoints and run

> b *0x402350
        Breakpoint 1 at 0x402350
> run
        Starting program: /home/lfs/sources/john-1.7.8/run/john
        
        Breakpoint 1, 0x0000000000402350 in ?? ()

assembly

> set disassembly-flavor intel/att
> layout asm
> layout regs

btw, if you prefer to save screen estate, starting with GDB 7.0 you can use:

> set disassemble-next-line on

debug

# Execute one machine instruction, but if it is a function call, proceed until the function returns. 
> nexti 
> ni
# Execute one machine instruction, then stop and return to the debugger. 
> stepi 
>si

Running ARM Applications on Native Linux

Today I’ve got a Linux application running on aarch64 architecture. But I don’t have any aarch64 (ARM64) architecture devices. So I’ve found a way to run it on my native Linux (without VM).
QEMU is a generic and open source machine emulator and virtualizer. Thanks to QEMU, we can running almost any other architecture applications on your native Linux host.

As for ARM (Arch Linux):

Preparetion: You need installing some packages first.
QEMU
Glibc(runtime)
GCC(for compiling)
GDB(for debug)
extra/qemu 2.4.1-2 [installed]    
    A generic and open source processor emulator which achieves a good emulation speed by using dynamic translation
extra/qemu-arch-extra 2.4.1-2 [installed]
    QEMU with full support for non x86 architectures
aur/qemu-user-static 2.5-2 [installed: 2.5-3] (31)
    A generic and open source processor emulator which achieves a good emulation speed by
community/arm-none-eabi-binutils 2.25.1-2 [installed]
    A set of programs to assemble and manipulate binary and object files for the ARM EABI
    (bare-metal) target
community/arm-none-eabi-gcc 5.3.0-1 [installed]
    The GNU Compiler Collection - cross compiler for ARM EABI (bare-metal) target
community/arm-none-eabi-gdb 7.10.1-1
    The GNU Debugger for the ARM EABI (bare-metal) target
community/arm-none-eabi-newlib 2.3.0.20160104-1 [installed]
    A C standard library implementation intended for use on embedded systems (ARM bare metal)

Now for aarch64 (Arch Linux):

Preparetion: You need some packages.
QEMU
Glibc(runtime)
GCC(for compiling)
GDB(for debug)
All aarch64 specific packages are in AUR:
aur/aarch64-linux-gnu-binutils 2.25.1-1 [installed] (1)
    A set of programs to assemble and manipulate binary and object files for the ARM64 target
aur/aarch64-linux-gnu-eglibc 2.19.r25988-1 [installed] (0)
    Embedded GNU C Library (aarch64-linux-gnu)
aur/aarch64-linux-gnu-eglibc-headers 2.19.r25988-1 (0)
    Embedded GNU C Library. Stage 1 - headers only. Needed for initialy build toolchain (aarch64-linux-gnu)
aur/aarch64-linux-gnu-gcc 5.3.0-1 [installed] (2)
    The GNU Compiler Collection - cross compiler for ARM64 target
aur/aarch64-linux-gnu-gcc-stage1 5.3.0-1 (0)
    The GNU Compiler Collection - cross compiler for ARM64 target
aur/aarch64-linux-gnu-gcc-stage2 5.3.0-1 (0)
    The GNU Compiler Collection - cross compiler for ARM64 target
aur/aarch64-linux-gnu-gdb 7.10.1-1 [installed] (0)
    The GNU Debugger for the ARM64 target
aur/aarch64-linux-gnu-linux-api-headers 4.4-1 [installed] (0)
    Kernel headers sanitized for use in userspace (aarch64-linux-gnu)
You don’t need to install aarch64-linux-gnu-gcc-stage1 or aarch64-linux-gnu-gcc-stage2 for they are temporary used to build gcc.

Attetion:

To find library location, just type “pacman -Ql aarch64-linux-gnu-eglibc”, and using “qemu-aarch64 -L /usr/aarch64-linux-gnu” specify library location, and “-g port” for gdb debuging.

Other resources:

  • http://www.bennee.com/~alex/blog/2014/05/09/running-linux-in-qemus-aarch64-system-emulation-mode/
  • https://rwmj.wordpress.com/2013/12/22/how-to-run-aarch64-binaries-on-an-x86-64-host-using-qemu-userspace-emulation/
  • https://gist.github.com/shiliang-hust/acf3e1294f1f04ef0eb6
  • https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-mips-elf-with-qemu-toolchain