娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

1. ARP的簡介

Address Resolution Protocol-地址解析協議

ARP為IP地址到對應的硬件地址之間提供動態映射。從邏輯Internet地址到對應的物理硬件地址需要進行翻譯。這就是ARP的功能。ARP的功能是在32 bit的IP地址和采用不同網絡技術的硬件地址之間提供動態映射。


2. ARP的應答流程


任何時候我們敲入下面這個形式的命令:

[html] view plain copy

  1. % ftp bsdi  //示例而已  

都會進行以下這些步驟。這些步驟的序號如圖 4 - 2所示。

1) 應用程序FTP客戶端調用函數gethostbyname(3)把主機名(bsdi)轉換成32 bit的IP地址。這個函數在DNS(域名系統)中稱作解析器,我們將在第1 4章對它進行介紹。這個轉換過程或者使用DNS,或者在較小網絡中使用一個靜態的主機文件(/etc/hosts) 。

2) FTP客戶端請求TCP用得到的IP地址建立連接。

3) TCP發送一個連接請求分段到遠端的主機,即用上述 IP地址發送一份IP數據報(在第1 8章我們將討論完成這個過程的細節) 。

4) 如果目的主機在本地網絡上(如以太網、令牌環網或點對點鏈接的另一端) ,那么IP數據報可以直接送到目的主機上。如果目的主機在一個遠程網絡上,那么就通過 IP選路函數來確定位于本地網絡上的下一站路由器地址,并讓它轉發 IP數據報。在這兩種情況下,IP數據報都是被送到位于本地網絡上的一臺主機或路由器。

5) 假定是一個以太網,那么發送端主機必須把 32 bit的IP地址變換成48 bit的以太網地址。從邏輯Internet地址到對應的物理硬件地址需要進行翻譯。這就是 ARP的功能。ARP本來是用于廣播網絡的,有許多主機或路由器連在同一個網絡上。

6) ARP發送一份稱作ARP請求的以太網數據幀給以太網上的每個主機。這個過程稱作廣播,如圖 4 - 2中的虛線所示。 ARP請求數據幀中包含目的主機的IP地址(主機名為bsdi) ,其意思是“如果你是這個IP地址的擁有者,請回答你的硬件地址。 ”

7) 目的主機的ARP層收到這份廣播報文后,識別出這是發送端在尋問它的 IP地址,于是發送一個ARP應答。這個ARP應答包含IP地址及對應的硬件地址。

8) 收到ARP應答后,使ARP進行請求—應答交換的IP數據報現在就可以傳送了。

9) 發送IP數據報到目的主機。

3. ARP的分組格式


? 以太網報頭中的前兩個字段是以太網的源地址和目的地址。目的地址為全 1的特殊地址是廣播地址。電纜上的所有以太網接口都要接收廣播的數據幀。

? 兩個字節長的以太網幀類型表示后面數據的類型。對于 A R P請求或應答來說,該字段的值為0 x 0 8 0 6。

? 硬件類型字段表示硬件地址的類型。它的值為 1即表示以太網地址。

? 協議類型字段表示要映射的協議地址類型。它的值為 0 x 0 8 0 0即表示I P地址。它的值與包含I P數據報的以太網數據幀中的類型字段的值相同,這是有意設計的(參見圖 2 - 1) -忘了截過來了。

? 接下來的兩個1字節的字段,硬件地址長度和協議地址長度分別指出硬件地址和協議地址的長度,以字節為單位。對于以太網上I P地址的ARP請求或應答來說,它們的值分別為6和4。

? 操作字段(op)指出四種操作類型,它們是 ARP請求(值為1) 、ARP應答(值為2) 、RARP請求(值為3)和R ARP應答(值為4) (我們在第5章討論RARP) 。這個字段必需的,因為ARP請求和ARP應答的幀類型字段值是相同的。

? 接下來的四個字段是發送端的硬件地址(在本例中是以太網地址) 、發送端的協議地址(IP地址) 、目的端的硬件地址和目的端的協議地址。注意,這里有一些重復信息:在以太網的數據幀報頭中和ARP請求數據幀中都有發送端的硬件地址。

對于一個ARP請求來說,除目的端硬件地址外的所有其他的字段都有填充值。當系統收到一份目的端為本機的 ARP請求報文后,它就把硬件地址填進去,然后用兩個目的端地址分別替換兩個發送端地址,并把操作字段置為 2,最后把它發送回去。

