2008年2月25日 星期一

Linux Command - ntp

setup the local time manually
# date -s 20080226
# date -s 09:22:10

display the local time
# date
Tue Feb 26 10:09:19 CST 2008
Another method to show the detail date (according to the system time hardware colock)
# hwclock --show
Fri 14 Mar 2008 11:23:32 AM CST -0.508117 seconds

use ntpupdate to sync your localtime correctly
# ntpdate time.stdtime.gov.tw
26 Feb 09:52:01 ntpdate[27524]: step time server 220.130.158.52 offset -210.262890 sec

Ther are also other ntp server in Taiwan as the following
* tock.stdtime.gov.tw
* time.stdtime.gov.tw
* clock.stdtime.gov.tw
* freq_f.stdtime.gov.tw
* tick.stdtime.gov.tw

other ntp servers
clock.redhat.com
clock2.redhat.com
ns1.tuxfamily.org

National Institute of Standards and Technology
time.nist.gov
Set Your Computer Clock Via the Internet NIST Internet Time Service (ITS)
http://tf.nist.gov/timefreq/service/its.htm

use zdump to print the time information

[root@localhost ~]# zdump Singapore
Singapore Tue Feb 26 10:52:33 2008 SGT ==> correct
[root@localhost ~]# zdump Japan
Japan Tue Feb 26 11:52:39 2008 JST ==> correct
[root@localhost ~]# zdump Taipei
Taipei Tue Feb 26 02:55:15 2008 Taipei ==> not correct, you need to plus the GMT difference
[root@localhost ~]# zdump NewYork
NewYork Tue Feb 26 02:55:22 2008 NewYork ==> not correct, you need to plus the GMT difference

I am looking for the zdump valid-argument list....
still looking forward...


Excellent Reference
http://www.vanemery.com/Linux/RH-Linux-Time.html

How to change the timezone in the Linux
1. Logged in as root, check which timezone your machine is currently using by executing `date`. You'll see something like Mon 17 Jan 2005 12:15:08 PM PST, PST in this case is the current timezone.
2. Change to the directory /usr/share/zoneinfo here you will find a list of time zone regions. Choose the most appropriate region, if you live in Canada or the US this directory is the "America" directory.
3. If you wish, backup the previous timezone configuration by copying it to a different location. Such as

mv /etc/localtime /etc/localtime-old

4. Create a symbolic link from the appropiate timezone to /etc/localtime. Example:

ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime

5. If you have the utility rdate, update the current system time by executing

/usr/bin/rdate -s time.nist.gov

6. Set the ZONE entry in the file /etc/sysconfig/clock file (e.g. "America/Los_Angeles")
7. Set the hardware clock by executing:

/sbin/hwclock --systohc




Time, Date, and Time Zones for Red Hat Linux
A Practical Guide

Van Emery - March, 2003

Introduction:

I have had nothing but trouble with Red Hat's GUI tools for setting date, time, time zone, and ntpd configuration files. In some cases, this has been as extreme as the dateconfig tool refusing to execute, and in other cases the tool ran, but did not change the underlying configuration files. I decided to dig down into the details and find out how date, time, time zones, and ntpd work on a Linux system. Armed with this knowledge, I would be able to configure my systems properly once and for all! As it turns out, this was an informative little detour...


Environment:
Red Hat 8.0 on a Pentium III 667 MHz & a Pentium II 233 MHz
Red Hat 7.3 on a Dell Optiplex GX-1 Pentium II running Red Hat 7.3


Objectives:
1. Set my Linux systems to the desired time zone
2. Set my Linux systems to the desired time and date
3. Get the NTP server running correctly
4. Make sure the hardware clock maintains the proper time
5. Find out as much as possible about the time and date configuration commands and files


Basic Command-line Tools:

The date command can be used as follows to display the time and date:


$ date
Fri Mar 28 16:01:50 CST 2003


To see UTC/GMT, you can do this:

$ date --utc
Fri Mar 28 08:04:32 UTC 2003


The date command also can be used to set the time and date. To set the time manually, do this:


# date -s "16:15:00"
Fri Mar 28 16:15:00 CST 2003

If you also need to adjust the date, and not just the time, you can do it like this:

# date -s "16:55:30 July 7, 1986"
Mon Jul 7 16:55:30 PDT 1986

There is also another way to set the date and time, which is not very pretty:

