發送自訂IP包(測試中:第二版)

來源:互聯網
上載者:User

 發送自訂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;
        }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.