--------------------------------以上內容整理于《TCP/IP協議詳解:卷1》----------------------------

理是那個那個理,但是過于抽象了,不過是基礎,看完上面再看實現,那感覺很爽的~~~

------------------------------------------以下內容產生于代碼及分析--------------------------------------

4. ARP的宏定義實現

 以太網協議而非802.3協議,看ETH命名的頭名字就曉得了,地址位置可以結合兩個header算算就出來了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27


// ******* ARP *******
//ARP包長度
#define ETH_ARP_PACKET_LEN          28

//硬件地址長度值
#define ETHTYPE_ARP_L_V             0x06
//協議地址長度值
#define ETHTYPE_ARP_PROTOCOL_SIZE_V 0x04
//操作碼位置 2字節
#define ETH_ARP_OPCODE_H_P 0x14
#define ETH_ARP_OPCODE_L_P 0x15
//ARP請求操作碼值
#define ETH_ARP_OPCODE_REQUEST_V    0x0001
#define ETH_ARP_OPCODE_REQUEST_H_V  0x00
#define ETH_ARP_OPCODE_REQUEST_L_V  0x01
//ARP響應操作碼值
#define ETH_ARP_OPCODE_REPLY_V      0x0002
#define ETH_ARP_OPCODE_REPLY_H_V    0x00
#define ETH_ARP_OPCODE_REPLY_L_V    0x02
// 發送者源硬件地址位置 6字節
#define ETH_ARP_SRC_MAC_P           0x16
//發送者源IP地址位置 4字節
#define ETH_ARP_SRC_IP_P            0x1c
//目標硬件地址位置 6字節
#define ETH_ARP_DST_MAC_P           0x20
//目標IP地址位置 4字節
#define ETH_ARP_DST_IP_P            0x26

5. ARP的實現函數

以太網的header在ARP的header之前,很簡單的,介紹先。

 配置以太網的頭,為14字節:6字節目的mac地址+6字節源mac地址+2字節協議類型,如圖4-3

1
2
3
4
5
6
7
8
9
10
11
12
13


// make a return eth header from a received eth packet
void make_eth(unsigned char *buf)
{
    unsigned char  i = 0;

    //copy the destination mac from the source and fill my mac into src
    while(i < sizeof(mac_addr))
    {
        buf[ETH_DST_MAC + i] = buf[ETH_SRC_MAC + i];
        buf[ETH_SRC_MAC + i] = macaddr[i];
        i++;
    }
}


展開就是這樣的,看看宏定義是否與此一一對應呢。


 在判斷為arp請求之后,填充以太網的頭之后響應arp請求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


void make_arp_answer_from_request(unsigned char *buf)
{
    unsigned char  i = 0;
    //配置以太網的頭,為14字節:6字節目的mac地址+6字節源mac地址+2字節協議類型
    make_eth(buf);
    buf[ETH_ARP_OPCODE_H_P] = ETH_ARP_OPCODE_REPLY_H_V; //arp 響應
    buf[ETH_ARP_OPCODE_L_P] = ETH_ARP_OPCODE_REPLY_L_V;

     // 后面的ARP_DEBUG插入此處即可。

    // fill the mac addresses:
    while(i < sizeof(mac_addr))
    {
        buf[ETH_ARP_DST_MAC_P + i] = buf[ETH_ARP_SRC_MAC_P + i];
        buf[ETH_ARP_SRC_MAC_P + i] = macaddr[i];
        i++;
    }

    i = 0;
    //fill the ipv4 addresses
    while(i < sizeof(ipv4_addr))
    {
        buf[ETH_ARP_DST_IP_P + i] = buf[ETH_ARP_SRC_IP_P + i];
        buf[ETH_ARP_SRC_IP_P + i] = ipaddr[i];
        i++;
    }

    // eth+arp is 42 bytes:
    enc28j60PacketSend(ETH_HEADER_LEN + ETH_ARP_PACKET_LEN, buf);
}

當然,響應ARP請求的前提是你得確定有人向你發出ARP請求(下面那個函數就是了),并且這個人是誰,你是要知道的(通過發送者的IP和MAC地址),這個很容易,本協議是將地址放在幾個全局變量里面的,大家就都知道了,雖然全局變量用起來很爽,但是對模塊化以及后期維護帶來的不便也是很大的。

 檢查是否為合法的eth,并且只接受發給本機的arp數據,此函數在上面那個函數之前被調用,再下面的代碼就是演示的例程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


