發表文章

目前顯示的是 9月, 2008的文章

Function Pointer in C

Function Pointer 是C語言最重要的高等特色之一,最常見的例子就是 State Machine 的實作以及排序演算法的 compare function 輸入。下面的程式碼只是要記錄一個基本的用法,方便之後使用參考,畢竟從來沒用過(雖然知道很久了)。 #include stdio.h > int sum( int, int ); int sub( int, int ); int mul( int, int ); int mod( int, int ); int (*op[4]) ( int, int ) = { sum, sub, mul, mod }; int main() { .... int a, b, i; .... a = 5; .... b = 3; .... for( i = 0 ; i ........ printf("Operation %d result: %d\n", i, (*op[i])(a, b) ); .... } .... return 0; } int sum( int a, int b ) { return a+b; } int sub( int a, int b ) { return a-b; } int mul( int a, int b ) { return a*b; } int mod( int a, int b ) { return a%b; }

exec() family

這只是一件小事,特此記錄用以提醒 在 Google 上面搜尋 exec 系列的 example code,常常會看到下面的寫法: #include unistd.h > int main() { .... char * argv[ ] ={ "ls","-al","/etc/passwd",0}; .... execvp("ls",argv); .... return 0; } 這是一個很簡單的範例,很可以編譯執行,但卻暗藏危險 Why? 首先,來問問看「男人」 The exec() family of functions replaces the current process image with a new process image. 這句話的意思是「 將外部程式(ELF image)取代掉原來的 process 」 所以,一般來說,在程式裡面要使用 exec 系列的 functions 時, 不能在 parent process 裡叫用 exec system call 來跑外部程式;否則 parent process 會消失 。正確的作法應該是 先 fork 一個 process,並於那個 process 裡面進行 exec 的呼叫 。而上面的範例之所以沒問題只能說是「剛好」沒問題而已,為什麼剛好沒問題... 自己看囉~ 一個可以看出錯誤的例子 #include unistd.h > #include stdio.h > int main() { .... int a = 0; .... char * argv[ ] ={ "ls","-al","/etc/passwd",0}; .... execvp("ls",argv); .... a++; // 你會發現這裡不會執行唷~ .... printf("a = %d\n", a); // .... return 0; } 正確的範例 #include unistd.h > #include stdio.h > #include sys/types.h > int main() { .... ...

Linux Multicast Routing Cache

圖片
在 Linux 裡面,Multicast 的 Routing 會不同於一般的 Routing 方式,在公司實驗的時候,明明 Routing Table 都已經進行設定了,封包卻始終不按照自己所想的方式來轉送,於是跟同事進行研究後,得到下面的結論。 首先,先來看一張圖 當然,這張圖有點小,請按照連結去觀看原始大小 當網卡收到封包以後,處理順序會是 netif_receive_skb -> ip_rcv -> ip_rcv_finish -> ip_route_input -> ip_route_input_slow ... 在 ip_route_input 和 ip_input_route_slow 裡面會進行 routing 的動作 但其實在 ip_route_input 裡面有多加了一段判斷,是圖中所沒有的 /linux/net/ipv4/route.c if (MULTICAST(daddr)) { ... return ip_route_input_mc(skb, daddr, saddr, tos, dev, our); } 很明顯的可以看到 multicast 是被例外處理的 而 MULTICAST 的定義如下: /linux/include/linux/in.h #define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000)) 很明顯的,可以看出是 Class D 的區段 總之,要 Linux 進行 Multicast Forwarding 的條件如下: 1. /proc/sys/net/ipv4/conf/all/mc_forwarding 要設成 1 請注意,這邊直接使用 echo 來設定是沒有用的 MRouterFD = socket( AF_INET, SOCK_RAW, IPPROTO_IGMP ); setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT, (void *)&Va, sizeof( Va ) ); 這是直接抄自 smcroute 的 code (當然我拿掉了 error protection 的部分) 2. /proc/net/ip_mr_cache 裡面要有資料 簡單來說...