日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux ping的原理与实现

發布時間:2023/12/15 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux ping的原理与实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. ping過程:

我們以下面一個網絡為例:有A、B、C、D四臺機子,一臺路由RA,子網掩碼均為255.255.255.0,默認網關為192.168.0.1

1、在同一網段內

在主機A上運行“Ping 192.168.0.5”后,都發生了些什么呢? 首先,Ping命令會構建一個固定格式的ICMP請求數據包,然后由ICMP協議將這個數據包連同地址“192.168.0.5”一起交給IP層協議(和ICMP一樣,實際上是一組后臺運行的進程),IP層協議將以地址“192.168.0.5”作為目的地址,本機IP地址作為源地址,加上一些其他的控制信息,構建一個IP數據包,并想辦法得到192.168.0.5的MAC地址(物理地址,這是數據鏈路層協議構建數據鏈路層的傳輸單元——幀所必需的),以便交給數據鏈路層構建一個數據幀。關鍵就在這里,IP層協議通過機器B的IP地址和自己的子網掩碼,發現它跟自己屬同一網絡,就直接在本網絡內查找這臺機器的MAC,如果以前兩機有過通信,在A機的ARP緩存表應該有B機IP與其MAC的映射關系,如果沒有,就發一個ARP請求廣播,得到B機的MAC,一并交給數據鏈路層。后者構建一個數據幀,目的地址是IP層傳過來的物理地址,源地址則是本機的物理地址,還要附加上一些控制信息,依據以太網的介質訪問規則,將它們傳送出去。

主機B收到這個數據幀后,先檢查它的目的地址,并和本機的物理地址對比,如符合,則接收;否則丟棄。接收后檢查該數據幀,將IP數據包從幀中提取出來,交給本機的IP層協議。同樣,IP層檢查后,將有用的信息提取后交給ICMP協議,后者處理后,馬上構建一個ICMP應答包,發送給主機A,其過程和主機A發送ICMP請求包到主機B一模一樣。

2、不在同一網段內

在主機A上運行“Ping 192.168.1.4”后,開始跟上面一樣,到了怎樣得到MAC地址時,IP協議通過計算發現D機與自己不在同一網段內,就直接將交由路由處理,也就是將路由的MAC取過來,至于怎樣得到路由的MAC,跟上面一樣,先在ARP緩存表找,找不到就廣播。路由得到這個數據幀后,再跟主機D進行聯系,如果找不到,就向主機A返回一個超時的信息。

?

2. iputils軟件包:

執行ping -V:

baoli@ubuntu:~$ ping -V

ping utility, iputils-s20161105

可知ping命令屬于iputils軟件包,參考: iputils軟件包

?

ping過程中會涉及兩種協議:

  • ICMP

  • ARP:查找MAC地址

?

ping報文格式:

MAC + IP + ICMP

?

iputils中ping相關文件:

  • ping.c

  • ping6.c

  • ping_common.c

?

3. ping代碼實現流程:

1. 首先創建raw socket:icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

2. 處理命令行選項

3. 如果沒有指定源IP(網絡接口),需要 創建probe_fd = socket(AF_INET, SOCK_DGRAM, 0),然后通過getsockname()找到源地址。

4. 通過setsockopt()設置各種選項

5.?bind:bind(icmp_sock, (struct sockaddr*)&source, sizeof(source))

6. 發送icmp報文:pinger(),在send_probe()中先構造struct icmphdr *icp,然后通過sendmsg發送出去。

7. 接收ICMP消息:recvmsg(icmp_sock, &msg, polling),再通過parse_reply()解析消息。

8. 已達指定次數、ctrl+c等退出處理。其中ctrl+c利用Linux?signal實現。

????set_signal(SIGINT, sigexit);

????set_signal(SIGALRM, sigexit);

????set_signal(SIGQUIT, sigstatus);

?

總結

以上是生活随笔為你收集整理的Linux ping的原理与实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。