發表文章

目前顯示的是有「Networks」標籤的文章

libpcap 使用範例

最近因為工作上的需求,所以透過 libpcap 寫了一個小程式。程式紀錄在下面。應該不難懂,所以就不多做說明。程式主要參考 sniffex ,不過主要針對  DHCP 的封包進行攔截以及顯示。 #include #include #include #include #include #include #include #include #define SIZE_ETHERNET (14) #define SIZE_UDP (8) #define ETHER_ADDR_LEN (6) const char *DHCP_MSG_TYPE_STR[9] = { "None", "DHCP Discover", "DHCP Offer", "DHCP Request", "DHCP Decline", "DHCP ACK", "DHCP NACK", "DHCP Release", "DHCP Inform" }; struct sniff_ethernet { uint8_t ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ uint8_t ether_shost[ETHER_ADDR_LEN]; /* source host address */ uint16_t ether_type; /* IP? ARP? RARP? etc */ }; struct sniff_ip { uint8_t ip_vhl; /* version << 4 | header length >> 2 */ uint8_t ip_tos; /* type of service */ uint16_t ip_len; /...

當 send 被 Block 的時候

今天在工作上遇到一個問題。有兩個 process ( process A 和 process B ) 透過 unix domain socket 彼此在傳遞資料,結果發現 process A 在送資料到 process B  的時候,程式居然卡在 send 這支系統函式。send 是會卡住的函式嗎? 答案是: 會 !來看看「男人」怎麼說: ssize_t send(int sockfd, const void *buf, size_t len, int flags ); When the message does not fit into the send  buffer  of  the  socket,  send()  normally blocks , unless the socket has been placed in nonblocking I/O mode .  In nonblocking mode it would fail with the error EAGAIN or EWOULDBLOCK in this case.   The  select(2)  call may be used to determine when it is possible to send more data. 意思是當呼叫 send 的時候,send 會先將資料放到 kernel 的 buffer,如果 buffer 已經放不進去了,而且 send 又處於 BLOCK 的模式時,這時候 send 就會卡住。而為什麼 buffer 會滿呢?因為 process B 處理封包的時間過久,進而造成 kernel buffer 被 process A 源源不絕的封包給塞滿了,然後 process A 的 send 就被 block 了。解決這個問題的方法可以將 socket 設成 non-blocking mode ,或是在傳送封包的時候把 flag 設成 MSG_DONTWAIT 。而這也就是為什麼 epoll, select 這類的函式需要去偵測 fd 是否已經是可寫狀態的原因。不過更根本要處理的問題是,為什麼 process...

TCP 和 UDP 共用同一個 Port?

這幾天在做網路實驗,利用 iperf3 來觀測流量的時候,發現一個神奇的地方,那就是 iperf3 在設定 server 端的時候,不用指定是 tcp 還是 udp,這跟 iperf 第2版以前是不一樣的。 iperf2: SYNOPSIS       iperf -s [ options ]       iperf -u -s [ options ] GENERAL OPTIONS       -u, --udp            use UDP rather than TCP iperf3: SYNOPSIS        iperf3 -s [ options ]        iperf3 -c server [ options ] CLIENT SPECIFIC OPTIONS       -u, --udp            use UDP rather than TCP 這代表 TCP 和 UDP 的 Socket 是可以同時使用同一個 Port 的。其實我一直以為是不行的(這就叫作孤陋寡聞 ...)。為了實驗起見,我自己寫了一個小小的 Echo Server,在指定的 Port 上同時監聽 TCP 和 UDP,來看看是否能夠運作(Client的程式就不附在上面了)。   #include <stdio.h> // for printf() and fprintf() #include <sys/socket.h> // for socket(), bind(), and connect() #include <arp...

Back to Basics:從 mininet 談起

