linux网络体系架构
原創(chuàng)kylin_zeng:http://blog.csdn.net/kylin_fire_zeng 本文參考國嵌視頻教程,再此感謝國嵌教育。
一、協(xié)議棧層次對比:
1)網絡接口層把數(shù)據鏈路層和物理層合并在了一起,提供訪問物理設備的驅動程序,對應的網絡協(xié)議主要是以太網協(xié)議。
2)網絡層協(xié)議管理離散的計算機間的數(shù)據傳輸,如IP協(xié)議為用戶和遠程計算機提供了信息包的傳輸方法,確保信息包能正確地到達目的機器。重要的網絡層協(xié)議包括ARP(地址解析協(xié)議)、ICMP(Internet控制消息協(xié)議)和IP協(xié)議(網際協(xié)議)等
3)傳輸層的功能包括:格式化信息流、提供可靠傳輸。傳輸層包括TCP(Transmission Control Protocol,傳輸控制協(xié)議)和UDP(User Datagram Protocol,用戶數(shù)據報協(xié)議),它們是傳輸層中最主要的協(xié)議
4)應用層位于協(xié)議棧的頂端,它的主要任務是服務于應用,如利用FTP(文件傳輸協(xié)議)傳輸一個文件。常見的應用層協(xié)議有:HTTP,F(xiàn)TP,Telnet等。應用層是Linux網絡設定很關鍵的一層,Linux服務器的配置文檔主要針對應用層中的協(xié)議
二、linux網絡子系統(tǒng)
1)
2)Linux 網絡子系統(tǒng)的頂部是系統(tǒng)調用接口層。它為用戶空間的應用程序提供了一種訪問內核網絡子系
統(tǒng)的方法。位于其下面的是一個協(xié)議無關層,它提供了一種通用方法來使用傳輸層協(xié)議。然后是具體
協(xié)議的實現(xiàn),在Linux 中包括內嵌的協(xié)議TCP、UDP,當然還有IP。然后是設備無關層,它提供了
協(xié)議與設備驅動通信的通用接口,最下面是設備驅動程序。
3)系統(tǒng)調用接口:為應用程序提供訪問內核網絡子系統(tǒng)的方法:Socket系統(tǒng)調用。
4)協(xié)議無關接口:實現(xiàn)一組通用函數(shù)來訪問各種不同的協(xié)議:通過socket實現(xiàn)。Linux 中的socket 使用
struct sock來描述,這個結構包含了特定socket 所需要的所有狀態(tài)信息,還包括
socket 所使用的特定協(xié)議和在socket 上可以執(zhí)行的一些操作
5)網絡協(xié)議層用于實現(xiàn)各種具體的網絡協(xié)議,如:TCP、UDP 等
6)設備無關接口:設備無關接口將協(xié)議與各種網絡設備驅動連接在一起。
這一層提供一組通用函數(shù)供底層網絡設備驅動程序使用,讓它們可以對高層協(xié)議棧進行操作。首先,設備驅
動程序可能會通過調用register_netdevice 或unregister_netdevice 在內核中進行注冊或注銷。調
用者首先填寫net_device 結構,然后傳遞這個結構進行注冊。內核調用它的init 函數(shù)(如果定義了這種函
數(shù)),然后執(zhí)行一組健全性檢查,并將新設備添加到設備列表中(內核中的活動設備鏈表)
要從協(xié)議層向設備發(fā)送數(shù)據,需要使用dev_queue_xmit函數(shù),這個函數(shù)對數(shù)據進行排
隊,并交由底層設備驅動程序進行最終傳輸報文的接收通常是使用netif_rx執(zhí)行的。當?shù)讓釉O備驅動
程序接收到一個報文(包含在所分配的sk_buff 中)時,就會通過調用netif_rx 將數(shù)據上傳至設備
無關層,然后,這個函數(shù)通過netif_rx_schedule 將sk_buff 在上層協(xié)議隊列中進行排隊,供以后進行處理。
7)驅動程序:網絡體系結構的最底部是負責管理物理網絡設備的設備驅動程序層
****************************************************************************************************************************************
二、網絡驅動程序設計:
每個網絡接口都由一個net_device結構來描述,該結構可使用如下內核函數(shù)動態(tài)分配:
1、struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *))
sizeof_priv 私有數(shù)據區(qū)大??;mask:設備名;setup 初始化函數(shù)
2、struct net_device *alloc_etherdev(int sizeof_priv)
struct net_device
{
char name[IFNAMSIZ] ;//設備名,如:eth%d //%d表示由內核自動獲取。
vunsigned long state ;//設備狀態(tài)
vunsigned long base_addr ;//I/O 基地址
vunsigned int irq ;//中斷號
...
}
3、net_device初始化:int (*init)(struct net_device *dev)
初始化函數(shù)。該函數(shù)在register_netdev時被調用來完成對net_device 結構的初始化
net_device和字符驅動一樣, 網絡設備也要聲明能操作它的函數(shù)。有些操作可以保留為NULL, 有的可以通過ether_setup 來使用默認設置。網絡
接口的設備方法可分為兩組:基本的和可選的,基本方法包括那些使用接口所必需的;可選的方法實現(xiàn)更多高級的功能。
4、基本方法:
int (*open)(struct net_device *dev) //打開接口。ifconfig 激活時,接口將被打開。
int (*stop)(struct net_device *dev) //停止接口。該什么時候調用呢?
int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev) //數(shù)據發(fā)送函數(shù)。
5、可選操作:
int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd) //處理特定于接口的ioctl 命令
int (*set_mac_address)(struct net_device *dev, void *addr) //改變Mac地址的函數(shù),需要硬件支持該功能
6、設備注冊:
網絡接口驅動的注冊方式與字符驅動不同之處在于它沒有主次設備號,并使用如下函數(shù)注冊。
int register_netdev(struct net_device *dev)
7、sk_buff 存放網絡包:
Linux內核中的每個網絡數(shù)據包都由一個套接字緩沖區(qū)結構struct sk_buff 描述,即一個
sk_buff結構就是一個包,指向sk_buff的指針通常被稱做skb。
struct sk_buff
{
struct device *dev; //處理該包的設備
__u32 saddr; //IP源地址
__u32 daddr; //IP目的地址
__u32 raddr; //IP路由器地址
unsigned char *head; //分配空間的開始
unsigned char *data; //有效數(shù)據的開始
unsigned char *tail; //有效數(shù)據的結束
unsigned char *end; //分配空間的結束
unsigned long len; //有效數(shù)據的長度
};
8、skb操作函數(shù):
操作sk_buff的內核函數(shù)如下: struct sk_buff *alloc_skb(unsigned int len, int priority)
分配一個sk_buff 結構,供協(xié)議棧代碼使用 struct sk_buff *dev_alloc_skb(unsigned int len)分配一個sk_buff 結構,供驅動代碼使用
unsigned char *skb_push(struct sk_buff *skb, int len) //向后移動skb的tail指針,并返回tail移動之前的值。 這樣才能再填入后面的值
unsigned char *skb_put(struct sk_buff *skb, int len) //向前移動skb的head指針,并返回head移動之后的值 這樣才不會覆蓋后面的值
kfree_skb(struct sk_buff *skb) //釋放一個sk_buff 結構,供協(xié)議棧代碼使用
dev_kfree_skb(struct sk_buff *skb) //釋放一個sk_buff 結構,供驅動代碼使用
9、設備打開:
Open 請求任何它需要的系統(tǒng)資源并且啟動
接口:
注冊中斷,DMA等
設置寄存器,啟動設備
啟動發(fā)送隊列
例如:
int net_open(struct net_device *dev)
{
/*申請中斷*/
request_irq(dev->irq, &net_interrupt, SA_SHIRQ,
“dm9000”, dev);
/* 設置寄存器,啟動設備*/
...... ...... ...... ......
/*啟動發(fā)送隊列*/
netif_start_queue(dev);
}
10、數(shù)據發(fā)送:
當核心需要發(fā)送一個數(shù)據包時,它調用hard_start_transmit函數(shù),該函數(shù)將最終調用到net_device結構中的hard_start_xmit函數(shù)指針。
11、數(shù)據接收
網絡接口驅動可以實現(xiàn)兩種方式的報文接收: 中斷和查詢,Linux中驅動多采用中斷方式
接收流程:
1、分配Skb:
skb = dev_alloc_skb(pkt->datalen + 2)
2、從硬件中讀取數(shù)據到Skb
3、調用netif_rx將數(shù)據交給協(xié)議棧
netif_rx(skb)
12、中斷處理:
網絡接口通常支持3種類型的中斷: 新報文到達中斷、報文發(fā)送完成中斷和出錯中斷。中
斷處理程序可通過查看網卡中的中斷狀態(tài)寄存器,來分辨出中斷類型。
總結
以上是生活随笔為你收集整理的linux网络体系架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 番茄todo怎么加app(番茄小说到底怎
- 下一篇: 6.BLE---数据传输