網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
OSI第2層
前兩個(gè)字段分別是目的地址和源地址字段。第3個(gè)字段是2字節(jié)的類型字段,用來(lái)標(biāo)識(shí)上一層是什么協(xié)議。
數(shù)據(jù)鏈路層有兩個(gè)子層:邏輯鏈路控制 (LLC) 子層和媒體訪問(wèn)控制 (MAC) 子層。
媒體訪問(wèn)控制 (MAC):MAC 子層處理硬件標(biāo)識(shí)號(hào)的分配,稱為 MAC 地址,它唯一地標(biāo)識(shí)網(wǎng)絡(luò)上的每個(gè)設(shè)備。 任何兩個(gè)設(shè)備都不應(yīng)具有相同的 MAC 地址。 MAC 地址是在制造時(shí)分配的。 大多數(shù)網(wǎng)絡(luò)都會(huì)自動(dòng)識(shí)別它。 MAC 地址位于網(wǎng)卡 上。
交換機(jī)跟蹤網(wǎng)絡(luò)上的所有 MAC 地址。
邏輯鏈路控制 (LLC):LLC 子層處理成幀尋址和流量控制。 速度取決于節(jié)點(diǎn)之間的鏈接,例如以太網(wǎng)或 Wifi。
第 2 層上的數(shù)據(jù)單元是一個(gè)幀。每個(gè)幀都包含一個(gè)幀頭、正文和一個(gè)幀尾:
Header:通常包括源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)的 MAC 地址。
Body:由正在傳輸?shù)奈唤M成。
Trailer:包括錯(cuò)誤檢測(cè)信息。 當(dāng)檢測(cè)到錯(cuò)誤時(shí),根據(jù)網(wǎng)絡(luò)或協(xié)議的實(shí)現(xiàn)或配置,幀可能會(huì)被丟棄,或者可能會(huì)將錯(cuò)誤報(bào)告給更高層以進(jìn)行進(jìn)一步的糾錯(cuò)。
error detection mechanisms::循環(huán)冗余校驗(yàn) (CRC) 和幀校驗(yàn)序列 (FCS)。
通常有一個(gè)最大幀大小限制,稱為最大傳輸單元,MTU。 巨型幀超過(guò)標(biāo)準(zhǔn) MTU.
通過(guò)ARP解析出目標(biāo) MAC 地址?
傳統(tǒng)交換在 OSI 模型的第 2 層運(yùn)行,其中數(shù)據(jù)包根據(jù)目標(biāo) MAC 地址發(fā)送到特定的交換機(jī)端口。第 2 層網(wǎng)段中的設(shè)備不需要路由即可到達(dá)本地對(duì)等點(diǎn)。 然而,需要的是可以通過(guò)地址解析協(xié)議 (ARP) 解析的目標(biāo) MAC 地址,如下所示:
在這里,PC A 想要將流量發(fā)送到 IP 地址為 192.168.1.6 的 PC B。 然而,它不知道唯一的 MAC 地址,直到它通過(guò) ARP 發(fā)現(xiàn)它,該 ARP 在整個(gè)第 2 層網(wǎng)段中廣播。
然后將數(shù)據(jù)包發(fā)送到適當(dāng)?shù)哪繕?biāo) MAC 地址,交換機(jī)將根據(jù)其 MAC 地址表將正確的端口轉(zhuǎn)發(fā)出去。
什么是MAC地址表
MAC地址表是在交換機(jī)中記錄局域網(wǎng)主機(jī)和對(duì)應(yīng)接口關(guān)系的表,交換機(jī)就是根據(jù)這張表負(fù)責(zé)將數(shù)據(jù)幀傳輸?shù)街付ǖ闹鳈C(jī)上的。
MAC地址表可以動(dòng)態(tài)的學(xué)習(xí)數(shù)據(jù)幀中的原MAC地址。在MAC地址表中,交換機(jī)的一個(gè)接口可以對(duì)應(yīng)多個(gè)MAC地址。一個(gè)MAC地址只能對(duì)應(yīng)在一個(gè)接口上。下面是MAC地址表形成的具體過(guò)程,如下:
二層轉(zhuǎn)發(fā)C/C++代碼實(shí)現(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;
//存儲(chǔ)發(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中設(shè)置字符串“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);
//關(guān)閉原始套接字
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;
}
編譯:
增加兩個(gè)虛擬網(wǎng)卡:
運(yùn)行:
總結(jié)
轉(zhuǎn)發(fā)是將連接到網(wǎng)絡(luò)交換機(jī)一個(gè)端口的設(shè)備的網(wǎng)絡(luò)流量傳遞到連接到交換機(jī)上另一個(gè)端口的另一個(gè)設(shè)備的過(guò)程。
當(dāng)?shù)?2 層以太網(wǎng)幀到達(dá)網(wǎng)絡(luò)交換機(jī)上的端口時(shí),交換機(jī)會(huì)讀取以太網(wǎng)幀的源 MAC 地址作為學(xué)習(xí)功能的一部分,它還會(huì)讀取目標(biāo) MAC 地址作為轉(zhuǎn)發(fā)功能的一部分。目標(biāo) MAC 地址對(duì)于確定連接目標(biāo)設(shè)備的端口號(hào)很重要。如果在 MAC 地址表中找到目的 MAC 地址,則交換機(jī)通過(guò) MAC 地址對(duì)應(yīng)的端口轉(zhuǎn)發(fā)以太網(wǎng)幀。
參考:
《TCP IP詳解卷一》
原文鏈接:https://blog.csdn.net/chen1415886044/article/details/124853000
相關(guān)推薦
- 2022-11-19 Kotlin協(xié)程之Flow異常示例處理_Android
- 2022-10-15 C#集合本質(zhì)之隊(duì)列的用法詳解_C#教程
- 2022-03-31 Python機(jī)器學(xué)習(xí)應(yīng)用之基于線性判別模型的分類篇詳解_python
- 2022-06-17 Go模板template用法詳解_Golang
- 2022-06-22 Android用SharedPreferences實(shí)現(xiàn)登錄注冊(cè)注銷功能_Android
- 2022-08-10 .Net使用Cancellation?Framework取消并行任務(wù)_實(shí)用技巧
- 2022-07-03 python使用pandas讀xlsx文件的實(shí)現(xiàn)_python
- 2022-06-22 C++深入探究類與對(duì)象之對(duì)象模型與this指針使用方法_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支