網站首頁 編程語言 正文
OSI第2層
前兩個字段分別是目的地址和源地址字段。第3個字段是2字節的類型字段,用來標識上一層是什么協議。
數據鏈路層有兩個子層:邏輯鏈路控制 (LLC) 子層和媒體訪問控制 (MAC) 子層。
媒體訪問控制 (MAC):MAC 子層處理硬件標識號的分配,稱為 MAC 地址,它唯一地標識網絡上的每個設備。 任何兩個設備都不應具有相同的 MAC 地址。 MAC 地址是在制造時分配的。 大多數網絡都會自動識別它。 MAC 地址位于網卡 上。
交換機跟蹤網絡上的所有 MAC 地址。
邏輯鏈路控制 (LLC):LLC 子層處理成幀尋址和流量控制。 速度取決于節點之間的鏈接,例如以太網或 Wifi。
第 2 層上的數據單元是一個幀。每個幀都包含一個幀頭、正文和一個幀尾:
Header:通常包括源節點和目標節點的 MAC 地址。
Body:由正在傳輸的位組成。
Trailer:包括錯誤檢測信息。 當檢測到錯誤時,根據網絡或協議的實現或配置,幀可能會被丟棄,或者可能會將錯誤報告給更高層以進行進一步的糾錯。
error detection mechanisms::循環冗余校驗 (CRC) 和幀校驗序列 (FCS)。
通常有一個最大幀大小限制,稱為最大傳輸單元,MTU。 巨型幀超過標準 MTU.
通過ARP解析出目標 MAC 地址?
傳統交換在 OSI 模型的第 2 層運行,其中數據包根據目標 MAC 地址發送到特定的交換機端口。第 2 層網段中的設備不需要路由即可到達本地對等點。 然而,需要的是可以通過地址解析協議 (ARP) 解析的目標 MAC 地址,如下所示:
在這里,PC A 想要將流量發送到 IP 地址為 192.168.1.6 的 PC B。 然而,它不知道唯一的 MAC 地址,直到它通過 ARP 發現它,該 ARP 在整個第 2 層網段中廣播。
然后將數據包發送到適當的目標 MAC 地址,交換機將根據其 MAC 地址表將正確的端口轉發出去。
什么是MAC地址表
MAC地址表是在交換機中記錄局域網主機和對應接口關系的表,交換機就是根據這張表負責將數據幀傳輸到指定的主機上的。
MAC地址表可以動態的學習數據幀中的原MAC地址。在MAC地址表中,交換機的一個接口可以對應多個MAC地址。一個MAC地址只能對應在一個接口上。下面是MAC地址表形成的具體過程,如下:
二層轉發C/C++代碼實現
cethping:
void ethping(char *destination, char* interface){
//創建原始套接字。 指定接口名稱
struct RawSocket* rawsocket = new_RawSocket(interface);
//數據包數據緩沖區
unsigned char buf[1024];
//定義數據包。 投射以匹配以太網幀的格式
struct ethhdr_frame* eth_packet = (struct ethhdr_frame*)buf;
//存儲發送方和接收方的 MAC 地址。 協議類型是可選的,并且指定了 0x0806。
//根據指定的接口名稱獲取發送者的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){
//創建原始套接字(指定接收器接口名稱)
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);
//顯示接收到的數據包的內容
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;
}
編譯:
增加兩個虛擬網卡:
運行:
總結
轉發是將連接到網絡交換機一個端口的設備的網絡流量傳遞到連接到交換機上另一個端口的另一個設備的過程。
當第 2 層以太網幀到達網絡交換機上的端口時,交換機會讀取以太網幀的源 MAC 地址作為學習功能的一部分,它還會讀取目標 MAC 地址作為轉發功能的一部分。目標 MAC 地址對于確定連接目標設備的端口號很重要。如果在 MAC 地址表中找到目的 MAC 地址,則交換機通過 MAC 地址對應的端口轉發以太網幀。
參考:
《TCP IP詳解卷一》
原文鏈接:https://blog.csdn.net/chen1415886044/article/details/124853000
相關推薦
- 2022-06-21 Android?Studio實現登錄界面功能_Android
- 2022-10-19 Android?webview加載H5方法詳細介紹_Android
- 2022-06-19 python繪制橫向水平柱狀條形圖_python
- 2023-01-15 React報錯Too?many?re-renders解決_React
- 2022-05-12 van-checkbox 全選,解決單個點擊后會取消全部的問題
- 2022-11-25 Docker?制作tomcat鏡像并部署項目的步驟_docker
- 2022-08-15 利用judge-width屬性實現Vcharts圖表自適應
- 2022-09-18 K8s實戰教程之容器和?Pods資源分配問題_云其它
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支