February 2012
M T W T F S S
« Apr    
 12345
6789101112
13141516171819
20212223242526
272829  

How Applications Resolve domain name(How DNS works)?

DNS on Linux is not so difficult as I thought before. When an program, such as wget, ping, met an domain name, it will query the DNS server to retrieve the IP for this host, and then use this IP to setup the network communication. All these staff have been done in the library. So, which library these programs use?

[root@ky_vm ~]# ldd `which ping`
        libresolv.so.2 => /lib/libresolv.so.2 (0x00af2000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00c7e000)
        /lib/ld-linux.so.2 (0x00b2a000)
[root@ky_vm ~]# ldd `which wget`
        libssl.so.4 => /lib/libssl.so.4 (0x00881000)
        libcrypto.so.4 => /lib/libcrypto.so.4 (0x0070c000)
        libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x006f6000)
        libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x007f7000)
        libcom_err.so.2 => /lib/libcom_err.so.2 (0x006d0000)
        libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x0085e000)
        libresolv.so.2 => /lib/libresolv.so.2 (0x004e3000)
        libdl.so.2 => /lib/libdl.so.2 (0x00446000)
        libz.so.1 => /usr/lib/libz.so.1 (0x0059b000)
        librt.so.1 => /lib/tls/librt.so.1 (0x00abd000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00319000)
        /lib/ld-linux.so.2 (0x002fb000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00562000)

Obviously, the libresolv.so is what we are looking for.

It’s time for us to ask how the application, such as ping,  works to resolve the domain name.

I will use strace to trace the ping execution process.

