2025年2.Ether协议分析与实践

2.Ether协议分析与实践2 Ether 协议分析与实践 1 概述 1 1 简介 以太网是当前应用最普遍的局域网技术 取代了其他局域网标准如令牌环 FDDI 和 ARCNET 以太网提供基于数据报 全双工 不可靠的通讯协议 1 2 常见以太网类型 速度 常用名称 IEEE 标准名称 线缆类型 最大传输距离 10Mbps 以太网 802 3 双绞线 100m 100Mbps

大家好,我是讯享网,很高兴认识大家。

2. Ether 协议分析与实践

1. 概述

1.1 简介

  • 以太网是当前应用最普遍的局域网技术,取代了其他局域网标准如令牌环、FDDI和ARCNET
  • 以太网提供基于数据报、全双工、不可靠的通讯协议

1.2 常见以太网类型

速度 常用名称 IEEE标准名称 线缆类型 最大传输距离
10Mbps 以太网 802.3 双绞线 100m
100Mbps 快速以太网 802.3u 双绞线 100m
1Gbps 吉比特以太网 802.3z 光纤 5000m
1Gbps 吉比特以太网 802.3ab 双绞线 100m
10Gbps 10吉比特以太网 802.3an 双绞线 100m

1.3 以太帧数据格式

  • 以太网中 MTU 为 1500 字节, 而 Internet 中默认 MTU 为 576 字节

    讯享网
  • 双方都可以给对方发信息(全双工),所以必须有双方的地址(目的 MAC 地址和源 MAC 地址)
  • 为了提高信道的利用率,还需要通过一个字段来区分不同的通信(多路复用),如 0x0800(IP)、0x0806(ARP) 、0x80dd(IPv6)等。比如说,打电话时,信道基本上都是空闲的,绝大部分时间都是在等待人说话,人说话的速度,相对于传输速度来说,太慢了,非常浪费资源!所以我们完全可以在同一时间,收邮件、看新闻等,类型字段就是为了区分不同的通信
# 开启网卡混杂模式, 网卡默认会丢弃目的地址与自己不符的数据帧 shell> sudo ip link set eth0 promisc on # off 表示关闭 shell> ip link show eth0 # 查看开启结果, 是否包含 promisc 2: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:0c:0c:0c:0c brd ff:ff:ff:ff:ff:ff # 查看和修改 MTU cat /sys/class/net/eth0/mtu echo 1460 | sudo tee /sys/class/net/eth0/mtu # 路径 MTU ping -s 1461 -M do baidu.com ping: local error: Message too long, mtu=1460 

讯享网

2. 以太网编程

2.1 eth.h

讯享网shell> cat eth.h #ifndef __eth_h___ #define __eth_h___ #define ETH_ALEN 6 /* Octets in one ethernet addr */ #define ETH_TLEN 2 /* Octets in ethernet type field */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */ #define ETH_MAX_MTU 0xFFFFU /* 65535, same as IP_MAX_MTU */ #define ETH_PROTO_ARP 0x0806 /* ARP 协议 */ #define ETH_PROTO_IP 0x0800 /* IP 协议 */ struct eth_frame { 
    unsigned char dest_addr[ETH_ALEN]; /* destination eth addr */ unsigned char src_addr[ETH_ALEN]; /* source ether addr */ unsigned short proto; /* packet type ID field */ unsigned char payload[0]; /* data */ // unsigned char crc[4]; /* checksum */ } __attribute__((packed)); struct eth_frame* eth_alloc_frame(const char *dest_mac, const char *src_mac, unsigned short proto, const void *data, const size_t lenght); void eth_free_packet(struct eth_frame **frame); int eth_socket(const char *iface); ssize_t eth_send(int sockfd, struct eth_frame *frame, size_t size, int flags); ssize_t eth_recv(int sockfd, void *buffer, size_t size, int flags); void eth_close(int sockfd); #endif /* __eth_h___ */ 

2.2 eth.c

