最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++詳解實現(xiàn)二層轉發(fā)

 更新時間:2022年05月24日 08:37:07   作者:程序猿編碼  
數(shù)據(jù)鏈路層是開放系統(tǒng)互連 (OSI) 模型中的第二層,該層用于通過 LAN 等單一網(wǎng)絡進行通信的節(jié)點,第二層數(shù)據(jù)包不能從一個網(wǎng)絡傳輸?shù)搅硪粋€網(wǎng)絡。而二層轉發(fā)是根據(jù)報文的目的MAC直接進行轉發(fā),轉發(fā)過程中不用對報文的頭部做任何的修改

OSI第2層

前兩個字段分別是目的地址和源地址字段。第3個字段是2字節(jié)的類型字段,用來標識上一層是什么協(xié)議。

數(shù)據(jù)鏈路層有兩個子層:邏輯鏈路控制 (LLC) 子層和媒體訪問控制 (MAC) 子層。

媒體訪問控制 (MAC):MAC 子層處理硬件標識號的分配,稱為 MAC 地址,它唯一地標識網(wǎng)絡上的每個設備。 任何兩個設備都不應具有相同的 MAC 地址。 MAC 地址是在制造時分配的。 大多數(shù)網(wǎng)絡都會自動識別它。 MAC 地址位于網(wǎng)卡 上。

交換機跟蹤網(wǎng)絡上的所有 MAC 地址。

邏輯鏈路控制 (LLC):LLC 子層處理成幀尋址和流量控制。 速度取決于節(jié)點之間的鏈接,例如以太網(wǎng)或 Wifi。

第 2 層上的數(shù)據(jù)單元是一個幀。每個幀都包含一個幀頭、正文和一個幀尾:

Header:通常包括源節(jié)點和目標節(jié)點的 MAC 地址。

Body:由正在傳輸?shù)奈唤M成。

Trailer:包括錯誤檢測信息。 當檢測到錯誤時,根據(jù)網(wǎng)絡或協(xié)議的實現(xiàn)或配置,幀可能會被丟棄,或者可能會將錯誤報告給更高層以進行進一步的糾錯。

error detection mechanisms::循環(huán)冗余校驗 (CRC) 和幀校驗序列 (FCS)。

通常有一個最大幀大小限制,稱為最大傳輸單元,MTU。 巨型幀超過標準 MTU.

通過ARP解析出目標 MAC 地址?

傳統(tǒng)交換在 OSI 模型的第 2 層運行,其中數(shù)據(jù)包根據(jù)目標 MAC 地址發(fā)送到特定的交換機端口。第 2 層網(wǎng)段中的設備不需要路由即可到達本地對等點。 然而,需要的是可以通過地址解析協(xié)議 (ARP) 解析的目標 MAC 地址,如下所示:

在這里,PC A 想要將流量發(fā)送到 IP 地址為 192.168.1.6 的 PC B。 然而,它不知道唯一的 MAC 地址,直到它通過 ARP 發(fā)現(xiàn)它,該 ARP 在整個第 2 層網(wǎng)段中廣播。

然后將數(shù)據(jù)包發(fā)送到適當?shù)哪繕?MAC 地址,交換機將根據(jù)其 MAC 地址表將正確的端口轉發(fā)出去。

什么是MAC地址表

MAC地址表是在交換機中記錄局域網(wǎng)主機和對應接口關系的表,交換機就是根據(jù)這張表負責將數(shù)據(jù)幀傳輸?shù)街付ǖ闹鳈C上的。

MAC地址表可以動態(tài)的學習數(shù)據(jù)幀中的原MAC地址。在MAC地址表中,交換機的一個接口可以對應多個MAC地址。一個MAC地址只能對應在一個接口上。下面是MAC地址表形成的具體過程,如下:

二層轉發(fā)C/C++代碼實現(xiàn)

cethping:

void ethping(char *destination, char* interface){
    //創(chuàng)建原始套接字。 指定接口名稱
    struct RawSocket* rawsocket = new_RawSocket(interface);
    //數(shù)據(jù)包數(shù)據(jù)緩沖區(qū)
    unsigned char buf[1024];
    //定義數(shù)據(jù)包。 投射以匹配以太網(wǎng)幀的格式
    struct ethhdr_frame* eth_packet = (struct ethhdr_frame*)buf;
    //存儲發(fā)送方和接收方的 MAC 地址。 協(xié)議類型是可選的,并且指定了 0x0806。
    //根據(jù)指定的接口名稱獲取發(fā)送者的MAC地址
    memset(buf, 0x0, sizeof(eth_packet));
    set_macaddr_from_string(destination, eth_packet->h_dest);
    set_macaddr_from_ifname(interface, eth_packet->h_source);
	eth_packet->h_proto = 0x0806;
    //在payload中設置字符串“Hello”
    char* data = "Hello";
    memcpy(eth_packet->payload, data, sizeof(data)); 
    //綁定指定接口上的socket
    rawsocket->bind_rawsocket(rawsocket);
    int send_size = send(rawsocket->socket, &buf, sizeof(buf), 0);
    printf("%dbyte send.\n", send_size);
    //關閉原始套接字
    rawsocket->close_rawsocket(rawsocket);
}
int main(int argc, char *argv[]){
    if(argc != 3){
        printf("usage: %s <destination> <interface>", argv[0]);
        exit(0);
    }
    char *destination = argv[1];
    char *if_name = argv[2];
    ethping(destination, if_name);
    return 0;
}

cethpingd:

