suricata 3.1 源码分析27 (数据包IPv4解码)
来源:互联网 发布:linux延时函数头文件 编辑:程序博客网 时间:2024/04/29 06:44
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq){ StatsIncr(tv, dtv->counter_ipv4); SCLogDebug("pkt %p len %"PRIu16"", pkt, len); /* do the actual decoding */ if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {/* DecodeIPV4首先会调用完成实际解码的DecodeIPV4Packet函数,该函数流程为: 1. 若len小于IPV4_HEADER_LEN(20),则添加IPV4_PKT_TOO_SMALL事件。 2. 使用IP_GET_RAW_VER获取版本号,若不为4,则添加IPV4_WRONG_IP_VER事件。 3. 设置ip4h指针(IPV4Hdr *类型)。 4. 使用IPV4_GET_HLEN获取IP头长度,若不等于IPV4_HEADER_LEN,则也添加IPV4_HEADER_LEN事件。 5. 使用IPV4_GET_IPLEN获取IP数据包长度(IP头+IP负载),若小于IP头长度,则添加IPV4_IPLEN_SMALLER_THAN_HLEN事件。 6. 若len小于IP数据包长度,则添加IPV4_TRUNC_PKT事件,表示这是个被截断的包。 7. 设置Packet的src和dst,通过SET_IPV4_SRC_ADDR和SET_IPV4_DST_ADDR实现。 8. 若IPv4选项长度(hlen-20)不为0,则调用DecodeIPV4Options对其进行解码。*/ SCLogDebug("decoding IPv4 packet failed"); p->ip4h = NULL; return TM_ECODE_FAILED; } p->proto = IPV4_GET_IPPROTO(p);//调用IPV4_GET_IPPROTO获取下层协议,存储在Packet的proto中 /* If a fragment, pass off for re-assembly. */ if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) { Packet *rp = Defrag(tv, dtv, p, pq); if (rp != NULL) { PacketEnqueue(pq, rp); } p->flags |= PKT_IS_FRAGMENT; return TM_ECODE_OK;/*分片情况处理:若offset大于0或者MF标志为1,表示这是一个分片包,将会交给重组模块的Defrag函数去处理。若返回不为NULL,表示已经重组完成了,那么就递归调用DecodeIPV4重新进行IP层的解码,然后把这个新生成的重组包扔到pre队列中去。接着,给当前数据包打上PKT_IS_FRAGMENT标志,然后返回。*/ } /* do hdr test, process hdr rules */#ifdef DEBUG if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ /* debug print */ char s[16], d[16]; PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d)); SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu32 " DF: %" PRIu32 " MF: %" PRIu32 " ID: %" PRIu32 "", s,d, IPV4_GET_IPPROTO(p), IPV4_GET_IPOFFSET(p), IPV4_GET_RF(p), IPV4_GET_DF(p), IPV4_GET_MF(p), IPV4_GET_IPID(p)); }#endif /* DEBUG */ /* check what next decoder to invoke */ switch (IPV4_GET_IPPROTO(p)) { case IPPROTO_TCP: DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); break; case IPPROTO_UDP: DecodeUDP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); break; case IPPROTO_ICMP: DecodeICMPV4(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); break; case IPPROTO_GRE: DecodeGRE(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); break; case IPPROTO_SCTP: DecodeSCTP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); break; case IPPROTO_IPV6: { if (pq != NULL) { /* spawn off tunnel packet */ Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), DECODE_TUNNEL_IPV6, pq); if (tp != NULL) { PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4); PacketEnqueue(pq,tp); } } break; } case IPPROTO_IP: /* check PPP VJ uncompressed packets and decode tcp dummy */ if(p->ppph != NULL && ntohs(p->ppph->protocol) == PPP_VJ_UCOMP) { DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); } break; case IPPROTO_ICMPV6: ENGINE_SET_INVALID_EVENT(p, IPV4_WITH_ICMPV6); break; } return TM_ECODE_OK;}
0 0
- suricata 3.1 源码分析27 (数据包IPv4解码)
- suricata 3.1 源码分析24 (数据包解码模块执行)
- suricata 3.1 源码分析25 (数据包以太层解码)
- suricata 3.1 源码分析26 (数据包VLAN解码)
- suricata 3.1 源码分析28 (数据包TCP解码)
- suricata 3.1 源码分析23 (数据包解码模块注册及初始化)
- suricata 3.1 源码分析19 (数据包获取)
- suricata 3.1 源码分析20 (数据包封装)
- suricata 3.1 源码分析21 (数据包处理1)
- suricata 3.1 源码分析22 (数据包处理2)
- suricata 3.1 源码分析29 (数据包队列)
- suricata 3.2 源码分析(IP数据包分片重组流程)
- suricata 3.1 源码分析31 (RespondReject)
- suricata 3.1 源码分析1
- suricata 3.1 源码分析2
- suricata 3.1 源码分析3
- suricata 3.1 源码分析4
- suricata 3.1 源码分析5
- Spring的@RequestMapping注解类浅析
- 建立学生链表【链表】
- BZOJ3996: [TJOI2015]线性代数 解题报告
- 关于block使用的5点注意事项
- stringentity、urlEncodeFormEntity区别
- suricata 3.1 源码分析27 (数据包IPv4解码)
- MySql提示:The server quit without updating PID file(…)失败
- 使用AdvinceInstaller把exe或者msi重新包装成为msi静默安装程序
- 在VS2013 less报错404,VS如何使用.less
- Velocity开发指南-内容
- PHP 导出 Excel 表格数据 方法
- Integer to Roman
- 同步线程和异步线程的区别
- epoll学习 相关资料