shell> cat eth.c #include <stdlib.h> #include <unistd.h> #include <string.h> #include <net/if.h> // for if_nametoindex #include <arpa/inet.h> // for htons #include <sys/types.h> #include <sys/socket.h> #include <netinet/ether.h> // for ether_aton #include <linux/if_packet.h> #include "eth.h" #include "common.h" struct eth_frame* eth_alloc_frame(const char *dest_mac, const char *src_mac, unsigned short proto, const void *data, const size_t size) { 
    struct ether_addr *addr; struct eth_frame *frame; frame = (struct eth_frame*)calloc(1, sizeof(struct eth_frame) + size); addr = ether_aton(dest_mac); // 将 mac 地址转换为网络字节序 memcpy(frame->dest_addr, addr->ether_addr_octet, sizeof(addr->ether_addr_octet)); addr = ether_aton(src_mac); // 将 mac 地址转换为网络字节序 memcpy(frame->src_addr, addr->ether_addr_octet, sizeof(addr->ether_addr_octet)); frame->proto = htons(proto); // 转换为网络字节序 memcpy(frame->payload, data, size); return frame; } void eth_free_packet(struct eth_frame **frame) { 
    if (NULL != frame && NULL != *frame) { 
    free(*frame); *frame = NULL; } } int eth_socket(const char *iface) { 
    int sockfd; struct sockaddr_ll sll; // create raw socket if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) handle_error("socket"); // config socket  memset(&sll, 0, sizeof(struct sockaddr_ll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = if_nametoindex(iface); // 绑定哪块网卡 // bind interface if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) == -1) handle_error("bind"); return sockfd; } ssize_t eth_send(int sockfd, struct eth_frame *frame, size_t size, int flags) { 
    ssize_t count; if ((count = send(sockfd, frame, size, flags)) == -1) handle_error("send"); return count; } ssize_t eth_recv(int sockfd, void *buffer, size_t size, int flags) { 
    ssize_t count; if ((count = recv(sockfd, frame, size, flags)) == -1) handle_error("recv"); return count; } void eth_close(int sockfd) { 
    if (close(sockfd) == -1) handle_error("close"); } 

2.3 main.c

讯享网shell> cat main.c #include <stdio.h> #include <string.h> #include "eth.h" #define ARP_PROTO 0x0806 #define SRC_IP "192.168.2.100" /* 本机 IP */ #define SRC_MAC "00:0C:0C:0C:0C:0C" /* 本机 MAC */ #define DEST_MAC "FF:FF:FF:FF:FF:FF" /* 广播地址 */ static void test_eth(const char *dest_mac, const char *src_mac, unsigned short proto, const void *data, size_t size) { 
    int sockfd; struct eth_frame *frame; sockfd = eth_socket("eth0"); // 使用 eth0 网卡 frame = eth_alloc_frame(dest_mac, src_mac, proto, data, size); eth_send(sockfd, frame, sizeof(struct eth_frame) + size, 0); eth_free_packet(&frame); eth_close(sockfd); } int main(int argc, char *argv[]) { 
    const char *data = "aaaaaaaaaaaaaaaaaaaaa"; test_eth(DEST_MAC, SRC_MAC, ARP_PROTO, data, strlen(data)); return 0; } 
192.168.1.200> sudo tcpdump -nt -i eth0 -XX arp 0x0000: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa 0x0010: 6161 6161 6100 0000 0000 0000 0000 0000 aaaaa........... 0x0020: 0000 0000 0000 0000 0000 0000 0000 .............. 0x0000: ffff ffff ffff 000c 0c0c 0c0c 0806 6161 ..............aa 0x0010: 6161 6161 6161 6161 6161 6161 6161 6161 aaaaaaaaaaaaaaaa 0x0020: 6161 6100 0000 0000 0000 0000 0000 0000 aaa............. 0x0030: 0000 0000 0000 0000 0000 0000 ............ 192.168.1.100> make run 

3. 以太网攻击

3.1 以太网泛洪

  • 利用交换机的自动学习 mac 地址机制,通过发送大量无效以太网包给交换机学习,造成交换机 mac 地址表爆表,因为存放 mac 表的存储介质容量有限
  • 当 mac 地址表爆掉之后,交换机不能再学习新的 mac 地址,转发数据只能像集线器广播给所有接口
讯享网# 泛洪交换机 192.168.2.100> sudo macof -i eth0 74:3c:ad:76:25:f7 66:8a:79:31:dd:6c 0.0.0.0.61458 > 0.0.0.0.33095: S :(0) win 512 1:1c:2:6a:eb:9b 92:e3:a0:5e:b9:74 0.0.0.0.28555 > 0.0.0.0.62737: S :(0) win 512 f4:e5:86:33:a0:14 e6:6e:15:70:73:bb 0.0.0.0.22104 > 0.0.0.0.34019: S :(0) win 512 # 查看交换机 mac 表 192.168.2.3> sudo brctl showmacs br0 port no mac addr is local? ageing timer 1 00:0b:0b:0b:0b:0b yes 0.00 1 00:0b:0b:0b:0b:0b yes 0.00 1 00:0c:0c:0c:0c:0c no 38.39 1 00:50:56:c0:00:01 no 6.30 1 74:3c:ad:76:25:f7 no 5.59 1 f4:e5:86:33:a0:14 no 5.59 ............. # 监听 200 主机的数据,网卡必须开启混杂模式 192.168.2.100> sudo tcpdum -nt -X 'host 192.168.2.200' # 200 访问 ftp 服务器 192.168.2.200> ftp 8.8.8.8 21 
参考链接

http://www.networksorcery.com/enp/protocol/IEEE8023.htm

https://zh.wikipedia.org/wiki/%E4%BB%A5%E5%A4%AA%E7%BD%91

https://linux-network-programming.readthedocs.io/zh_CN/latest/protocols/data-link-layer.html

小讯
上一篇 2025-02-11 12:01
下一篇 2025-03-02 16:53

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/21997.html