話先說在前面,這篇文章完全不會提到任何和 mininet架設、操作有關係的內容,因為這部份我都請同事代勞了(明明就是威脅加恐嚇還不給胡蘿蔔,誰叫我沒有胡蘿蔔) ,也因為這樣所以我沒有寫任何相關的文章,反正網路上已經一大堆了。 會想寫這篇文章是因為一個學生跟我說的一句話:「我的老師覺得 mininet 只是模擬器,不是很真實,所以他要我們參考網路上的文章,把 openvswitch(縮寫為 ovs)放到 AP 上來進行實驗。」聽到這句話我我第一時間完全不知道該怎麼回答。mininet 是不是模擬器?是!mininet 算是模擬器,既是模擬就有一定程度的不真實性,但是那個老師知道 mininet 的運作原理嗎? mininet 是 Stanford 大學 Brandon Heller 的研發成果,它的概念很單純,就是利用 Linux Kernel 所提供的 network namespace 概念來建制虛擬環境,而每一台的 openflow switch 或是 host,其實就是一個獨立的 namespace。相關的概念可以參考我之前寫過的文章 linux network namespace 。而在 mininet 裏面,OpenFlow switch 的部份就是直接使用 openvswitch ,也就是說,使用 mininet 和把 openvswitch porting 到 AP 上是幾乎一樣的效果。知道這些細節以後,我在使用 mininet 上就會比較放心了。畢竟最後的問題就是一台主機的運算資源能不能負擔這麼多個 namespace 的問題,而這 performance 的議題難道會因為 porting 到 AP 上就不存在嗎? 我在意的地方到不是老師的質疑,而是大部份我看過的學生,在 mininet 的使用上都不會去深入了解它的原理。為什麼被老師問一下就回答不出來,為什麼報告 mininet 只會停留在操作的層及而不會進一步去釐清它的實作技術?只會照著文件一步一步的操作,是很難做到舉一反三。其實我也不是多勤勞的傢伙,會去研究這東西只是因為在某次報告中要介紹相關技術,為了不要讓自己講的很心虛所以就稍微研究了一下。但盼望不要因為當工程師愈來愈久之後,就忘記了最初研究的樂趣。 ... 總的來說,這是我對自己提醒的文章。

我對 OpenFlow APP 的看法

會寫這篇文章最主要的理由在於,我發現很多人(包含我自己的長官以及眾多的指導委員)對於 OpenFlow APP的看法和我不一樣(這是客氣的說法,其實是 我認為他們的想法是錯誤 的)。所以囉,我決定整理一下自己的想法並寫在這裡,希望有興趣的人可以一起參與討論(雖然沒多少人看吧),一方面可以檢討自己的想法;二方面可以宣傳自己的理念。在這邊要先說明一件事,SDN 是一個概念而非實作上的技術,因此幾乎所有的東西都可以套入 SDN 的概念,因此我在這裡不談 SDN APP,而只單單著重在 OpenFlow APP。 很多人都期待 OpenFlow 可以帶來新的網路應用服務,well ... 單單這件事就有點問題,OpenFlow 算是一種 網路基礎建設的新型態架構 ,那麼我要問問,網路基礎建設所負責最主要的功能是什麼?答案很簡單,就是確保網路中的用戶端設備彼此之間能夠順利的連通,不管是 L2 switching 或是 L3 routing,那我們回到最基本的問題,請問目前的網路設備(我是指 L2/L3 的 switch 和 router)沒有辦法達成這一類的功能嗎?答案是,當然可以,不然我們現在用的網路是假的嗎?既然如此,那使用 OpenFlow 到底有什麼好處?使用 OpenFlow 最大的價值在於,我可以用新的想法來處理 L2 switching 和 L3 routing,藉由新的巧思,來達到比過去更好的網路效能或是使用率。有沒有例子?最簡單的一個例子就是 Broadcast 的封包處理概念,相關的細節可以參考下面的連結。 如何利用 OpenFlow 打造一個「無廣播」的網路環境 在這裡我可以斷言, 如果使用了 OpenFlow 的架構卻在思考網路問題上停留在傳統網路的思維,下場是網路的效能只會變得比過去還差。 現在面對的問題是,很多人問說,我可以不可以用 OpenFlow 來做到一些網路應用服務功能,如 Firewall、IDS/IPS 等,然後說用 OpenFlow Switch 會比較便宜,他們的理由是硬體規統、功能統一化,而且不用被網路大廠所把持。事實上,我也看到有台灣廠商投入在這一塊的發展(如果他們問我的話,我一定會加以勸阻),為了不想惹麻煩上身,姑且保留公司名稱不提。我為什麼認為這種發展方向是有問題的呢?第一, 你會期待網路基礎建設中每台設備都...