//檢查是否為合法的eth,并且只接受發給本機的arp數據
unsigned char  eth_type_is_arp_and_my_ip(unsigned char *buf, unsigned  int len)
{
    unsigned char  i = 0;

    // 幀長度不得小于以太網的最小幀長度值,即46-除以太網頭和CRC檢測
    if(len < MIN_FRAMELEN)
    {
        return(0);
    }

    if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V)
    {
        return(0);
    }

    //不是發給本機IP地址的不接收,那么如此說來,我在這里可以設定監聽其他IP的信息!
    while(i < sizeof(ipv4_addr))
    {
        if(buf[ETH_ARP_DST_IP_P + i] != ipaddr[i])
        {
            return(0);
        }

        i++;
    }

    return(1);
}

以上函數在別人向你發送任何請求之前都將被調用一次(原因是本協議只是實現了對IP和ARP的響應),所以需要在一個while死循環或者RTOS的一個thread/task/process里面。如下所示:

 上層調用示例代碼 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


/*
    此部分為一部分代碼
*/

/*do something initial */

while(1)
{
    // get the next new packet:         
    plen = enc28j60PacketReceive(BUFFER_SIZE, buf);      
      
    // plen will be unequal to zero if there is a valid packet (without crc error)          
    if(plen==0)
    {
        continue;
    }
    // check if ip packets are for us:          
    if(eth_type_is_ip_and_my_ip(buf,plen)==0) 
    {
        //丟棄本次獲取的數據,再接下一個
        continue;
    }   
    // arp is broadcast if unknown but a host may also
    // verify the mac address by sending it to 
    // a unicast address.
    //這里就是ARP的響應了,如果我們在這里加入串口調試,
    //就可以將誰在向我發送arp請求的數據打印到串口
    //當然加一個選擇宏,放在函數里面更方便一點           
    if(eth_type_is_arp_and_my_ip(buf,plen))
    {
        make_arp_answer_from_request(buf);          
        continue;
    }
    /*do other things */
  
}

6. ARP實驗調式

嗯,接者來看看在make_arp_answer_from_request函數里面加入串口調試信息來輸出arp請求者的ip和mac地址。

 加入到 make_arp_answer_from_request中的調試代碼,用于輸出ARP請求者的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42


#ifdef ARP_DEBUG
printf("ARP請求者IP地址 : \r\n");

while(i < sizeof(ipv4_addr))
{
    printf("%d", buf[ETH_ARP_SRC_IP_P + i]);

    if(i != sizeof(ipv4_addr) - 1) // 加入判斷只是為了輸出的形式好看點 
    {
        printf(".");
    }

    else
    {
        printf("\r\n");
    }

    i++;
}

i = 0;
printf("ARP請求者MAC地址 :\r\n");

while(i < sizeof(mac_addr))
{
    printf("%x", buf[ETH_ARP_SRC_MAC_P + i]);

    if(i != sizeof(mac_addr) - 1)
    {
        printf(":");
    }

    else
    {
        printf("\r\n");
    }

    i++;
}

i = 0;
#endif

PC端:測試arp請求需要先執行“arp -d”清楚本地的arp-ip對應列表,這樣PC機才會發送ARP請求

ps:enj28j60的MAC地址是軟件設定的,所以就不打碼了。


串口端:顯示調試信息而已


下面是我放著沒動它,局域網內就有其他主機來找我的嵌入式Web Server了,O(∩_∩)O~


--------------------------------------------以下是我看代碼看的不仔細的糾結,可跳過-----------------------------------------------

但是在實驗過程中發現如下情況是不會調用make_arp_answer_from_request函數的:PC機本地有arp-ip列表,就是ping過一次以后ping第二次的就不會去響應了,這個本來就是要如此的,希望結果就是這樣的,你要問我是誰(MAC地址是多少),然后我告訴你一次,你記住就ok了么。但是問題出在我們的協議棧實現代碼里面,本協議棧在通過eth_type_is_arp_and_my_ip判斷了是發給本機的數據包之后,就會調用arp響應的,沒有一個對以太網header的類型的判斷啊。怎么會自己變的智能了呢?

 代碼如下 

1
2
3
4
5
6



if(eth_type_is_arp_and_my_ip(buf, plen))
{
    make_arp_answer_from_request(buf);
    continue;
}

那么問題出在哪里呢?