# date 033121422003.55
Mon Mar 31 21:42:55 PST 2003

The above command does not use the -s option, and the fields are arranged like this: MMDDhhmmCCYY.ss
where MM = month, DD = day, hh = hour, mm = minute, CCYY = 4 digit year, and ss = seconds.

Please note that setting the clock with the date command must be done as root. This is a "savage" way to adjust the time. It adjusts the Linux kernel system time.

There is also a hardware clock (CMOS clock). You can look at the current hardware clock time with:


hwclock --show


I always keep my hardware clocks set to UTC/GMT. This maintains my clocks uniformly without any worries about "Daylight Savings Time". This is important, because when you set the hardware clock from the system clock (kept by the Linux kernel), you need to know if this is the case. To set the hardware clock from the system clock, leaving the hardware clock in UTC, enter the following:


# hwclock --systohc --utc
# hwclock --show
Fri 28 Mar 2003 04:23:52 PM CST -0.864036 seconds


Another interesting item is that the Linux system clock stores time in seconds since midnight on January 1st, 1970 (UTC). This is called UNIX time. Unfortunately, because this is a 32-bit value, there is a year-2038 problem. Hopefully, everyone will have moved to 64-bit architectures by then. In order to see the UNIX time, you can use the following command:

date +%s


There are many useful formatting options for the date command. See the date manpage for details.


Of course, there is another useful tool available related to date and time: cal


$ cal -3

February 2003 March 2003 April 2003
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 1 1 2 3 4 5
2 3 4 5 6 7 8 2 3 4 5 6 7 8 6 7 8 9 10 11 12
9 10 11 12 13 14 15 9 10 11 12 13 14 15 13 14 15 16 17 18 19
16 17 18 19 20 21 22 16 17 18 19 20 21 22 20 21 22 23 24 25 26
23 24 25 26 27 28 23 24 25 26 27 28 29 27 28 29 30
30 31


You can also specify "cal -y" for the entire year, "cal" by itself for the current month, or "cal 12 2005" to see the calendar for December, 2005.



Time Zone Configuration:


Background - The Earth is divided into time zones that are 15 degrees of longitude each, for this corresponds to the amount of angular distance the Sun appears to travel in 1 hour. 0 degrees longitude runs through the Royal Observatory in Greenwich, England. This is the origin of Greenwich Mean Time, or GMT. For all practical purposes, GMT and UTC are the same. To complicate matters, some countries observe Daylight Savings Time (DST), while others do not. Even within some countries, some states or districts do not observe DST while the rest of the country does! DST can also begin and end on different days in different countries! What a mess...

There are several files and directories that are used for time zones, and several tools:

/etc/sysconfig/clock - this is a short text file that defines the timezone, whether or not the hardware clock is using UTC, and an ARC option that is only relevant to DEC systems.

/etc/localtime - this is a symbolic link to the appropriate time zone file in /usr/share/zoneinfo

/usr/share/zoneinfo - this directory contains the time zone files that were compiled by zic. These are binary files and cannot be viewed with a text viewer. The files contain information such as rules about DST. They allow the kernel to convert UTC UNIX time into appropriate local dates and times.

/etc/rc.d/rc.sysinit - This script runs once, at boot time. A section of this script sets the system time from the hardware clock and applies the local time zone information.

/etc/init.d/halt - This script runs during system shutdown. A section of this script synchronizes the hardware clock from the system clock.

/etc/adjtime - This file is used by the adjtimex function, which can smoothly adjust system time while the system runs. settimeofday is a related function.


redhat-config-date or dateconfig - These commands start the Red Hat date/time/time zone configuration GUI. Both commands failed to change the timezone in two different stock Red Hat 8.0 systems. They also failed to create a working ntp.conf file for the NTP server. The timezone problem went away after upgrading from the installed RPM, redhat-config-date-1.5.2-10, to a newer RPM from a Red Hat beta release, redhat-config-date-1.5.9-6.

zic - (The time zone compiler) Zic creates the time conversion information files.

zdump - This utility prints the current time and date in the specified time zone. Example:


# zdump Japan
Japan Sat Mar 29 00:47:57 2003 JST
# zdump Iceland
Iceland Fri Mar 28 15:48:02 2003 GMT

In order to manually change the timezone, you can edit the /etc/sysconfig/clock file and then make a new soft link to /etc/localtime. Here is an example of changing the timezone manually to "America/Denver":

