• 发送自定义IP包(测试中:第二版)


     发送自定义IP包:
            public struct ip_hdr   //IP头
            {
               public byte h_lenver; //4位首部长度+4位IP版本号
               public byte tos; //8位服务类型TOS
               public ushort total_len; //16位总长度(字节)
               public ushort ident; //16位标识
               public ushort frag_and_flags; //3位标志位+13报片偏移
               public byte ttl; //8位生存时间 TTL
               public byte proto; //8位协议 (TCP, UDP 或其他)
               public ushort checksum; //16位IP首部校验和
               public uint sourceIP; //32位源IP地址
               public uint destIP; //32位目的IP地址 
            }
            public struct tcp_hdr  //TCP头
            {
                public ushort th_sport; //16位源端口
                public ushort th_dport; //16位目的端口
                public uint th_seq; //32位序列号
                public uint th_ack; //32位确认号
                public byte th_lenres; //4位首部长度/6位保留字
                public byte th_flag; //6位标志位
                public ushort th_win; //16位窗口大小
                public ushort th_sum; //16位校验和
                public ushort th_urp; //16位紧急数据偏移量
            }
            public struct psd_hdr    //TCP伪首部,用来计算校验和,无意义
            {
                public long saddr; //源地址
                public long daddr; //目的地址
                public byte mbz;
                public byte ptcl; //协议类型
                public ushort tcpl; //TCP长度
            }
    //开始
            private void button1_Click(object sender, EventArgs e)
            {
                //检测是否填写完整
                if (t_locIP.Text == "" || t_locPort.Text == "" || t_remoIP.Text == "" || t_remoPort.Text == "")
                { MessageBox.Show("本地IP,端口,远程IP,端口必填!"); return; }
                if (radioButton2.Checked && t_count.Text == "")
                    return;
                //创建原始套接字
                Socket s;
                try
                {
                    s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
                    s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, false);
                }
                catch (SocketException ee)
                { MessageBox.Show("创建原始套接字失败!\r\n"+ee.Message.ToString()); return; }
               
                //创建IP头
                ip_hdr myip_hdr = new ip_hdr();
                tcp_hdr mytcp_hdr = new tcp_hdr();
                myip_hdr.h_lenver = (byte)(4 << 4 | Marshal.SizeOf(myip_hdr) / sizeof(uint));
                myip_hdr.total_len = (ushort)(Marshal.SizeOf(myip_hdr) + Marshal.SizeOf(mytcp_hdr));
                myip_hdr.ident = 1;
                myip_hdr.frag_and_flags = 0;
                myip_hdr.ttl = 128;
                myip_hdr.proto = 6;
                myip_hdr.checksum = 0;
                myip_hdr.sourceIP=(uint)IPAddress.Parse(t_locIP.Text).Address;
                myip_hdr.destIP = (uint)IPAddress.Parse(t_remoIP.Text).Address;

                //创建TCP头
               
                mytcp_hdr.th_sport = Convert.ToUInt16(t_locPort.Text);
                mytcp_hdr.th_dport = Convert.ToUInt16(t_remoPort.Text);
                mytcp_hdr.th_seq=0x12345678;//32位序列号
                mytcp_hdr.th_ack = 0;
                mytcp_hdr.th_lenres = (byte)(Marshal.SizeOf(mytcp_hdr) / 4 << 4 | 0);
                mytcp_hdr.th_flag = 2;//修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等
                mytcp_hdr.th_win = 512;
                mytcp_hdr.th_urp = 0;
                mytcp_hdr.th_sum = 0;

                //伪tcp头
                psd_hdr mypsd_hdr = new psd_hdr();
                mypsd_hdr.saddr = myip_hdr.sourceIP;
                mypsd_hdr.daddr = myip_hdr.destIP;
                mypsd_hdr.mbz = 0;
                mypsd_hdr.ptcl = 6;
                mypsd_hdr.tcpl =(ushort) Marshal.SizeOf(mytcp_hdr);

                //计算校验和
                byte[] psdbytes = StructToBytes(mypsd_hdr);
                byte[] tcpbytes = StructToBytes(mytcp_hdr);
                byte[] buffer=new byte[psdbytes.Length+tcpbytes.Length];
                psdbytes.CopyTo(buffer, 0);
                tcpbytes.CopyTo(buffer, psdbytes.Length);
                UInt16[] myarray1 = byteToUint16(buffer);
                mytcp_hdr.th_sum = checksum(myarray1, myarray1.Length);

                byte[] ipbytes = StructToBytes(myip_hdr);
                buffer=new byte[ipbytes.Length+tcpbytes.Length];
                ipbytes.CopyTo(buffer,0);
                tcpbytes.CopyTo(buffer, ipbytes.Length);
                UInt16[] myarray2 = byteToUint16(buffer);
                myip_hdr.checksum = checksum(myarray2,myarray2.Length);
                ipbytes = StructToBytes(myip_hdr);
                ipbytes.CopyTo(buffer, 0);    //buffer即为要发送的伪IP包
               
                //发送ip包
                IPEndPoint remoEnd = new IPEndPoint(IPAddress.Parse(t_remoIP.Text), Convert.ToInt16(t_remoPort.Text));
                try
                {
                    s.SendTo(buffer, remoEnd);
                    MessageBox.Show("发送成功!发送的数据包为:\r\n"+DisplayByte(buffer));
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("发送数据过程中出错:\r\n" + ex.Message.ToString());
                }
            }
    //计算校验和
            public UInt16 checksum(UInt16[] buffer, int size)
            {
                Int32 cksum = 0;
                int counter;
                counter = 0;

                while (size > 0)
                {
                    UInt16 val = buffer[counter];

                    cksum += Convert.ToInt32(buffer[counter]);
                    counter += 1;
                    size -= 1;
                }

                cksum = (cksum >> 16) + (cksum & 0xffff);
                cksum += (cksum >> 16);
                return (UInt16)(~cksum);
            }

    //struct类型转换成byte[]
            public static byte[] StructToBytes(object structObj)
            {
                int size = Marshal.SizeOf(structObj);
                IntPtr buffer = Marshal.AllocHGlobal(size);
                try
                {
                    Marshal.StructureToPtr(structObj, buffer, false);
                    byte[] bytes = new byte[size];
                    Marshal.Copy(buffer, bytes, 0, size);
                    return bytes;
                }
                finally
                {
                    Marshal.FreeHGlobal(buffer);
                }

            }  
    //byte[]转换成uint16[]
            public static UInt16[] byteToUint16(byte[] putin)
            {
                double dlong = Convert.ToDouble(putin.Length);
                double dtemp = Math.Ceiling(dlong/2);
                int intlong = Convert.ToInt16(dtemp);
                UInt16[] retArray=new UInt16[intlong];
                int flag = 0;
                for (int i = 0; i < intlong; i++)
                {
                    retArray[i] = BitConverter.ToUInt16(putin, flag);
                    flag += 2;
                }
                return retArray;
            }
    //显示byte[]的内容
            public static string DisplayByte(byte[] putin)
            {
                string retstr = "";
                for (int i = 0; i < putin.Length; i++)
                    retstr += putin[i].ToString("X2")+" ";
                return retstr;
            }

  • 相关阅读:
    一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用
    智能手机的工业控制应用方案——SimpleWiFi在工业控制领域应用
    一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用
    TI推出SimpleLink低能耗蓝牙CC2541
    SimpleWiFi模块评估板
    Android架构设计和软硬整合完整训练
    CentOS上解压ZIP乱码的解决办法
    更具体的描述JNI
    数据市中心全省中国mysql脚本
    几种方法枚举子集
  • 原文地址:https://www.cnblogs.com/tuyile006/p/583400.html
Copyright © 2020-2023  润新知