1. 難道是進入make_arp_answer_from_request 函數,但是沒有發送出去么?當然也不會在enc28j60PacketSend(ETH_HEADER_LEN + ETH_ARP_PACKET_LEN, buf); 里面,因為沒有判別信息傳遞進去。(當然發不發,只要如函數之后就會有打印信息輸出到串口)

2. 那么就是eth_type_is_arp_and_my_ip 函數返回為0了;

但是ping命令還是可以得到響應的,哦,對了,還有ICMP(我本來就用的ping,都忘了,放在IP層),那么就好解釋了,第一次是由ARP+ICMP響應,第二次及之后的只有ICMP響應。所以現象還是符合原理解釋的。

但是,我用網頁去刷新和點亮LED等,走的肯定是IP包,ARP還是不響應。

回去看代碼,當時對自己就無語了

if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V)

是ARP啊,我以為是對IP和ARP都會響應,而且人家的函數名是eth_type_is_arp_and_my_ip ,我自己把它想成eth_type_is_arp_and_ip ,╮(╯▽╰)╭

代碼就在那里,自己SB了~~~

--------------------------------------------以上是我邊想邊實驗邊寫的過程-----------------------------------------------

硬件環境:STM32+ENC28J60

軟件環境:MDK4.70a

TCP/IP協議棧:開發者的網站已經關閉了,也沒有命名~~~

給出作者信息:

/*********************************************
 * modified: 2007-08-08
 * Author  : awake
 * Copyright: GPL V2
 * http://www.icdev.com.cn/?2213/
 * Host chip: ADUC7026
**********************************************/


關鍵字:TCP  IP協議棧  ARP  STM32平臺 引用地址:分析TCP/IP協議棧代碼之ARP(STM32平臺)

上一篇:分析TCP/IP協議棧代碼之UDP(STM32平臺)
下一篇:分析TCP/IP協議棧代碼之IP & ICMP(STM32平臺)

推薦閱讀

騰訊科技訊 據外媒報道,市場調研公司Canalys周四發布報告稱,中國智能手機市場第一季度的出貨量同比下滑了21%,降至9100萬部,創出單季最大跌幅。Canalys在報告中稱,在中國市場的10大智能手機制造商當中,只有華為和小米兩家公司第一季度的出貨量出現上漲;金立、魅族和三星電子出貨量跌幅均超過50%。Canalys稱,華為第一季度繼續成為中國智能手機市場...
全球電源管理與散熱解決方案的提供商臺達,近期在西班牙馬德里為國際IT服務供應商Atos完成了不間斷電源(UPS)系統的安裝計劃。臺達推薦采用的Modulon DPH系列模塊化UPS,是一款久經市場考驗的明星產品,已在國內外屢獲獎項,包括俄羅斯國際貿易部能源局“節能獎”(Save Energy!)評選的“年度技術”獎,IT168網“年度產品獎”等,其卓越的性能表現已得到...
(文章來源:教育新聞網) 加利福尼亞大學圣地亞哥分校的工程師開發了一種不需要任何特殊設備的新方法,并且只需幾分鐘即可創建出柔軟,靈活,的機器人。 創新來自于對軟機器人的構建方式的重新思考:加州大學圣地亞哥分校的研究人員從不考慮如何將軟材料添加到剛性機器人主體中,而是從軟主體入手,并在關鍵組件中添加了剛性特征。這些結構的靈感來自...
Poly博詣的揚聲器和個人視頻一體機憑借卓越設計和出色功能獲得兩項全球知名設計獎項4月28日,中國北京–近日,全球領先統一通信和協作公司Poly博詣宣布旗下個人視頻一體機和智能揚聲器榮獲兩項全球知名獎項——2021年紅點獎和iF設計獎,彰顯出Poly博詣所擁有的卓越設計和強大的科技實力。 Poly Studio P15個人視頻一體機和Poly Sync系列智能揚聲器榮獲...

史海拾趣

小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 昌都县| 新泰市| 丰顺县| 额济纳旗| 昌江| 西贡区| 达孜县| 宁波市| 江口县| 旬阳县| 芷江| 东丽区| 慈溪市| 清苑县| 丹东市| 句容市| 盘锦市| 静乐县| 星座| 塔城市| 达日县| 道孚县| 丰顺县| 繁峙县| 盐亭县| 清丰县| 孙吴县| 沿河| 天柱县| 正阳县| 武邑县| 会宁县| 甘肃省| 闽清县| 新乐市| 天全县| 平潭县| 兴文县| 白沙| 长岭县| 日土县|