1. Select the appropriate time zone from the /usr/share/zoneinfo directory. Time zone names are relative to that directory. In this case, we will select "America/Denver"

2. Edit the /etc/sysconfig/clock text file so that it looks like this:

ZONE="America/Denver"
UTC=true
ARC=false

Of course, this assumes that your hardware clock is running UTC time...

3. Delete the following file: /etc/localtime

4. Create a new soft link for /etc/localtime. Here is an example of step 3 and step 4:

# cd /etc
# ls -al localtime
lrwxrwxrwx 1 root root 39 Mar 28 07:00 localtime -> /usr/share/zoneinfo/America/Los_Angeles

# rm /etc/localtime

# ln -s /usr/share/zoneinfo/America/Denver /etc/localtime
# ls -al localtime
lrwxrwxrwx 1 root root 34 Mar 28 08:59 localtime -> /usr/share/zoneinfo/America/Denver

# date
Fri Mar 28 09:00:04 MST 2003


NTP Configuration and Usage:

Background - Network Time Protocol (NTP) allows computers, servers, and network devices to synchronize their internal clock systems to an external reference source. In some cases, the reference source can be an atomic clock or GPS receiver. This is useful for a number of reasons. If you would like to automatically keep the time on your Linux system synchronized to standard world times, you have two built-in tools to do this:

ntpdate and ntpd (NTP Daemon)


ntpdate:
ntpdate was written by David L. Mills at the University of Delaware. For details on Dr. Mills, enter this:

$ finger David.L.Mills@udel.edu

ntpdate allows you to view or set system time from one or more NTP servers. The first thing you need to do is find a time server you can query. Here is a list of public time servers, or you can use one of the following:

clock.redhat.com
clock2.redhat.com
ns1.tuxfamily.org
time.nist.gov

For example, if you only want to query an NTP server and make sure that you can reach it, use the following command:

# ntpdate -q clock2.redhat.com
server 66.187.224.4, stratum 1, offset -0.067532, delay 0.38452
28 Mar 18:14:20 ntpdate[10724]: adjust time server 66.187.224.4 offset -0.067532 sec


Note that some firewall systems do not allow NTP traffic. NTP uses UDP port 123. If you would like to query more than one server and set your system clock with the result, use the following:

# ntpdate clock2.redhat.com clock.redhat.com
28 Mar 18:20:59 ntpdate[10754]: adjust time server 66.187.233.4 offset -0.043222 sec


You can add the -v flag for verbose output.

This command is very similar to the rdate command. The ntpdate command can be used in startup scripts or cron jobs to automatically set the system time without running a dedicated server process. You will definitely want to try to retrieve the time from an NTP server with ntpdate before setting up your own NTP server. This will ensure that (a) you have connectivity (b) your firewall does not block NTP. Another thing to note about the ntpdate command is that it will not work in update mode if you are running a local NTP server process. It will work in query mode.


NTP Server:
The NTP server (ntpd) can be setup to run continuously. This will keep the system clock synchronized. You will also be able to server NTP clients on your LAN, if you wish. I had problems with the Red Hat configuration GUI not setting the NTP server up correctly.

The configuration file is /etc/ntp.conf, and there is also an /etc/ntp directory which contains keys and the drift file. I will show you a working configuration file, with comments:

# Prohibit general access to this service.
restrict default ignore

# Permit all access over the loopback interface. This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1


# -- CLIENT NETWORK -------
# Permit systems on this network to synchronize with this
# time service. Do not permit those systems to modify the
# configuration of this service. Also, do not use those
# systems as peers for synchronization.

# This is my internal LAN network address
restrict 192.168.212.0 mask 255.255.255.0 notrust nomodify notrap


# --- OUR TIMESERVERS -----
# or remove the default restrict line
# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.

# The statements below limit what the servers can do to your server
# I am using IP instead of DNS name because the "restrict" construct
# requires IP addresses

restrict 66.187.224.4 mask 255.255.255.255 nomodify notrap noquery
restrict 80.67.177.2 mask 255.255.255.255 nomodify notrap noquery

# The server listed below is clock2.redhat.com
server 66.187.224.4

# The server listed below is ns1.tuxfamily.org
server 80.67.177.2


# --- NTP MULTICASTCLIENT ---
#multicastclient # listen on default 224.0.1.1
# restrict 224.0.1.1 mask 255.255.255.255 notrust nomodify notrap
# restrict 192.168.1.0 mask 255.255.255.0 notrust nomodify notrap
# I don't want to use multicast for my NTP server