NAT64 (WrapSix) Tutorial

圖片
最近請人協助架設環境,但似乎進度不如預期。所以一怒之下( 開玩笑的,我這人一向與人為善,您說是吧 ... ),就自己來架設NAT64的實驗環境,而這篇教學就是自己架設的過程紀錄。所以本篇文章告訴我們,少發脾氣比較好 ... ( 畫錯重點了吧 ) 在紀錄相關實驗步驟的時候,先來說明一下什麼是NAT64。Wikipedia上的描述是:「 NAT64 is a mechanism to allow IPv6 hosts to communicate with IPv4 servers. 」簡單來說,就是讓IPv6的設備能夠連上傳統IPv4網路設備的機制。怎麼做呢?看到NAT這幾個字眼應該用猜的也猜的到, 就是把封包的IPv6 Header替換成某個預先設定的IPv4 Header就完成了 。這裡要特別強調的一點,這個技術是 讓IPv6的設備能夠連上IPv4的設備,並不是讓IPv4的設備能夠連上IPv6的設備 !理由呢?下面這個解釋是從 TAYGA 的網站上抄下來的: It is technically impossible for a translation system operating purely at the IP layer to allow IPv4 hosts to establish connections to any arbitrary IPv6 server. Such a system would need to represent every IPv6 server on the Internet with a unique IPv4 address, which is clearly infeasible given the size of the IPv6 address space. 當然我個人有另外非技術的解釋,NAT64是為了讓過去已經存在的IPv4 Server可以繼續提供服務,而如果連Server都已經是IPv6了,現在的client大部份都有IPv6的介面了啊,直接用IPv6來溝通不就好了。 這邊的紀錄著重在於架設環境以及實驗,相關工具的程式碼解析不在範圍內(因為我沒有這麼多時間)。 1. 實驗環境 實驗環境的圖如下: 在這邊解釋一下NAT64的設定。IPv4和IPv6是指NAT64自己的I...

如何將Linux打造成OpenFlow Switch:Lagopus

圖片
上次介紹的部份是利用 openvswitch 來打造 OpenFlow switch,這也是大部份目前市面上買的到的 OpenFlow switch 所使用的軟體。問題是,它的傳輸效率不太好,畢竟它是透過 Linux kernel 來處理 Flow Entry。有人可能會說:「不會啊,我買的 switch 傳輸速度沒有問題啊,幾乎都可以達到 line rate」,OK,這是因為這些市面上賣的 switch 大部份都移植 Flow Entry 到處理程序到硬體平台上(像是 Broadcom 的晶片),所以傳輸速度當然不差, 可是!很多 OpenFlow 的功能就不支援了 ,畢竟那些晶片本來就沒有提供這些功能啊(通常是Set Field)。我們可以將目前 OpenFlow switch 的狀況大概整理如下: Software-based OpenFlow switch 功能支援度高,容易升級,但傳輸速度慢 Hardware-based OpenFlow switch 傳輸速度快,但功能並不完善 有沒有能夠兼顧兩者的設備呢?今天要介紹的這套 Lagopus 就是一個可能的選項。 Lagopus 是 NTT 所開發的 Software OpenFlow switch。Software?那傳輸速率呢?為了解決這個問題,Lagopus 採用了 Intel 所推出的 Data Plane Development Kit (DPDK) 技術。下面我們就先來介紹什麼是 DPDK。 DPDK簡介 DPDK 這個技術的概念可以用下圖來表達: DPDK(資料來源:Intel) 這張圖說明了 Intel 的 DPDK 技術是如何加速封包的處理。大概解釋一下。傳統 Linux 封包處理流程,是硬體收到封包後觸發 interrupt 後導到 Linux Kernel,如果還要進入 user space,就要通過 copy_to_user/copy_from_user 這樣的機制,而這會牽扯到記憶體拷貝的問題,這是因為不能讓 user space 直接讀到 kernel space 的記憶體管理,免得造成系統錯誤,所以作業系統會用一塊虛擬化的記憶體位置來給 user space 的 process,而這種記憶體保護機制以及拷貝很吃系統資源,這也是為什麼傳統上在處...

