物理连接,物理标识,网络标识,端口标识,数据标识
星形联结,mac地址,ip地址,服务端口,数据协议
===dns请求为例
应用层构造DNS包,告诉udp层数据目的8.8.8.8的端口53
udp层构造udp包,数据就是dns包内容,目的端口,源端口,告诉ip层
ip收到请求后,查询路由表,不在一个子网,找到默认网关,得到源ip,网关ip,构造ip包
arp构造mac地址,获取网关对应mac
链路层构造以太网包,填写网关mac和目的地址,原地址和源ip
路由器收到数据包,根据目的地址,不再一个子网,查询路由表,发送到下一个网关
直到最后一个路由器,发现目的地址在一个子网,通过网卡发送
目的地址收到dns包,根据端口,发送给目的进程进行处理
应用层构造应答包,返回请求
===ip转发与链路转发
1,路由表小很多,差不多万条级别,ip范围和生活中地址一样,不怎么变化
2,ip在整个网络拓扑位置不会变化,变化的是设备位置
3,ip不携带个人信息,需要mac完成动态分配和解决冲突
二层转发
主机根据ip地址判断是否在一个网段,一个网段去查询并更新本地arp表
arp请求和回复,更新并老化了交换机的FDB表(FordWarding DateBase):
即MAC地址映射表,有MAC地址、端口、VLAN ID等信息
三层转发
交换机接收包时发现目的IP与源IP不在同一个网段,提交到三层,
路由表:包含默认路由、RIP等动态路由的路由路径信息的记录表。
路由表中有记录进行硬件转发,与或非数字电路,否则进行软件路由转发
数据包缓存于cpu的内存中,实现数据包的循径,转发的
转发过程中,ip不变,修改mac
===数据接收
接收: 数据包从网卡接收,驱动判断目的地址匹配,非混杂模式直接丢弃
存储: dma方式放到内存
通知cpu: 硬件中断irq通知cpu
中断处理: cpu根据中断表,调用驱动程序相应函数,禁用中断,启动软中断,返回
数据处理: ksoftirqd调用数据包处理函数,将内存数据包转换skb格式,交给协议栈处理
poll处理完后,启用网卡的硬件中断。
协议栈: 协议是通信规则,协议栈是层级结构,协议总和,代码实现的库函数
ip层:根据mac,ip判断是丢弃并处理,转发ip-forward,还是直接处理给udp
udp层:根据ip和端口找到服务socket,并判断该socket上的filter,没有则丢弃
将数据包放入socket接收队列的末尾,通知socket数据包已经准备好
应用层:socket根据阻塞或者select,epoll方式读取队列数据
===数据发送
创建socket 初始化socket相应的函数和udp相关函数,分配源端口,sendto发给udp层
协议栈 udp层:构造skb,分配源ip,路由表找到目的地址,初始化ip包头,分片
IP层:设置IP报文头的长度和checksum,snat更新路由信息,获取下一跳mac
填写到skb中,调用dev_queue_xmit
netdevice:过滤和优先级处理,tcpdump的copy,具体驱动ndo_start_xmit
driver:skb到队列,通知网卡发送,完成中断给cpu,skb清理
===netfliter和iptables
netfilter在协议栈中添加了5个钩子
iptables是用户空间的一个程序,通过netlink和内核的netfilter框架打交道,配置回调
hook:
1,接收 NF_IP_PRE_ROUTING
2,进入本地 NF_IP_LOCAL_IN
3,forward NF_IP_FORWARD
4,发送到ip层 NF_IP_LOCAL_OUT
5,下层发送 NF_IP_POST_ROUTING
一个数据包只会经过下面三个路径中的一个:
本机收到目的IP是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_LOCAL_IN
本机收到目的IP不是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_FORWARD -> NF_IP_POST_ROUTING
本机发出去的数据包: NF_IP_LOCAL_OUT -> NF_IP_POST_ROUTING
iptables用表(table)来分类管理它的规则(rule),根据rule的作用分成了好几个表,
比如用来过滤数据包的rule就会放到filter表中,用于处理地址转换的rule就会放到nat表中,
其中rule就是应用在netfilter钩子上的函数,用来修改数据包的内容或过滤数据包
iptables里面有5个内置的chains,分别对应5个钩子:
PREROUTING: 数据包经过NF_IP_PRE_ROUTING时会触发该chain上的rule
INPUT: 数据包经过NF_IP_LOCAL_IN时会触发该chain上的rule
FORWARD: 数据包经过NF_IP_FORWARD时会触发该chain上的rule
OUTPUT: 数据包经过NF_IP_LOCAL_OUT时会触发该chain上的rule
POSTROUTING: 数据包经过NF_IP_POST_ROUTING时会触发该chain上的rule