[root@ky_vm ~]# strace ping www.a.com
execve("/bin/ping", ["ping", "www.a.com"], [/* 21 vars */]) = 0
uname({sys="Linux", node="ky_vm", ...}) = 0
brk(0)                                  = 0x97f2000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=58577, ...}) = 0
old_mmap(NULL, 58577, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f00000
close(3)                                = 0
open("/lib/libresolv.so.2", O_RDONLY)   = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360SN\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=79488, ...}) = 0
old_mmap(NULL, 75944, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3d0000
old_mmap(0x3df000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf000) = 0x3df000
old_mmap(0x3e1000, 6312, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3e1000
close(3)                                = 0
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\336"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1526984, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7eff000
old_mmap(NULL, 1223900, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xd05000
old_mmap(0xe2a000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x124000) = 0xe2a000
old_mmap(0xe2e000, 7388, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xe2e000
close(3)                                = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7efe000
mprotect(0xe2a000, 8192, PROT_READ)     = 0
mprotect(0xed0000, 4096, PROT_READ)     = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7efe6c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xb7f00000, 58577)               = 0
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
getuid32()                              = 0
setuid32(0)                             = 0
brk(0)                                  = 0x97f2000
brk(0x9813000)                          = 0x9813000
gettimeofday({1199477920, 545573}, NULL) = 0
getpid()                                = 5231
open("/etc/resolv.conf", O_RDONLY)      = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=158, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "; generated by /sbin/dhclient-sc"..., 4096) = 158
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
socket(PF_FILE, SOCK_STREAM, 0)         = 4
fcntl64(4, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(4, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(4)                                = 0
socket(PF_FILE, SOCK_STREAM, 0)         = 4
fcntl64(4, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(4, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(4)                                = 0
open("/etc/nsswitch.conf", O_RDONLY)    = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=1620, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1620
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
open("/etc/ld.so.cache", O_RDONLY)      = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=58577, ...}) = 0
old_mmap(NULL, 58577, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb7f00000
close(4)                                = 0
open("/lib/libnss_db.so.2", O_RDONLY)   = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220&\0"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=548068, ...}) = 0
old_mmap(NULL, 547276, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x898000
old_mmap(0x91d000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x85000) = 0x91d000
close(4)                                = 0
open("/lib/libnss_files.so.2", O_RDONLY) = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\33\0"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=47436, ...}) = 0
old_mmap(NULL, 41608, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x2cf000
old_mmap(0x2d8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x8000) = 0x2d8000
close(4)                                = 0
mprotect(0x2d8000, 4096, PROT_READ)     = 0
munmap(0xb7f00000, 58577)               = 0
open("/etc/host.conf", O_RDONLY)        = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=17, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "order hosts,bind\n", 4096)     = 17
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
open("/etc/hosts", O_RDONLY)            = 4
fcntl64(4, F_GETFD)                     = 0
fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=179, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "# Do not remove the following li"..., 4096) = 179
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
open("/etc/ld.so.cache", O_RDONLY)      = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=58577, ...}) = 0
old_mmap(NULL, 58577, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb7f00000
close(4)                                = 0
open("/lib/libnss_ldap.so.2", O_RDONLY) = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0b\1\000"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=2285888, ...}) = 0
old_mmap(NULL, 2342648, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x4d2000
old_mmap(0x6ec000, 81920, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x21a000) = 0x6ec000
old_mmap(0x700000, 57080, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x700000
close(4)                                = 0
open("/lib/libcom_err.so.2", O_RDONLY)  = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\354\10"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=7004, ...}) = 0
old_mmap(NULL, 8636, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x394000
old_mmap(0x396000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x1000) = 0x396000
close(4)                                = 0
open("/lib/libdl.so.2", O_RDONLY)       = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260kD\000"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=16764, ...}) = 0
old_mmap(NULL, 12388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0xc79000
old_mmap(0xc7b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x1000) = 0xc7b000
close(4)                                = 0
mprotect(0xc7b000, 4096, PROT_READ)     = 0
munmap(0xb7f00000, 58577)               = 0
rt_sigaction(SIGPIPE, {SIG_IGN}, {SIG_DFL}, 8) = 0
geteuid32()                             = 0
open("/etc/ldap.conf", O_RDONLY)        = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=8738, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "# @(#)$Id: ldap.conf,v 1.34 2004"..., 4096) = 4096
read(4, "_password ad\n\n# Use the OpenLDAP"..., 4096) = 4096
read(4, "ipher suite\n# See man ciphers fo"..., 4096) = 546
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
uname({sys="Linux", node="ky_vm", ...}) = 0
open("/etc/hosts", O_RDONLY)            = 4
fcntl64(4, F_GETFD)                     = 0
fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=179, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "# Do not remove the following li"..., 4096) = 179
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0
open("/etc/openldap/ldap.conf", O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=320, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f0e000
read(4, "#\n# LDAP Defaults\n#\n\n# See ldap."..., 4096) = 320
read(4, "", 4096)                       = 0
close(4)                                = 0
munmap(0xb7f0e000, 4096)                = 0
getuid32()                              = 0
geteuid32()                             = 0
getgid32()                              = 0
getegid32()                             = 0
open("/root/ldaprc", O_RDONLY)          = -1 ENOENT (No such file or directory)
open("/root/.ldaprc", O_RDONLY)         = -1 ENOENT (No such file or directory)
socket(PF_NETLINK, SOCK_RAW, 0)         = 4
bind(4, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
getsockname(4, {sa_family=AF_NETLINK, pid=5231, groups=00000000}, [12]) = 0
time(NULL)                              = 1199477920
sendto(4, "\24\0\0\0\26\0\1\3\240\224~G\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
recvmsg(4, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"<\0\0\0\24\0\2\0\240\224~Go\24\0\0\2\10\200\376\1\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 128
recvmsg(4, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"@\0\0\0\24\0\2\0\240\224~Go\24\0\0\n\200\200\376\1\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 128
recvmsg(4, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\24\0\0\0\3\0\2\0\240\224~Go\24\0\0\0\0\0\0\1\0\0\0\24"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20
close(4)                                = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
fcntl64(4, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(4, {sa_family=AF_INET, sin_port=htons(389), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
select(1024, NULL, [4], NULL, {120, 0}) = 1 (out [4], left {120, 0})
getpeername(4, 0xbffd4a40, [128])       = -1 ENOTCONN (Transport endpoint is not connected)
read(4, 0xbffd4a2b, 1)                  = -1 ECONNREFUSED (Connection refused)
shutdown(4, 2 /* send and receive */)   = -1 ENOTCONN (Transport endpoint is not connected)
close(4)                                = 0
rt_sigaction(SIGPIPE, {SIG_DFL}, NULL, 8) = 0
open("/etc/ld.so.cache", O_RDONLY)      = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=58577, ...}) = 0
old_mmap(NULL, 58577, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb7f00000
close(4)                                = 0
open("/lib/libnss_nis.so.2", O_RDONLY)  = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200\33"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=43056, ...}) = 0
old_mmap(NULL, 37420, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x227000
old_mmap(0x22f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x7000) = 0x22f000
close(4)                                = 0
open("/lib/libnsl.so.1", O_RDONLY)      = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\27"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=97164, ...}) = 0
old_mmap(NULL, 88072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x99b000
old_mmap(0x9ad000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x11000) = 0x9ad000
old_mmap(0x9af000, 6152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x9af000
close(4)                                = 0
mprotect(0x9ad000, 4096, PROT_READ)     = 0
mprotect(0x22f000, 4096, PROT_READ)     = 0
munmap(0xb7f00000, 58577)               = 0
uname({sys="Linux", node="ky_vm", ...}) = 0
open("/etc/ld.so.cache", O_RDONLY)      = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=58577, ...}) = 0
old_mmap(NULL, 58577, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb7f00000
close(4)                                = 0
open("/lib/libnss_dns.so.2", O_RDONLY)  = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\r\0"..., 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=22532, ...}) = 0
old_mmap(NULL, 20612, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0x122000
old_mmap(0x126000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0x3000) = 0x126000
close(4)                                = 0
mprotect(0x126000, 4096, PROT_READ)     = 0
munmap(0xb7f00000, 58577)               = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.182.122.37")}, 28) = 0
fcntl64(4, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
gettimeofday({1199477920, 689011}, NULL) = 0
poll([{fd=4, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
send(4, "\323\352\1\0\0\1\0\0\0\0\0\0\3www\1a\3com\0\0\1\0\1", 27, MSG_NOSIGNAL) = 27
poll([{fd=4, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
ioctl(4, FIONREAD, [100])               = 0
recvfrom(4, "\323\352\201\203\0\1\0\0\0\1\0\0\3www\1a\3com\0\0\1\0\1"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.182.122.37")}, [16]) = 100
close(4)                                = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.182.122.37")}, 28) = 0
fcntl64(4, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
gettimeofday({1199477921, 122373}, NULL) = 0
poll([{fd=4, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1
send(4, "\24\325\1\0\0\1\0\0\0\0\0\0\3www\1a\3com\2cn\6oracle"..., 41, MSG_NOSIGNAL) = 41
poll([{fd=4, events=POLLIN, revents=POLLIN}], 1, 5000) = 1
ioctl(4, FIONREAD, [112])               = 0
recvfrom(4, "\24\325\205\203\0\1\0\0\0\1\0\0\3www\1a\3com\2cn\6orac"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.182.122.37")}, [16]) = 112
close(4)                                = 0
write(2, "ping: unknown host www.a.com\n", 29ping: unknown host www.a.com
) = 29
exit_group(2)                           = ?
Process 5231 detached
[root@ky_vm ~]#

We can focus on the files involved in this ping process.

open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libresolv.so.2", O_RDONLY)   = 3
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
open("/etc/resolv.conf", O_RDONLY)      = 4
open("/etc/nsswitch.conf", O_RDONLY)    = 4
open("/etc/ld.so.cache", O_RDONLY)      = 4
open("/lib/libnss_db.so.2", O_RDONLY)   = 4
open("/lib/libnss_files.so.2", O_RDONLY) = 4
open("/etc/host.conf", O_RDONLY)        = 4
open("/etc/hosts", O_RDONLY)            = 4
open("/etc/ld.so.cache", O_RDONLY)      = 4
open("/lib/libnss_ldap.so.2", O_RDONLY) = 4
open("/lib/libcom_err.so.2", O_RDONLY)  = 4
open("/lib/libdl.so.2", O_RDONLY)       = 4
open("/etc/ldap.conf", O_RDONLY)        = 4
open("/etc/hosts", O_RDONLY)            = 4
open("/etc/openldap/ldap.conf", O_RDONLY) = 4
open("/root/ldaprc", O_RDONLY)          = -1 ENOENT (No such file or directory)
open("/root/.ldaprc", O_RDONLY)         = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 4
open("/lib/libnss_nis.so.2", O_RDONLY)  = 4
open("/lib/libnsl.so.1", O_RDONLY)      = 4
open("/etc/ld.so.cache", O_RDONLY)      = 4
open("/lib/libnss_dns.so.2", O_RDONLY)  = 4

Mainly, the following configuration files, /etc/resolv.conf, /etc/nsswitch.conf, /etc/host.conf, /etc/hosts, /etc/ldap.conf, /etc/openldap/ldap.conf are read.

/etc/nsswitch.conf is used to determine the  lookup order of name resolution for various functions. The following databases are available in the Name Service Switch:

aliases

Mail aliases, used by sendmail(8).  Presently ignored.

ethers

Ethernet numbers.

group

Groups of users, used by getgrent(3) functions.

hosts

Host names and numbers, used by gethostbyname(3) and similar functions.

netgroup

Network  wide  list  of  hosts and users, used for access rules.  C libraries before glibc 2.1 only support netgroups over NIS.

network

Network names and numbers, used by getnetent(3) functions.

passwd

User passwords, used by getpwent(3) functions.

protocols

Network protocols, used by getprotoent(3) functions.

publickey

Public and secret keys for Secure_RPC used by NFS and NIS+.

rpc

Remote procedure call names and numbers, used by getrpcbyname(3) and similar functions.

services

Network services, used by getservent(3) functions.

shadow

Shadow user passwords, used by getspnam(3).

For each database, we can specify how the lookup process work. Here hosts are our focus point. In my system, it’s

hosts:     db files ldap nis dns

It means that firstly lookup the db, then files, ldap, nis, and lastly dns.

/etc/host.conf:  this file have the same function with nsswitch.conf, but is used in older libc 5 library. and nsswitch is used in glibc 6 library.

/etc/resolv.conf contains the DNS server address which is used when dns lookup way is lastly adopted.

/etc/hosts: contains the local name resolution such as localhost, hostname.

/etc/ldap.conf, /etc/openldap/ldap.conf: contains the ldap configuration.

So, in order for the DNS to function correctly, at least /etc/nsswitch.conf, /etc/resolve.conf and /etc/hosts  should be configured.

Below shows the process of another two applications, wget and nslookup.

wget output:
open("/etc/nsswitch.conf", O_RDONLY)    = 3
open("/etc/resolv.conf", O_RDONLY)      = 3
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libnss_db.so.2", O_RDONLY)   = 3
open("/lib/libnss_files.so.2", O_RDONLY) = 3
open("/etc/hosts", O_RDONLY)            = 3
open("/etc/hosts", O_RDONLY)            = 3
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libnss_ldap.so.2", O_RDONLY) = 3
open("/etc/ldap.conf", O_RDONLY)        = 3
open("/etc/host.conf", O_RDONLY)        = 3
open("/etc/hosts", O_RDONLY)            = 3
open("/etc/openldap/ldap.conf", O_RDONLY) = 3
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libnss_nis.so.2", O_RDONLY)  = 3
open("/lib/libnsl.so.1", O_RDONLY)      = 3
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/lib/libnss_dns.so.2", O_RDONLY)  = 3

nslookup output:
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/usr/lib/libdns.so.16", O_RDONLY) = 3
open("/usr/lib/libisc.so.7", O_RDONLY)  = 3
open("/lib/libcrypto.so.4", O_RDONLY)   = 3
open("/lib/libnsl.so.1", O_RDONLY)      = 3
open("/lib/tls/libpthread.so.0", O_RDONLY) = 3
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
open("/usr/lib/libgssapi_krb5.so.2", O_RDONLY) = 3
open("/usr/lib/libkrb5.so.3", O_RDONLY) = 3
open("/lib/libcom_err.so.2", O_RDONLY)  = 3
open("/usr/lib/libk5crypto.so.3", O_RDONLY) = 3
open("/lib/libresolv.so.2", O_RDONLY)   = 3
open("/lib/libdl.so.2", O_RDONLY)       = 3
open("/usr/lib/libz.so.1", O_RDONLY)    = 3
open("/etc/resolv.conf", O_RDONLY)      = 5

Therefore, the nslookup command doesn’t depend on the nsswitch.conf file, it always use resolve.conf to execute the lookup process. This is why under some circumstance, ping command return "unkown host", but nslookup or host command work correctly! What you need is, for example, replace the line below,

hosts:     db files ldap nis dns

with

hosts:      files

Shell Scripts: using wc and grep and awk

1. count the code lines using wc.

   1: wc -l `find . -name *.c` 

2. count the code lines, using an elegant way "xargs" to transfer the arguments of wc

   1: find . -name *.c |xargs wc -l 

3. count the code lines, self calculation the result of wc using awk

   1: find . -name *.c |xargs wc -l|awk '
   2: BEGIN {sum=0;fnum=0;}
   3: {sum=sum+$1; printf "%-10s %s\n",$1,$2; fnum=fnum+1; }
   4: END {printf "Total files: %s,\tTotal lines: %s.\n",fnum,sum} 
   5: '

4. List all the text files residing in current directory, recursively,

[code='c']

grep -rIc “.*” . | awk -F : ‘{if($2!=0)print($1)}’

[/code]

Here, -I let grep only search text files, -c count the line of files. When the count is larger than 0, we print it out.

The Essential of Shell scripts

In Linux world, shell script is a powerful language, maybe it’s not easy, but it’s practical for use.
I have read a lot of scripts in the past, but when asked to write a snippet of script, I usually need to query other’s code for reference.
But today suddenly I find shell script is quite practical and Linux-friendly. Below are some clarifies and examples.
The familiar form for flow control is “if”, how to use it? It’s not as simple as in java or in c/c++.

# First form
if condition
then
  commands
fi

Example 1:
if gcc demo.c –o demo
then
 echo "sucess"
fi

Firstly, the condition is also a command, the return value indicate its success or failure, linux treat exit value 0 as success/true, other values as failure/false.
So here it contradicts with normal treatment with 0/1 as true/false.

Second, as the condition is a command, a semicolon can follow the condition and followed by another command or statement. or to say, there is another form.
if gcc demo.c –o demo; then echo "sucess"; fi

Some more forms about if list below:

# Second form
if condition ; then
commands
else
commands
fi

# Third form
if condition ; then
commands
elif condition
commands
fi

Please compare the three formats below:

Example 2:
if [ -f .bash_profile ]; then
echo “You have a .bash_profile. Things are fine.”
else
echo “Yikes! You have no .bash_profile!”
fi
# Alternate form
if [ -f .bash_profile ]
then
echo “You have a .bash_profile. Things are fine.”
else
echo “Yikes! You have no .bash_profile!”
fi
# Another alternate form
if [ -f .bash_profile ]
then echo “You have a .bash_profile. Things are fine.”
else echo “Yikes! You have no .bash_profile!”
fi