void start_daemon(char *interface){
    //創(chuàng)建原始套接字(指定接收器接口名稱)
    struct RawSocket* rawsocket = new_RawSocket(interface);
    int len;
    //使用 bind 綁定到接口
    rawsocket->bind_rawsocket(rawsocket);
    while(1){
        int len = rawsocket->recv_rawsocket(rawsocket);
        struct ethhdr_frame *data = (struct ethhdr_frame*)(rawsocket->buf);
        fflush(stdout);
        //顯示接收到的數(shù)據(jù)包的內(nèi)容
        if(len > 0){
            printf("src: ");
            print_macaddr(data->h_source);
            printf(", ");
            printf("dst: ");
            print_macaddr(data->h_dest);
            printf(", ");
            printf("type: ");
            printf("%02x", (uint16_t)data->h_proto);
            printf(", ");
            printf("payload: ");
            printf("%s", data->payload);
            printf("\n");
        }
    }
}
int main(int argc, char *argv[]){
    if(argc != 2){
        printf("usage: %s <interface>", argv[0]);
        exit(0);
    }
    char *if_name = argv[1];
    start_daemon(if_name);
    return 0;
}

編譯:

增加兩個虛擬網(wǎng)卡:

運行:

總結

轉發(fā)是將連接到網(wǎng)絡交換機一個端口的設備的網(wǎng)絡流量傳遞到連接到交換機上另一個端口的另一個設備的過程。

當?shù)?2 層以太網(wǎng)幀到達網(wǎng)絡交換機上的端口時,交換機會讀取以太網(wǎng)幀的源 MAC 地址作為學習功能的一部分,它還會讀取目標 MAC 地址作為轉發(fā)功能的一部分。目標 MAC 地址對于確定連接目標設備的端口號很重要。如果在 MAC 地址表中找到目的 MAC 地址,則交換機通過 MAC 地址對應的端口轉發(fā)以太網(wǎng)幀。

參考:

《TCP IP詳解卷一》

到此這篇關于C/C++詳解實現(xiàn)二層轉發(fā)的文章就介紹到這了,更多相關C語言二層轉發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++深入講解對象的銷毀之析構函數(shù)

    C++深入講解對象的銷毀之析構函數(shù)

    構造函數(shù)在創(chuàng)建對象時被系統(tǒng)自動調(diào)用,而析構函數(shù)(Destructor)在對象被撤銷時被自動調(diào)用,相比構造函數(shù),析構函數(shù)要簡單的多
    2022-04-04
  • C語言回溯法 實現(xiàn)組合數(shù) 從N個數(shù)中選擇M個數(shù)

    C語言回溯法 實現(xiàn)組合數(shù) 從N個數(shù)中選擇M個數(shù)

    在平時的算法的題目中,時常會遇到組合數(shù)相關的問題,暴力枚舉。在N個數(shù)中挑選M個數(shù)出來。利用for循環(huán)也可以處理,但是可拓展性不強,于是寫這個模板供以后參考
    2018-08-08
  • C語言數(shù)據(jù)結構之圖的遍歷實例詳解

    C語言數(shù)據(jù)結構之圖的遍歷實例詳解

    這篇文章主要介紹了C語言數(shù)據(jù)結構之圖的遍歷實例詳解的相關資料,需要的朋友可以參考下
    2017-07-07
  • C語言?const修飾普通變量和指針的操作代碼

    C語言?const修飾普通變量和指針的操作代碼

    這篇文章主要介紹了C語言const修飾普通變量和指針,用const修飾普通變量時,是在語法層面限制了變量的修改,但是本質(zhì)上,變量還是變量,是一種不能被修改的變量,本文通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • C、C++線性表基本操作的詳細介紹

    C、C++線性表基本操作的詳細介紹

    這篇文章主要給大家介紹了關于C、C++線性表基本操作的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 用C語言實現(xiàn)排雷游戲

    用C語言實現(xiàn)排雷游戲

    大家好,本篇文章主要講的是用C語言實現(xiàn)排雷游戲,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++中順序表操作的示例代碼

    C++中順序表操作的示例代碼

    這篇文章主要為大家詳細介紹了C++中順序表的基礎操作的相關代碼,主要有順序表的輸出、插入和刪除數(shù)據(jù)等,感興趣的小伙伴可以了解一下
    2022-10-10
  • C語言實現(xiàn)簡單的三子棋小游戲

    C語言實現(xiàn)簡單的三子棋小游戲

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)簡單的三子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • c++關鍵字const的用法詳解

    c++關鍵字const的用法詳解

    在類中,如果你不希望某些數(shù)據(jù)被修改,可以使用const關鍵字加以限定。const 可以用來修飾成員變量、成員函數(shù)以及對象,希望能夠給你帶來幫助
    2021-09-09
  • C語言數(shù)據(jù)結構超詳細講解單向鏈表

    C語言數(shù)據(jù)結構超詳細講解單向鏈表

    鏈表可以說是一種最為基礎的數(shù)據(jù)結構了,而單向鏈表更是基礎中的基礎。鏈表是由一組元素以特定的順序組合或鏈接在一起的,不同元素之間在邏輯上相鄰,但是在物理上并不一定相鄰。在維護一組數(shù)據(jù)集合時,就可以使用鏈表,這一點和數(shù)組很相似
    2022-03-03

最新評論

黎城县| 丘北县| 乐至县| 合肥市| 静安区| 五河县| 襄汾县| 鱼台县| 保山市| 黔江区| 加查县| 申扎县| 石屏县| 沿河| 明水县| 霞浦县| 启东市| 尚志市| 鄯善县| 邵阳市| 阿鲁科尔沁旗| 怀宁县| 沙雅县| 吴堡县| 图们市| 云南省| 社会| 铜鼓县| 铜梁县| 兴和县| 古田县| 和龙市| 邢台县| 河曲县| 无锡市| 嘉定区| 手游| 前郭尔| 玛纳斯县| 万全县| 陇西县|