如何利用 OpenFlow 打造一個「無廣播」的網路環境

有沒有試過在實驗室網路或是公司網路內打開 wireshark 來收收看封包?就算自己什麼網路行為都沒做,還是會發現收到一大堆不是自己該收到的封包。為什麼?因為網路上充斥太多的廣播訊息了!什麼是廣播封包?首先,我們先將目光集中在同一個 subnet 中(一般來說,目前的網路設備通常不會讓廣播封包傳到 subnet 的外面),廣播封包就是一種讓同一個 subnet 裏面所有的成員都要收到的封包。常見的封包有 IP 位置為 255.255.255.255 或是 192.168.1.255 這一類的封包以及 MAC 位置為 FF:FF:FF:FF:FF:FF 的訊框。 一般來說,廣播封包的存在有兩個意義: 我不知道我想溝通的對象在哪裡,所以我只好大聲的呼喊希望那個對象會來回應我。 造成這種情況的主因是因為當初網路在設計時是採用分散式的架構。因為分散,所以沒有人知道整個網路的狀況。既然不知道,就只好所有人都去問一遍,這個行為就是廣播。常見的例子是 ARP 以及 DHCP DISCOVER 等。 所有人注意,下面是關於我的資訊 ... 這種情況通常是要招告天下關於我的資訊,所以本來就會廣播給所有人知道。常見的例子是 NetBios 以及 IPv6 Neighbor Discovery 等。 因為過去網路發展的因素,廣播信息似乎是必要的。但其實大部分的人都很討厭廣播,因為在大多數的情況下廣播信息根本不是自己要收的啊,就像是一開始提到的例子。網管人員一般來說也很討厭廣播,因為只會白白佔掉網路頻寬而已。 現在來想想 OpenFlow 的架構,OpenFlow 是一個邏輯上集中式的網路架構,並且在這網路上有個神一般的角色:OpenFlow Controller。那麼,還需要廣播信息的存在嗎? 我不知道要溝通的對象在哪裡?沒關係,Controller 應該知道 ; 招告天下,不用,告訴 Controller 就好了 。當然要改變 Host 的行為是不可能的事情,但我們可以透過 OpenFlow Entry 的設定來 透過非廣播的方式來處理廣播封包 。 在額外多討論一件事情。當網路上不存在廣播封包時, 請問一個 Loop-Free 的網路是否還是必須的?換句話說,我們還需要 Spanning Tree Protocol 嗎? 歡迎大家提出自己的意見(有人會留言嗎?) ...

Linux Network Namespace