# --- GENERAL CONFIGURATION ---
#
# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available. The
# default stratum is usually 3, but in this case we elect to use stratum
# 0. Since the server line does not have the prefer keyword, this driver
# is never used for synchronization, unless no other other
# synchronization source is available. In case the local host is
# controlled by some external source, such as an external oscillator or
# another protocol, the prefer keyword would cause the local host to
# disregard all other synchronization sources, unless the kernel
# modifications are in use and declare an unsynchronized condition.
#
# If you un-comment the two statements below, you could run an NTP server
# off of your local (and inaccurate) system clock.
#restrict 127.127.1.0
#server 127.127.1.0
fudge 127.127.1.0 stratum 10

#
# Drift file. Put this in a directory which the daemon can write to.
# No symbolic links allowed, either, since the daemon updates the file
# by creating a temporary in the same directory and then rename()'ing
# it to the file.
#
driftfile /etc/ntp/drift
broadcastdelay 0.008

#
# Authentication delay. If you use, or plan to use someday, the
# authentication facility you should make the programs in the auth_stuff
# directory and figure out what this number should be on your machine.
#
# I am not using any authentication for this simple setup.
authenticate no

#
# Keys file. If you want to diddle your server at run time, make a
# keys file (mode 600 for sure) and define the key number to be
# used for making requests.
#
# PLEASE DO NOT USE THE DEFAULT VALUES HERE. Pick your own, or remote
# systems might be able to reset your clock at will. Note also that
# ntpd is started with a -A flag, disabling authentication, that
# will have to be removed as well.
#
keys /etc/ntp/keys


After you install this new version of the config file, you can start the service with /etc/init.d/ntpd start

To monitor the service, you can run the following command: ntpdc -p or ntpdc -p -n
If you are really impatient, you can use this command to watch the system until it synchronizes: watch nptdc -p -n
The ntpdc command can be run interactively as well. There are a number of informative ntpdc commands, such as iostats, sysstats, and peers.

When enough time has gone by, one of the servers will have an * placed in front of it to tell you that your system is synchronized to it. The lower the stratum number, the more accurate the server.




To see that your NTP server is listening on UDP port 123, use the following command: netstat -tuna

Please note that the NTP server makes NTP queries from a UDP source port of 123. Some firewalls will not allow this, even if ntpdate worked (ntpdate uses a source port > 1023.)

You can also use the ntpq utility, and the ntptrace utility for additional diagnostic support. For complete documentation on setting up and using NTP servers, see www.ntp.org.


Conclusion:
Changing the date, time, and time zone on a Red Hat Linux system can be done easily once all of the files and commands are identified. NTP clock synchronization is also fairly straightforward. Hopefully, future time and date configuration tools will work well enough that the average user/administrator does not have to resort to manual work-arounds.

2008年2月4日 星期一

UltraEdit 如何不要wrap line to single line

設定
Edit->Toggle Word-Wrap
就可以改變是否要自動換行 (顯示模式, 並沒有在中間插入CRLF字元)

Linux Service - cvs setup server

CVS Server 利用xinetd dispatch

1. 設定xinetd 的相關步驟, 如果是使用ssh(ext mode)access CVS Server, 應該可以不用, 似乎是使用pserver才需要

首先在/etc/xinetd.d/ 增加cvspserver 檔案
內容如下
service cvspserver
{
disable = no ==> enable the service
port = 2401 ==> cvs listen port
socket_type = stream
protocol = tcp
wait = no
user = root
passenv = PATH
server = /usr/bin/cvs
env = HOME=/var/cvs
server_args = -f --allow-root=/home/cvs/CVSROOT pserver ==> /home/cvs/CVSROOT 為CVS repository directory
bind = 127.0.0.1 ==> cvs listen address
}

注意必須包含有 /etc/xinetd.conf, 如下

#
## Simple configuration file for xinetd
##
## Some defaults, and include /etc/xinetd.d/

defaults
{
instances = 60
log_type = SYSLOG authpriv
log_on_success = HOST PID
log_on_failure = HOST
cps = 25 30
}
includedir /etc/xinetd.d

