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

it2022-05-09  35

 发送自定义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;        }

转载于:https://www.cnblogs.com/tuyile006/archive/2006/12/05/583400.html

相关资源:数据结构—成绩单生成器

最新回复(0)