/// <summary> Generate a pseudo-random TCP header. /// </summary> public static byte[] generateRandomTCPHeader() { byte[] bytes = new byte[Packets.TCPFields_Fields.TCP_HEADER_LEN]; // source port ArrayHelper.insertLong(bytes, randomPort(), Packets.TCPFields_Fields.TCP_SP_POS, Packets.TCPFields_Fields.TCP_PORT_LEN); // destination port ArrayHelper.insertLong(bytes, randomPrivilegedPort(), Packets.TCPFields_Fields.TCP_DP_POS, Packets.TCPFields_Fields.TCP_PORT_LEN); // sequence number ArrayHelper.insertLong(bytes, 0x00000000, Packets.TCPFields_Fields.TCP_SEQ_POS, Packets.TCPFields_Fields.TCP_SEQ_LEN); // acknowledgment number ArrayHelper.insertLong(bytes, 0x00000000, Packets.TCPFields_Fields.TCP_ACK_POS, Packets.TCPFields_Fields.TCP_ACK_LEN); // header length and flags (0x2 is syn). ArrayHelper.insertLong(bytes, 0xa002, Packets.TCPFields_Fields.TCP_FLAG_POS, Packets.TCPFields_Fields.TCP_FLAG_LEN); // window size ArrayHelper.insertLong(bytes, 0x0000, Packets.TCPFields_Fields.TCP_WIN_POS, Packets.TCPFields_Fields.TCP_WIN_LEN); // checksum. todo: generate real checksum ArrayHelper.insertLong(bytes, 0xcccc, Packets.TCPFields_Fields.TCP_CSUM_POS, Packets.TCPFields_Fields.TCP_CSUM_LEN); // urgent pointer ArrayHelper.insertLong(bytes, 0x0000, Packets.TCPFields_Fields.TCP_URG_POS, Packets.TCPFields_Fields.TCP_URG_LEN); return(bytes); }
/// /// <summary> Create a new IP packet. /// </summary> public IPPacket(int lLen, byte[] bytes) : base(lLen, bytes) { // fetch the actual header length from the incoming bytes _ipHeaderLength = (ArrayHelper.extractInteger(_bytes, _ethOffset + Packets.IPFields_Fields.IP_VER_POS, Packets.IPFields_Fields.IP_VER_LEN) & 0xf) * 4; // set offset into _bytes of previous layers _ipOffset = _ethOffset + _ipHeaderLength; }
/// <summary> Generate a pseudo-random ARP header. /// </summary> public static byte[] generateRandomARPHeader() { byte[] bytes = new byte[Packets.ARPFields.ARP_HEADER_LEN]; ArrayHelper.insertLong(bytes, Packets.ARPFields.ARP_ETH_ADDR_CODE, Packets.ARPFields.ARP_HW_TYPE_POS, Packets.ARPFields.ARP_ADDR_TYPE_LEN); ArrayHelper.insertLong(bytes, Packets.ARPFields.ARP_IP_ADDR_CODE, Packets.ARPFields.ARP_PR_TYPE_POS, Packets.ARPFields.ARP_ADDR_TYPE_LEN); ArrayHelper.insertLong(bytes, IPAddress.WIDTH, Packets.ARPFields.ARP_HW_LEN_POS, Packets.ARPFields.ARP_ADDR_SIZE_LEN); ArrayHelper.insertLong(bytes, MACAddress.WIDTH, Packets.ARPFields.ARP_PR_LEN_POS, Packets.ARPFields.ARP_ADDR_SIZE_LEN); ArrayHelper.insertLong(bytes, test(Settings.PROB_ARP_REQUEST)?Packets.ARPFields.ARP_OP_REQ_CODE:Packets.ARPFields.ARP_OP_REP_CODE, Packets.ARPFields.ARP_OP_POS, Packets.ARPFields.ARP_OP_LEN); ArrayHelper.insertLong(bytes, MACAddress.random(), Packets.ARPFields.ARP_S_HW_ADDR_POS, MACAddress.WIDTH); int srcAddress = IPAddress.random(Settings.SIM_NETWORK, Settings.SIM_NETMASK); ArrayHelper.insertLong(bytes, srcAddress, Packets.ARPFields.ARP_S_PR_ADDR_POS, IPAddress.WIDTH); ArrayHelper.insertLong(bytes, MACAddress.random(), Packets.ARPFields.ARP_T_HW_ADDR_POS, MACAddress.WIDTH); int dstAddress = srcAddress; int count = 0; // cheezy way to make sure that the source and dest address aren't the same while (dstAddress == srcAddress && count++ < randomRetryCount) { dstAddress = IPAddress.random(Settings.SIM_NETWORK, Settings.SIM_NETMASK); } ArrayHelper.insertLong(bytes, dstAddress, Packets.ARPFields.ARP_T_PR_ADDR_POS, IPAddress.WIDTH); return(bytes); }
/// <summary> Convert captured packet data into an object. /// </summary> public static Packet dataToPacket(int linkType, byte[] bytes, Timeval tv) { int ethProtocol; // record the length of the headers associated with this link layer type. // this length is the offset to the header embedded in the packet. lLen = LinkLayer.getLinkLayerLength(linkType); // extract the protocol code for the type of header embedded in the // link-layer of the packet int offset = LinkLayer.getProtoOffset(linkType); if (offset == -1) { // if there is no embedded protocol, assume IP? ethProtocol = Packets.EthernetProtocols_Fields.IP; } else { ethProtocol = ArrayHelper.extractInteger(bytes, offset, Packets.EthernetFields.ETH_CODE_LEN); } // try to recognize the ethernet type.. switch (ethProtocol) { // arp case Packets.EthernetProtocols_Fields.ARP: return(new ARPPacket(lLen, bytes, tv)); case Packets.EthernetProtocols_Fields.IP: int ipProtocol = IPProtocol.extractProtocol(lLen, bytes); switch (ipProtocol) { // icmp case Packets.IPProtocols_Fields.ICMP: return(new ICMPPacket(lLen, bytes, tv)); // igmp case Packets.IPProtocols_Fields.IGMP: return(new IGMPPacket(lLen, bytes, tv)); // tcp case Packets.IPProtocols_Fields.TCP: return(new TCPPacket(lLen, bytes, tv)); // udp case Packets.IPProtocols_Fields.UDP: return(new UDPPacket(lLen, bytes, tv)); // unidentified ip.. default: return(new IPPacket(lLen, bytes, tv)); } // ethernet level code not recognized, default to anonymous packet.. //goto default; default: return(new EthernetPacket(lLen, bytes, tv)); } }
/// /// <summary> Create a new TCP packet. /// </summary> public TCPPacket(int lLen, byte[] bytes) : base(lLen, bytes) { // set TCP header length _tcpHeaderLength = ((ArrayHelper.extractInteger(_bytes, _ipOffset + Packets.TCPFields_Fields.TCP_FLAG_POS, Packets.TCPFields_Fields.TCP_FLAG_LEN) >> 12) & 0xf) * 4; // set data (payload) length based on info in headers (note: tcpdump // can return extra junk bytes which bubble up to here int tmpLen = Length - Packets.IPFields_Fields.IP_HEADER_LEN - _tcpHeaderLength; _payloadDataLength = (tmpLen < 0)?0:tmpLen; }
/// <summary> Generate a pseudo-random network packet. /// </summary> /// <returns> an array of bytes containing a randomly generated /// ethernet network packet. Packet can encapsulate any known protocol. /// /// </returns> public static byte[] generate() { // create ethernet header byte[] packet = HeaderGenerator.generateRandomEthernetHeader(); int eProto = ArrayHelper.extractInteger(packet, Packets.EthernetFields.ETH_CODE_POS, Packets.EthernetFields.ETH_CODE_LEN); // figure out what type of packet should be encapsulated after the // newly generated ethernet header. switch (eProto) { case Packets.EthernetProtocols_Fields.IP: byte[] ipHeader = HeaderGenerator.generateRandomIPHeader(); packet = ArrayHelper.join(packet, ipHeader); // figure out what type of protocol should be encapsulated after the // newly generated IP header. int ipProto = ArrayHelper.extractInteger(ipHeader, Packets.IPFields_Fields.IP_CODE_POS, Packets.IPFields_Fields.IP_CODE_LEN); switch (ipProto) { case Packets.IPProtocols_Fields.UDP: byte[] udpHeader = HeaderGenerator.generateRandomUDPHeader(); packet = ArrayHelper.join(packet, udpHeader); break; case Packets.IPProtocols_Fields.ICMP: byte[] icmpHeader = HeaderGenerator.generateRandomICMPHeader(); packet = ArrayHelper.join(packet, icmpHeader); break; case Packets.IPProtocols_Fields.TCP: byte[] tcpHeader = HeaderGenerator.generateRandomTCPHeader(); packet = ArrayHelper.join(packet, tcpHeader); break; default: break; } break; case Packets.EthernetProtocols_Fields.ARP: byte[] arpHeader = HeaderGenerator.generateRandomARPHeader(); packet = ArrayHelper.join(packet, arpHeader); break; default: break; } return(packet); }
/// <summary> Extract a string describing an IP address from an array of bytes. /// * /// </summary> /// <param name="offset">the offset of the address data. /// </param> /// <param name="bytes">an array of bytes containing the IP address. /// </param> /// <returns> a string of the form "255.255.255.255" /// /// </returns> public static System.String extract(int offset, byte[] bytes) { return(toString(ArrayHelper.extractInteger(bytes, offset, WIDTH))); /* * StringBuffer sa = new StringBuffer(); * for(int i=offset; i<offset + WIDTH; i++) { * sa.append(0xff & bytes[i]); * if(i != offset + WIDTH - 1) * sa.append('.'); * } * return sa.toString(); */ }
/// <summary> Generate a pseudo-random ICMP header. /// </summary> public static byte[] generateRandomICMPHeader() { byte[] bytes = new byte[Packets.ICMPFields.ICMP_HEADER_LEN]; // code (message type) ArrayHelper.insertLong(bytes, randomICMPType(), Packets.ICMPFields.ICMP_CODE_POS, Packets.ICMPFields.ICMP_CODE_LEN); // subcode ArrayHelper.insertLong(bytes, 0x0, Packets.ICMPFields.ICMP_SUBC_POS, Packets.ICMPFields.ICMP_SUBC_LEN); // checksum. todo: generate real checksum ArrayHelper.insertLong(bytes, 0xcccc, Packets.ICMPFields.ICMP_CSUM_POS, Packets.ICMPFields.ICMP_CSUM_LEN); return(bytes); }
/// <summary> Generate a pseudo-random IP header. /// </summary> public static byte[] generateRandomIPHeader() { byte[] bytes = new byte[Packets.IPFields_Fields.IP_HEADER_LEN]; // ipv4. WARNING: only IPv4 is currently supported ArrayHelper.insertLong(bytes, 0x45, Packets.IPFields_Fields.IP_VER_POS, Packets.IPFields_Fields.IP_VER_LEN); // specify no special handling flag in type of service code ArrayHelper.insertLong(bytes, 0x2, Packets.IPFields_Fields.IP_TOS_POS, Packets.IPFields_Fields.IP_TOS_LEN); // random packet contains only a header, no payload ArrayHelper.insertLong(bytes, Packets.IPFields_Fields.IP_HEADER_LEN, Packets.IPFields_Fields.IP_LEN_POS, Packets.IPFields_Fields.IP_LEN_LEN); // increment id each time a packet is generated ArrayHelper.insertLong(bytes, fakeId++, Packets.IPFields_Fields.IP_ID_POS, Packets.IPFields_Fields.IP_ID_LEN); // header length and flags (none specified).. ArrayHelper.insertLong(bytes, 0x4000, Packets.IPFields_Fields.IP_FRAG_POS, Packets.IPFields_Fields.IP_FRAG_LEN); // time-to-live ArrayHelper.insertLong(bytes, 0xff, Packets.IPFields_Fields.IP_TTL_POS, Packets.IPFields_Fields.IP_TTL_LEN); // protocol ArrayHelper.insertLong(bytes, randomIPProtocol(), Packets.IPFields_Fields.IP_CODE_POS, Packets.IPFields_Fields.IP_CODE_LEN); // checksum. todo: generate real checksum ArrayHelper.insertLong(bytes, 0xcccc, Packets.IPFields_Fields.IP_CSUM_POS, Packets.IPFields_Fields.IP_CSUM_LEN); int srcAddress = IPAddress.random(Settings.SIM_NETWORK, Settings.SIM_NETMASK); // source ip ArrayHelper.insertLong(bytes, srcAddress, Packets.IPFields_Fields.IP_SRC_POS, IPAddress.WIDTH); int dstAddress = srcAddress; int count = 0; // cheezy way to make sure that the source and dest address aren't the same while (dstAddress == srcAddress && count++ < randomRetryCount) { dstAddress = IPAddress.random(Settings.SIM_NETWORK, Settings.SIM_NETMASK); } // dest ip ArrayHelper.insertLong(bytes, dstAddress, Packets.IPFields_Fields.IP_DST_POS, IPAddress.WIDTH); return(bytes); }
/// <summary> Generate a pseudo-random TCP header. /// </summary> public static byte[] generateRandomUDPHeader() { byte[] bytes = new byte[Packets.UDPFields_Fields.UDP_HEADER_LEN]; // source port ArrayHelper.insertLong(bytes, randomPort(), Packets.UDPFields_Fields.UDP_SP_POS, Packets.UDPFields_Fields.UDP_PORT_LEN); // destination port ArrayHelper.insertLong(bytes, randomPort(), Packets.UDPFields_Fields.UDP_DP_POS, Packets.UDPFields_Fields.UDP_PORT_LEN); // length ArrayHelper.insertLong(bytes, Packets.UDPFields_Fields.UDP_HEADER_LEN, Packets.UDPFields_Fields.UDP_LEN_POS, Packets.UDPFields_Fields.UDP_PORT_LEN); // checksum. todo: generate real checksum ArrayHelper.insertLong(bytes, 0xcccc, Packets.UDPFields_Fields.UDP_CSUM_POS, Packets.UDPFields_Fields.UDP_CSUM_LEN); return(bytes); }
/// <summary> Generate a pseudo-random ethernet header. /// </summary> public static byte[] generateRandomEthernetHeader() { byte[] bytes = new byte[Packets.EthernetFields.ETH_HEADER_LEN]; long dst = MACAddress.random(); ArrayHelper.insertLong(bytes, dst, Packets.EthernetFields.ETH_DST_POS, MACAddress.WIDTH); long src = MACAddress.random(); ArrayHelper.insertLong(bytes, src, Packets.EthernetFields.ETH_SRC_POS, MACAddress.WIDTH); int type = randomEthernetProtocol(); ArrayHelper.insertLong(bytes, type, Packets.EthernetFields.ETH_CODE_POS, Packets.EthernetFields.ETH_CODE_LEN); return(bytes); }