2. 重新啟動xinetd (由於我在安裝時系統沒有xinetd, 所以我去重新下載了xinetd, 編譯過後, copy contrib/xinetd /etc/rc.d/init.d/ 下成為service script)
/etc/rc.d/init.d/xinetd restart
正在停止 xinetd: [ 確定 ]
正在啟動 xinetd: [ 確定 ]


/home/cvs 的結構如下

ls -la /home/cvs/
drwxrwxrwx 3 root wheel 4096 2008-02-05 13:15 CVSROOT
drwxrwxr-x 6 username username 4096 2008-02-05 13:15 test
drwxrwxr-x 3 username username 4096 2008-02-05 20:42 test2

CVSROOT 目錄必須要讓所有人都可以有寫的權限, 因為cvs server 必須要記錄user 的cvs 行為在CVSROOT 目錄內的檔案中

如何控管CVS Server 的個別權限 (READERS, WRITERS,PASSWD...)
設定Anonymous 的權限
有空再來測試
We can manage the CVS permission by using the Linux file system permission mechanism. For example, you can group some user into a specified group. And only this group can access a cvs project which group id is the same with that user group. So we can simply use the user/group/other file permission to manage the CVS access control.

e.g.
Set the user1, user2 belong in the "cvs"(id: 501) group
# cat /etc/passwd
[omit]
user1:x:500:501:User1:/home/user1:/bin/bash
cvs:x:501:501::/home/cvs:/bin/bash
user2:x:502:501::/home/user2:/bin/bash

// Make user1 and user2 in the cvs group
# cat /etc/group
[omit]
cvs:x:501:user1,user2




3. 如何import 檔案到剛建立好的CVS Server
我的經驗是從其他CVS import 檔案進來, 首先先把原有的目錄中的 CVS/ 子目錄先刪掉(這些檔案是CVS Server 在maintain cvs 的系統檔案, 我們不用把它們upload到新的project當中)

# cd project
project/# find ./* -name CVS -exec "rm -rf {}" \;

cvs import -m "initial" test3 vendor-name main ==> 其中test3是CVS project name, vendor-name 是 branch tag, main (release tag) 是main trunk tag

cvs import -kb -m "initial files" projectName vendorName main ==> import binary files (add -kb will inform the cvs server that all the uploaded files are binary files)

import 過程的log如下
I test3/filename.o ==> ignored files (*.o, *.a..)
N test3/filename.c ==> newAdded files
[omit]


之後再來cvs client 檢查就會發現如下
# cvs st -v Makefile
username@IP-address's password:
===================================================================
File: Makefile Status: Up-to-date

Working revision: 1.1.1.1
Repository revision: 1.1.1.1 /home/cvs/test3/Makefile,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)

Existing Tags:
main (revision: 1.1.1.1)
vendor-name (branch: 1.1.1)


之後就可以利用client CVS 來執行checkouot 該project 來work了

Note:
We can configure the /CVSROOT/cvswrappers as the following setting to separate different file expansion as binary or text file (default configuration)

*.vsd -k 'b' -m 'COPY'
*.CLASS -k 'b' -m 'COPY'
*.DOC -k 'b' -m 'COPY'

In the real CVS data file, like "file.doc,v", will contain the expand tag to record the kflag type. like following examples
head 1.1;
branch 1.1.1;
access ;
symbols main:1.1.1.1 vendor-name:1.1.1;
locks ; strict;
comment @# @;
expand @b@; ==> "b" indicate "binary"



The method of changing the kflag
$ echo '$Id$' > kotest
$ cvs add -kb -m"A test file" kotest
$ cvs ci -m"First checkin; contains a keyword" kotest

If a file accidentally gets added without '-kb', one can use the cvs admin command to recover. For example:

$ echo '$Id$' > kotest
$ cvs add -m"A test file" kotest
$ cvs ci -m"First checkin; contains a keyword" kotest
$ cvs admin -kb kotest
$ cvs update -A kotest
# For non-unix systems:
# Copy in a good copy of the file from outside CVS
$ cvs commit -m "make it binary" kotest

2007年12月20日 星期四

SIP Transaction and Dialog parameters

Transaction:
Via - Must contain a branch parameter to identify the transaction created by that request. The branch ID must always begin with the characters “z9hG4bK” as a magic cookie.
Branch parameter “branch=z9hG4bK776asdhds” to identify the transaction


Dialog:
The combination of the “To tag”, “From tag”, and “Call-ID” completely defines a peer-to-peer SIP relationship between Alice and Bob and is referred to as a dialog.

