TCP/IP协议栈,关于TCP_RST | TCP_ACK正确姿态

60 篇文章 2 订阅
21 篇文章 2 订阅

不废话上实现:

        bool TapTap2Socket::RST(My::Tun::ITap* tap, struct My::Net::Native::ip_hdr* iphdr, struct My::Net::Native::tcp_hdr* pkg, int len) { assert(tap && iphdr && pkg);
            uint32_t dstAddr       = iphdr->dest;
            uint16_t dstPort       = pkg->dest;
            uint32_t srcAddr       = iphdr->src;
            uint16_t srcPort       = pkg->src;
            uint32_t seqNo         = pkg->seqno;
            uint32_t ackNo         = pkg->ackno;

            uint32_t hdrlen_bytes  = tcp_hdr::TCPH_HDRLEN_BYTES(pkg);
            uint32_t tcplen        = len - hdrlen_bytes;
            if (tcp_hdr::TCPH_FLAGS(pkg) & (TcpFlags::TCP_FIN | TcpFlags::TCP_SYN)) {
                tcplen++;
            }

            len                    = tcp_hdr::TCP_HLEN; // 1 align sizeof(tcp_hdr)
            iphdr->src             = dstAddr;
            pkg->src               = dstPort;
            iphdr->dest            = srcAddr;
            pkg->dest              = srcPort;
            pkg->ackno             = seqNo + tcplen;
            pkg->seqno             = ackNo;
            pkg->hdrlen_rsvd_flags = 0;
            pkg->urgp              = 0;

            tcp_hdr::TCPH_HDRLEN_BYTES_SET(pkg, len);
            tcp_hdr::TCPH_FLAGS_SET(pkg, TcpFlags::TCP_RST | TcpFlags::TCP_ACK);

            NetworkStatistics::TcpStatistics& tcp_stat = this->_statistics.Tcp;
            tcp_stat.IncomingUnicastPacket++;
            tcp_stat.IncomingTrafficSize += len;
            return this->OPT(false, tap, iphdr, pkg, len);
        }
        bool TapTap2Socket::OPT(bool lan2wan, My::Tun::ITap* tap, struct My::Net::Native::ip_hdr* iphdr, struct My::Net::Native::tcp_hdr* pkg, int len) { assert(tap && iphdr && pkg);
            pkg->chksum = 0;
            pkg->chksum = My::Net::Native::inet_chksum_pseudo((unsigned char*)pkg,
                        (unsigned int)ip_hdr::IP_PROTO_TCP,
                        (unsigned int)len,
                        iphdr->src,
                        iphdr->dest);
            if (pkg->chksum == 0) {
                pkg->chksum = 0xffff;
            }

            int iphdr_len = (char*)pkg - (char*)iphdr;
            iphdr->chksum = 0;
            iphdr->chksum = My::Net::Native::inet_chksum(iphdr, iphdr_len);
            if (iphdr->chksum == 0) {
                iphdr->chksum = 0xffff;
            }

            int ippkg_len = ((char*)pkg + len) - (char*)iphdr;
            NetworkStatistics::Statistics& ip_stat = this->_statistics.IPv4;
            if (lan2wan) {
                ip_stat.OutgoingUnicastPacket++; 
                ip_stat.OutgoingTrafficSize += ippkg_len;
            }
            else {
                ip_stat.IncomingUnicastPacket++; 
                ip_stat.IncomingTrafficSize += ippkg_len;
            }
            return tap->Output(iphdr, ippkg_len);
        }

tcp_hdr.h

#pragma once

#include <My/Net/Native/ip.h>
#include <My/Net/Native/checksum.h>

namespace My {
    namespace Net {
        namespace Native {
#pragma pack(push, 1)
            /*
             * typedef struct _tcp_hdr  
             * {  
             *     unsigned short src_port;    //源端口号   
             *     unsigned short dst_port;    //目的端口号   
             *     unsigned int seq_no;        //序列号   
             *     unsigned int ack_no;        //确认号   
             *     #if LITTLE_ENDIAN   
             *     unsigned char reserved_1:4; //保留6位中的4位首部长度   
             *     unsigned char thl:4;        //tcp头部长度   
             *     unsigned char flag:6;       //6位标志   
             *     unsigned char reseverd_2:2; //保留6位中的2位   
             *     #else   
             *     unsigned char thl:4;        //tcp头部长度   
             *     unsigned char reserved_1:4; //保留6位中的4位首部长度   
             *     unsigned char reseverd_2:2; //保留6位中的2位   
             *     unsigned char flag:6;       //6位标志    
             *     #endif   
             *     unsigned short wnd_size;    //16位窗口大小   
             *     unsigned short chk_sum;     //16位TCP检验和   
             *     unsigned short urgt_p;      //16为紧急指针   
             * }tcp_hdr;  
             */

            struct tcp_hdr {
            public:
                enum TcpFlags {
                    TCP_FIN                     = 0x01,
                    TCP_SYN                     = 0x02,
                    TCP_RST                     = 0x04,
                    TCP_PSH                     = 0x08,
                    TCP_ACK                     = 0x10,
                    TCP_UGR                     = 0x20,
                    TCP_ECE                     = 0x40,
                    TCP_CWR                     = 0x80,
                    TCP_FLAGS                   = 0x3f
                };

            public:
                unsigned short                  src;
                unsigned short                  dest;
                unsigned int                    seqno;
                unsigned int                    ackno;
                unsigned short                  hdrlen_rsvd_flags;
                unsigned short                  wnd;
                unsigned short                  chksum;
                unsigned short                  urgp; // 应用层不可能出现“URGP/UGR or OPT”的协议;这类紧急协议数据报文直接RST链接即可。

            public:
                inline static unsigned short    TCPH_HDRLEN(struct tcp_hdr* phdr) {
                    return ((unsigned short)(__ntohs((phdr)->hdrlen_rsvd_flags) >> 12));
                }
                inline static unsigned char     TCPH_HDRLEN_BYTES(struct tcp_hdr* phdr) {
                    return ((unsigned char)(TCPH_HDRLEN(phdr) << 2));
                }
                inline static unsigned char     TCPH_FLAGS(struct tcp_hdr* phdr) {
                    return ((unsigned char)((__ntohs((phdr)->hdrlen_rsvd_flags) & (unsigned char)TCP_FLAGS)));
                }
                inline static unsigned short    TCPH_HDRLEN_SET(struct tcp_hdr* phdr, int len) {
                    int u = ((len) << 12) | TCPH_FLAGS(phdr);
                    return (phdr)->hdrlen_rsvd_flags = __htons((unsigned short)u);
                }
                inline static unsigned short    TCPH_HDRLEN_BYTES_SET(struct tcp_hdr* phdr, int len) {
                    return TCPH_HDRLEN_SET(phdr, len >> 2);
                }
                inline static unsigned short    PP_HTONS(int x) {
                    return ((unsigned short)((((x) & (unsigned short)0x00ffU) << 8) | (((x) & (unsigned short)0xff00U) >> 8)));
                }
                inline static unsigned short    TCPH_FLAGS_SET(struct tcp_hdr* phdr, int flags) {
                    return (phdr)->hdrlen_rsvd_flags = (unsigned short)(((phdr)->hdrlen_rsvd_flags &
                        PP_HTONS(~(unsigned short)TCP_FLAGS)) | __htons((unsigned short)flags));
                }

            public:
                static struct tcp_hdr*          Parse(struct ip_hdr* iphdr, const void* packet, int size);

            public:
                static const int                TCP_HLEN;
            };
#pragma pack(pop)
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值