发送自定义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
相关资源:数据结构—成绩单生成器