2007年12月19日 星期三

bash, tcsh shell variable experience

Default file permission is 666 (user, group, other can read/write file)
Default directory permission is 777 (user, group, other can none/add, delete/list the files of the directory)

#tcsh .tcshrc file

alias h history 25
alias j jobs -l
alias la ls -a
alias lf ls -FA
alias ll ls -lA
alias su su -m

setenv EDITOR vi
setenv VISUAL ${EDITOR}
setenv EXINIT 'set autoindent'
setenv PAGER more

set path = (~/bin /bin /sbin /usr/local/{,s}bin /usr/{bin,sbin,X11R6/bin,pkg/{,s}bin,games} )

if ($?prompt) then
# An interactive shell -- set some stuff up
set filec
set history = 1000
# set ignoreeof
set mail = (/var/mail/$USER)
set mch = `hostname -s`
set prompt = "${mch:q}: {\!} "
umask 22
endif
alias vi env TERM=xterm vim
setenv CVSROOT :ext:username@IP-Address:/home/cvsroot
setenv CVS_RSH /usr/local/bin/ssh
set prompt="[%{^[[1;32m%}%n%{^[[31m%}@%{^[[33m%}%m%{^[[36m%}(%{^[[34m%}%p%{^[[36m%}):%{^[[35m%}~%C2%{^[[0m%}]"
setenv LD_LIBRARY_PATH /usr/pkg/lib:/usr/lib/compat/aout:/usr/X11R6/lib:/usr/local/lib:/usr/X11R6/lib/aout:/usr/lib/aout:/usr/lib
#setenv ENABLE_STARTUP_LOCALE zh_TW.Big5
#setenv LC_CTYPE en_US.ISO_8859-1
#setenv LANG zh_TW.Big5
# 若要支援中文顯示, 請設定成下面的 LC settings
setenv LANG zh_TW.UTF-8
setenv LC_CTYPE zh_TW.UTF-8
setenv LC_ALL zh_TW.UTF-8
setenv LC_MESSAGES zh_TW.UTF-8
unset autologout

tcshell 的cvs environment variable設定方法
setenv CVSROOT ":ext:username@1.2.3.4:/home/cvsroot"
setenv CVS_RSH "/usr/bin/ssh"

bashrc 的cvs environment variable設定方法
export CVSROOT=:ext:username@1.2.3.4:/home/cvsroot
export CVS_RSH=/usr/bin/ssh

The following are reference from http://www.horde.org/source/using.php
sh, ksh, bash, zsh:
export CVSROOT=:pserver:cvsread@anoncvs.horde.org:/repository

csh, tcsh:
setenv CVSROOT :pserver:cvsread@anoncvs.horde.org:/repository


# 另外要設定環境變數, 一般可以使用 export (設定單個) or source (讀入一個config file)

在/root/.bashrc or /root/.bash_profile檔案中,
加入下列的參數
export PS1='[fish]# '
則shell 的prompt ]就會變成
[fish]#

sh, bash:
set environment variable:
# export Variable_Name=Variable_Value
show all the environment variable values
# set
reload config file
# source /to/path/.bashrc

csh, tcsh:
set environment variable:
# setenv Variable_Name Variable_Value
show all the environment variable values
# setenv

2007年10月9日 星期二

Fast path vs Slow path in linux kernel routing

Fast path vs Slow path in Linux kernel routing

執行順序
先做Fast Path Routing, 如果找不到, 才會做 Slow Path Routing
ip_input.c: ip_rcv_finish: PREROUTING CHAIN traversal 之後的function, 做ip packet receive 後的最後處理
ip_input.c: ip_rcv_finish: function 定義於此
ip_input.c: ip_route_input: 做fast path routing, 作法為利用rcu_dereference 循序去撈出rt_hash_table[hash] 裡面的 chain 為rth (struct rtable), 然後和 source, destination, iif, mark, tos 等作比較, 若符合, 則update lastuse 為jiffies, 另外設定 skb->dst = (struct dst_entry*)rth, 讓之後可以使用
route.c: ip_route_input: function 定義於此
route.c: ip_route_input_slow: 如果fast path routing 找不到之前的routing cache, 我們就做slow path routeing
route.c: ip_route_input_slow: function 定義於此
route.c fib_lookup: 執行fib search
net/ipv4/fib_rules.c: fib_lookup: function 定義於此
net/ipv4/fib_rules.c: fib_rules_lookup: 帶了定義在fib_rules.c 裡面特有的參數, 利用fib4_rules_ops 這個變數
net/core/fib_rules.c: fib_rules_lookup: function 定義於此
net/core/fib_rules.c: fib_rules_lookup: 利用 list_for_each_entry_rcu 去逐步檢查每個
ops->rules_list 的rule 和 fl (struct flowi) 是否符合
net/core/fib_rules.c: ops->action: 執行match rule->action
net/ipv4/fib_rules.c: fib4_rule_action: function 定義於此
net/ipv4/fib_rules.c: fib4_rule_action: 當rule->action 為 FR_ACT_TO_TBL時, 執行 include/net/ip_fib.h: fib_get_table: 如果是non-Local, 則為ip_fib_main_table, 如果是Local, 則為ip_fib_local_table
net/ipv4/fib_rules.c: tbl->tb_lookup




