Linux2.6 netfilter编程过程中,TCP端口错误!关键代码如下!希望解答详细!

Linux2.6 netfilter编程过程中,TCP端口错误!关键代码如下!希望解答详细!,第1张

嵌入式linux,linux系统编程要去做网络安全防火墙开发,是不是两个不同的方向?都研二了,有必要去学习网络安全的netfilter/iptables等东西吗?这个对网络编程提高有很大的用处没?

你正好是做这方面的,麻烦都我回答一下,谢谢!

————————————————

版权:本文转自cnblogs 刘超的通俗云计算

四、内核态网络包处理

Openvswitch的内核模块openvswitchko会在网卡上注册一个函数netdev_frame_hook,每当有网络包到达网卡的时候,这个函数就会被调用。

函数int ovs_vport_receive(struct vport vport, struct sk_buff skb, const struct ip_tunnel_info tun_info)实现如下

在 ovs_vport_receive() 这个函数里面,首先声明了变量 struct sw_flow_key key;

如果我们看这个key的定义,可见这个key里面是一个大杂烩,数据包里面的几乎任何部分都可以作为key来查找flow表:

可见这个key里面是一个大杂烩,数据包里面的几乎任何部分都可以作为key来查找flow表

所以,要在内核态匹配流表,首先需要调用 ovs_flow_key_extract ,从包的正文中提取key的值。

接下来

函数 ovs_dp_process_packet() 首先在内核里面的流表中查找符合key的flow,也即ovs_flow_tbl_lookup_stats,如果找到了,很好说明用户态的流表已经放入内核,则走fast path就可了。于是直接调用ovs_execute_actions,执行这个key对应的action。

如果不能找到,则只好调用ovs_dp_upcall,让用户态去查找流表。会调用static int queue_userspace_packet(struct datapath dp, struct sk_buff skb, const struct sw_flow_key key, const struct dp_upcall_info upcall_info)

它会调用err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);通过netlink将消息发送给用户态。在用户态,有线程监听消息,一旦有消息,则触发udpif_upcall_handler。

也就是说OVS处理数据包首先会看有没有事先订阅的事件,如果有直接转交给该对应的处理函数,然后匹配流表,最后按照传统网络协议栈进行处理。

————————————————

版权:本文转自cnblogs 刘超的通俗云计算

原文链接: >

int (hard_start_xmit)( struct sk_buff skb, struct net_device dev ); skb是待发送的数据缓冲区,dev是该网络设备接口本身的一个指针。环回设备接口由于是把数据报发给本机,所以其发送数据报函数比较特殊,它把skb稍加处理后,又转回给协议栈的数据报接收函数netif_rx。其发送函数的函数名是loopback_xmit。首先,loopback_xmit调用skb_orphan把skb孤立,使它跟发送socket和协议栈不再有任何联系,也即对本机来说,这个skb的数据内容已经发送出去了,而skb相当于已经被释放掉了。skb_orphan所做的实际事情是,首先从skb->sk(发送这个skb的那个socket)的sk_wmem_alloc减去skb->truesize,也即从socket的已提交发送队列的字节数中减去这个skb,表示这个skb已经发送出去了,同时,如果有进程在这个socket上写等待,则唤醒这些进程继续发送数据报,然后把socket的引用计数减1,最后,令sk->destructor和skb->sk都为NULL,使skb完全孤立。实际上,对于环回设备接口来说,数据的发送工作至此已经全部完成,接下来,只要把这个实际上还未被释放的skb传回给协议栈的接收函数即可。 在传回去之前,还需要做一些工作,因为协议栈在发送数据报时,为数据报打以太网首部时,skb->data是指向以太网首部的开始位置的,网络设备接口传回的数据报是需要已经剥离了以太网首部的,所以令skb->data加上ETH_HLEN(14),令skb->macraw指向原来data的位置,即以太网首部。然后,需要确定skb->pkt_type的值,即该数据报的类型,如果以太网首部中的目的mac地址是个组播或广播地址,则skb->pkt_type为PACKET_BROADCAST或PACKET_MULTICAST,关于MAC地址类型的判断方法以后再详细分析。否则,如果目的mac地址不等于本接口设备的mac地址,则skb->pkt_type为PACKET_OTHERHOST,否则就为默认值PACKET_HOST。最后,设置skb->protocol(ETH_P_IP,ETH_P_ARP或其它),设置skb->dev,再更新一下统计值,把skb交回给协议协栈即可。struct net_device还有一些跟协议栈的处理流程关系比较密切的成员函数,下面一一介绍。hard_header,该成员被以太网设备驱动程序用于为每一个待发送数据报构建以太网首部,系统中所有以太网设备驱动程序共享一个函数即eth_header。所有数据报在传递给该函数之前,其skb头部预留了以太网首部的空间,data成员指向网络层首部,eth_header将data成员指向以太网首部,并为以太网首部填入目的以太网地址,源以太网地址和网络层协议类型(ETH_P_IP或ETH_P_ARP),该函数在协议栈中主要有两处被用到,一是ARP模块中,发送ARP请求或应答前,构建以太网首部用;另一处是在IP数据发送过程中,构建以太网首部用。hard_header_cache,用于创建以太网首部的高速缓冲,每一个邻居节点都有一个struct hh_cache hh成员,用于缓冲该邻居节点的以太网首部,有了这个缓冲,以后再向这个邻居发数IP数据的时候,不必再调用hard_header构建以太网首部,而是直接从hh中拷贝即可。

转发数据包主要包括一下步骤:

l  处理 IP 头选项。如果需要的话,会记录本地 IP 地址和时间戳;

l  确认分组可以被转发;

l  将 TTL 减一,如果 TTL 为 0 ,则丢弃分组;

l  根据 MTU 大小和路由信息,对数据分组进行分片,如果需要的话;

l  将数据分组送往外出设备。

如果由于某种原因,数据分组不能被转发,那么就回应 ICMP 消息来说明不能转发的原因。在对转发的分组进行各种检查无误后,执行 ip_forward_finish ,准备发送。然后执行 dst_output(skb) 。无论是转发的分组,还是本地产生的分组,都要经过 dst_output(skb) 到达目的主机。 IP 头在此时已经完成就绪。dst_output(skb) 函数要执行虚函数 output (单播的话为 ip_output ,多播为 ip_mc_output )。最后,ip_finish_output 进入邻居子系统。

下图是转发数据包的流程图:

241 本地处理

int ip_local_deliver(struct sk_buff skb)

{

if (skb->nhiph->frag_off & htons(IP_MF|IP_OFFSET)) {

skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);

if (!skb)

return 0;

}

return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,

ip_local_deliver_finish);

}

最后执行 ip_local_deliver_finish 。

以下属 ip_local_deliver_finish 函数流程图:

在 L4 协议中, TCP 和 UDP 是运行在内核空间的,而 RAW 则可以运行在用户空间中。

 

以上就是关于Linux2.6 netfilter编程过程中,TCP端口错误!关键代码如下!希望解答详细!全部的内容,包括:Linux2.6 netfilter编程过程中,TCP端口错误!关键代码如下!希望解答详细!、OVS流表精确匹配TCP/IP报头五元组、环回设备接口(loopback)上如何发送和接收数据报等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10134032.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存