今天要介紹的東西是 Linux Network Namespace。為什麼會知道這東西呢?主要是因為在研究 SDN 模擬器 mininet (正確來說是 OpenFlow 模擬器)時,發現它是透過 Linux Network Namespace 這個技術,將每個 Host 以及 Switch 獨立開來(Isolation),並在當中建立起虛擬的連線,藉這個概念在一台電腦內打造出虛擬的網路拓樸。所以就想說花點時間來看看如何使用這個技術。 我們先來看看在 Wikipedia 上關於 cgroups 的介紹: cgroups (abbreviated from control groups) is a Linux kernel feature to limit , account , and isolate resource usage (CPU, memory, disk I/O, etc.) of process groups. Namespace isolation While not technically part of the cgroups work, a related feature of the Linux kernel is namespace isolation , where groups of processes are separated such that they cannot "see" resources in other groups. For example, a PID namespace provides a separate enumeration of process identifiers within each namespace. Also available are mount, UTS, network and SysV IPC namespaces. 簡單來說,就是透過 group 這樣的觀念,讓每個 process group 間所使用的資源能夠獨立開來而不會互相影響。而這樣的 group 就被稱做是 namespace。而今天要看的是 Network Namespace。用例子來看或許會比較容易了解,下面的例子主要是參考 這個網頁 所建立出來的。 1. 建立 N...

SDN 簡介

這邊是 2014.06.23 在元智大學介紹  SDN 所使用的簡報。這幾份簡報基本上已經覆蓋了 SDN 的技術研究以及實際開發所需要的背景,很適合當作入門的簡報。當中還缺少一份關於 OpenFlow 的介紹,因為那是我同事製作的,不方便放到我自己的 Blog 上面,所以之後我自己補上那一份的自行製作的投影片。另外,我很討厭我公司的簡報背景,所以我換了自己喜歡的 template 才放上來。 如果有人需要我去簡介的話,歡迎隨時跟我聯絡,我很樂意唷! 01.Introduction.to.SDN 這份投影片是從故事入手,幫助大家輕鬆學習 SDN 的概念,也同時帶出業界不同公司的不同看法。 02.SDN.Research.Tools SDN 很紅,但如果要做研究,應該要從何上手?OpenFlow Switch 很貴,我該怎麼辦?這份投影片介紹目前 SDN可使用的相關工具,並給了自己的 Comments。 03.SDN.APPs 軟體定義網路,關鍵當然在軟體(智能),該怎麼設計自己的網路才是 SDN 的真正關鍵。本份投影片介紹了 SDN App 的設計概念,透過實際的例子來帶出 SDN 創新思維。

Netfilter Hook 程式範例

圖片
Netfilter 是 Linux Kernel 裏面對於網路封包處理一個非常有趣的設計,它在 Linux Kernel 的封包處理路徑上安插了許多的 Hook Point,這樣使用者可以隨自己的高興在這些 Hook Point 上安插自己的封包處理行為(使用註冊 callback function的方式),常見的應用如防火牆檢查、NAT等。在這邊稍微提一下,很多人會說 Linux 是用 iptables 來做防火牆的,我不太喜歡這個說法(但我不會說它是錯的),因為 iptables 不過是設定 netfilter 的 user space 工具,當你使用 iptables 時,不過就是將那些功能模組配合上使用者輸入的參數,然後掛載到對應的 Hook Point。下面是來自官網的描述: netfilter is a set of hooks inside the Linux kernel that allows kernel modules to register callback functions with the network stack . A registered callback function is then called back for every packet that traverses the respective hook within the network stack . 至於有哪些 Hook Point 可以參考下面這張來自 Wiki 的圖:  這個概念是從 Linux Kernel 2.4 以後就內建在核心的機制。基本上我在研究所很常利用 iptables 這個設定工具來使用 netfilter,但一直沒有實際寫這 callback 的機會(之前工作上沒碰到,外加人懶)。但現在因為工作上有特殊的需求(來自一個莫名其妙的設計),所以就請(逼迫?)我同事撰寫了一個 Netfilter Callback 的模組範例出來(從程式裡可以找到作者),下面就是這個範例: # include < linux/module.h > # include < linux/kernel.h > # include < linux/init.h > # include ...