Fast path
* using routing cache
* accomplish by ip_route_input function
compare the data of routing cache (rth->fl, rtable->flow)



Slow path
* using FIB(Forwarding Information Base)
* accomplish by ip_route_input_slow, fib_lookup

2007年9月21日 星期五

share/static library experience sharing

一般gcc compile 預設都是使用share library (libXXX.so.X), 除非compile時, gcc 加上 -static 或是直接將.a (libXXX.a) 和.o (object files)放在一起來link成execution file

如何看static library 的成員API 有哪些
# strings libpcap.a | grep pcap_findalldevs
pcap_findalldevs
pcap_findalldevs
pcap_findalldevs

Show the member symbols/variables/functions of shared library
# nm /usr/local/src/library/libpcap/libpcap-0.9.7/libpcap.so.0.9.7 | grep pcap_findalldevs
000052c0 T pcap_findalldevs

nm can show the shared library (libXXX.so.a.b.c) and static library (libYYY.a)

More verbose command with options
with -l, it will show the symbols/variables/functions appearing place(file name and line number) originally
with -o, it will print out the symbols/variables/functions belong to which library

show the symbols of the static library
# nm -o -l /usr/lib/libeXosip2.a 2> /dev/null | grep eXosip_init
/usr/lib/libeXosip2.a:eXconf.o:00001800 T eXosip_init /usr/local/src/sip/libeXosip2-3.0.3-3/src/eXconf.c:616

show the symbols of the shared library
# nm -o -l /usr/lib/libeXosip2.so.4.2.0 2> /dev/null | grep eXosip_init
/usr/lib/libeXosip2.so.4.2.0:0000c4ce T eXosip_init /usr/local/src/sip/libeXosip2-3.0.3-3/src/eXconf.c:616

If you have ever used to strip the static/shared library, all the symbols (functions/variables) inside the file will be deleted.
# strip /usr/lib/libeXosip2.a
# strip /usr/lib/libeXosip2.so.4.2.0

The type is displayed as a letter;
lowercase means that the symbol is local,
uppercase means that the symbol is global (external).

Typical symbol types include
T (a normal definition in the code section),
D (initialized data section),
B (uninitialized data section),
U (undefined; the symbol is used by the library but not defined by the library),
W (weak; if another library also defines this symbol, that definition overrides this one)



如何看某一個程式使用哪些shared library
# ldd zip
libc.so.6 => /lib/i686/libc.so.6 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7fee000)


Question: 下面這樣的程式編譯, 不是只要用到 static library 就可以了嗎? 為什麼還要用到 dynamic library?

# cat aaa.c
#include
#include

void main()
{
char errbuf[1024];
pcap_if_t *devices = NULL;
pcap_findalldevs(&devices, errbuf);
printf("ok\n");


# gcc -o aaa -lpcap aaa.c
aaa.c: In function `main':
aaa.c:5: warning: return type of `main' is not `int'
aaa.c:10:2: warning: no newline at end of file
/tmp/cc6CFwvH.o: In function `main':
/tmp/cc6CFwvH.o(.text+0x2f): undefined reference to `pcap_findalldevs' ==> 未定義 pcap_findalldevs, 因為libpcap.so.0 沒有包含這個API
collect2: ld returned 1 exit status

>>> libpcap static/shared library compiling procedures
# ./configure --prefix=/home/userName/usr --exec-prefix=/home/userName/usr --enable-yydebug

( DON'T set this parameter, --enable-optimizer-dbg, cause it will result the "dflag" variable in the optimize.c nondefined. And later if we compile other program will due to linking error...

my examples:
compile NSAT program...
g++ -Wall -O6 -funroll-loops -ansi -fPIC -DLINUX functions.o pidalloc.o nsat.o progress.o AuditSet.o SockSet.o Distributed.o Logging.o mod/binfo.o mod/bo.o mod/ftp.o mod/rpc.o mod/snmp.o mod/www.o mod/xp_icmp_addrmask.o mod/xp_icmp_timestamp.o mod/xp_pcap_iface.o mod/xp_utils.o mod/xp_icmp_echo.o mod/xp_logic_tree.o mod/xp_pkt_exams.o mod/xp_icmp_infr.o mod/xp_udp_probe.o libmix++/net/net.o libmix++/misc/misc.o libmix++/misc/exclude.o -o ../nsat -L/usr/X11R6/lib -L/home/userName/usr/lib -lX11 -lrpcsvc -lpcap
/home/userName/usr/lib/libpcap.so: undefined reference to `dflag'
)


make all
# make install
會編譯出來 libpcap.a static library
# make shared
# make install-shared
會編譯出來 libpcap.so.0.9.7 shared library

要真正編譯之前, 需要先到/usr/local/lib or /usr/lib 下面建立soft link 如下
ln -sf ./libpcap.so.0.9.7 ./libpcap.so

之後再去編譯程式就ok了

Or
{
# tar xvfz libpcap-1.0.0.tar.gz cd libpcap-1.0.0
# ./configure --prefix=/usr
# make shared all
# make install-shared install
# ln -sf /usr/lib/libpcap.so.1.0.0 /usr/lib/libpcap.so
# ln -sf /usr/lib/libpcap.so.1.0.0 /usr/lib/libpcap.so.1
}

[root@localhost src]# cat aaa.c
#include
#include

int main()
{
char errbuf[1024];
pcap_if_t *devices = NULL;
pcap_findalldevs(&devices, errbuf);
printf("ok\n");
return 0;
}
[root@localhost src]# gcc -o aaa -lpcap -L/usr/local/lib aaa.c
# ls aaa -la
-rwxr-x--- 1 root root 11769 Sep 21 17:45 aaa

成功編譯出 aaa 程式

How to use ldconfig to add the /usr/lib to the system permanently?
Use the following command to add the library path
PATH="$PATH:/sbin" ldconfig -n /usr/lib


openssl 編完 make install 之後秀出來的message, 告知我們如何做share library linking
* you link with static (archive) libraries. If you are truly
paranoid about security, you should use static libraries.
* you use the GNU libtool code during linking
(http://www.gnu.org/software/libtool/libtool.html)
* you use pkg-config during linking (this requires that
PKG_CONFIG_PATH includes the path to the OpenSSL shared
library directory), and make use of -R or -rpath.
(http://www.freedesktop.org/software/pkgconfig/)
* you specify the system-wide link path via a command such
as crle(1) on Solaris systems.
* you add the OpenSSL shared library directory to /etc/ld.so.conf
and run ldconfig(8) on Linux systems.

We can show all the searched directories that
# ldconfig -Nv | grep ":" | sed 's/:.*//'


* you define the LD_LIBRARY_PATH, LIBPATH, SHLIB_PATH (HP),
DYLD_LIBRARY_PATH (MacOS X) or PATH (Cygwin and DJGPP)
environment variable and add the OpenSSL shared library
directory to it.

One common tool to check the dynamic dependencies of an executable
or dynamic library is ldd(1) on most UNIX systems.

See any operating system documentation and manpages about shared
libraries for your version of UNIX. The following manpages may be
helpful: ld(1), ld.so(1), ld.so.1(1) [Solaris], dld.sl(1) [HP],
ldd(1), crle(1) [Solaris], pldd(1) [Solaris], ldconfig(8) [Linux],
chatr(1) [HP].
cp libcrypto.pc /tmp/newopenssl/lib/pkgconfig
chmod 644 /tmp/newopenssl/lib/pkgconfig/libcrypto.pc
cp libssl.pc /tmp/newopenssl/lib/pkgconfig
chmod 644 /tmp/newopenssl/lib/pkgconfig/libssl.pc
cp openssl.pc /tmp/newopenssl/lib/pkgconfig
chmod 644 /tmp/newopenssl/lib/pkgconfig/openssl.pc