OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / lib / Libnet / example / libnet-example-4.c
1 /*
2  *  $Id: libnet-example-4.c,v 1.1.1.1 2000/05/25 00:28:49 route Exp $
3  *
4  *  libnet example code
5  *  example 4:  link-layer api / UDP packet using port list chaining
6  *
7  *  Copyright (c) 1998 - 2001 Mike D. Schiffman <mike@infonexus.com>
8  *  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  */
32
33 #include <libnet.h>
34
35 #define MAX_PAYLOAD_SIZE    1024
36
37 void usage(char *);
38
39 u_char enet_src[6] = {0x0d, 0x0e, 0x0a, 0x0d, 0x00, 0x00};
40 u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
41
42 int
43 main(int argc, char *argv[])
44 {
45     int packet_size,                    /* size of our packet */
46         payload_size,                   /* size of our packet */
47         c;                              /* misc */
48     u_long src_ip, dst_ip;              /* source ip, dest ip */
49     u_short bport, eport;               /* beginning and end ports */
50     u_short cport;                      /* current port */
51     u_char payload[MAX_PAYLOAD_SIZE];   /* packet payload */
52     u_char *packet;                     /* pointer to our packet buffer */
53     char err_buf[LIBNET_ERRBUF_SIZE];   /* error buffer */
54     u_char *device;                     /* pointer to the device to use */
55     struct libnet_link_int *network;    /* pointer to link interface struct */
56     struct libnet_plist_chain plist;    /* plist chain */
57     struct libnet_plist_chain *plist_p; /* plist chain pointer */
58
59     printf("libnet example code:\tmodule 4\n\n");
60     printf("packet injection interface:\tlink layer\n");
61     printf("packet type:\t\t\tUDP [with payload] using port list chaining\n");
62
63     plist_p = NULL;
64     device = NULL;
65     src_ip = 0;
66     dst_ip = 0;
67
68     while ((c = getopt(argc, argv, "i:d:s:p:")) != EOF)
69     {
70         switch (c)
71         {
72             case 'd':
73                 if (!(dst_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE)))
74                 {
75                     libnet_error(LIBNET_ERR_FATAL,
76                             "Bad destination IP address: %s\n", optarg);
77
78                 }
79                 break;
80             case 'i':
81                 device = optarg;
82                 break;
83             case 's':
84                 if (!(src_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE)))
85                 {
86                     libnet_error(LIBNET_ERR_FATAL,
87                             "Bad source IP address: %s\n", optarg);
88                 }
89                 break;
90             case 'p':
91                 plist_p = &plist;
92                 if (libnet_plist_chain_new(&plist_p, optarg) == -1)
93                 {
94                     libnet_error(LIBNET_ERR_FATAL, "Could not build port list\n");
95                 }
96                 break;
97             default:
98                 usage(argv[0]);
99                 exit(EXIT_FAILURE);
100         }
101     }
102
103     if (!src_ip || !dst_ip || !plist_p)
104     {
105         usage(argv[0]);
106         exit(EXIT_FAILURE);
107     }
108
109     c = argc - optind;
110     if (c != 1)
111     {
112         usage(argv[0]);
113         exit(EXIT_FAILURE);
114     }
115     memset(payload, 0, sizeof(payload));
116     strncpy(payload, argv[optind], strlen(argv[optind]));
117
118
119     /*
120      *  Step 1: Network Initialization (interchangable with step 2).
121      */
122     if (device == NULL)
123     {
124         struct sockaddr_in sin;
125         /*
126          *  Try to locate a device.
127          */
128         if (libnet_select_device(&sin, &device, err_buf) == -1)
129         {
130             libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf);
131         }
132         printf("device:\t\t\t\t%s\n", device);
133     }
134     if ((network = libnet_open_link_interface(device, err_buf)) == NULL)
135     {
136         libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf);
137     }
138
139     /*
140      *  Get the payload from the user.  Hrm.  This might fail on a Sparc
141      *  if byte alignment is off...
142      */
143     payload_size = strlen(payload);
144
145     /*
146      *  We're going to build a UDP packet with a payload using the
147      *  link-layer API, so this time we need memory for a ethernet header
148      *  as well as memory for the ICMP and IP headers and our payload.
149      */
150     packet_size = LIBNET_IP_H + LIBNET_ETH_H + LIBNET_UDP_H + payload_size;
151
152     /*
153      *  Step 2: Memory Initialization (interchangable with step 1).
154      */
155     if (libnet_init_packet(packet_size, &packet) == -1)
156     {
157         libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
158     }
159
160
161     /*
162      *  Step 3: Packet construction (ethernet header).
163      */
164     libnet_build_ethernet(enet_dst,
165             enet_src,
166             ETHERTYPE_IP,
167             NULL,
168             0,
169             packet);
170
171     /*
172      *  Step 3: Packet construction (IP header).
173      */
174     libnet_build_ip(LIBNET_UDP_H + payload_size,
175             0,                      /* IP tos */
176             242,                    /* IP ID */
177             0,                      /* Frag */
178             64,                     /* TTL */
179             IPPROTO_UDP,            /* Transport protocol */
180             src_ip,                 /* Source IP */
181             dst_ip,                 /* Destination IP */
182             NULL,                   /* Pointer to payload (none) */
183             0,
184             packet + LIBNET_ETH_H); /* Packet header memory */
185
186
187     while (libnet_plist_chain_next_pair(plist_p, &bport, &eport))
188     {
189         while (!(bport > eport) && bport != 0)
190         {
191             cport = bport++;
192             /*
193              *  Step 3: Packet construction (UDP header).
194              */
195             libnet_build_udp(242,           /* source port */
196                     cport,                  /* dest. port */
197                     payload,                /* payload */ 
198                     payload_size,           /* payload length */ 
199                     packet + LIBNET_ETH_H + LIBNET_IP_H);
200
201             /*
202              *  Step 4: Packet checksums (ICMP header *AND* IP header).
203              */
204             if (libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1)
205             {
206                 libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
207             }
208             if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1)
209             {
210                 libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
211             }
212
213             /*
214              *  Step 5: Packet injection.
215              */
216             c = libnet_write_link_layer(network, device, packet, packet_size);
217             if (c < packet_size)
218             {
219                 libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c);
220             }
221             else
222             {
223                 printf("construction and injection completed, wrote all %d bytes, port %d\n", c, cport);
224             }
225         }
226     }
227     /*
228      *  Shut down the interface.
229      */
230     if (libnet_close_link_interface(network) == -1)
231     {   
232         libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface");
233     }
234
235
236     /*
237      *  Free packet memory.
238      */
239     libnet_destroy_packet(&packet);
240
241     return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS);
242 }
243
244
245 void
246 usage(char *name)
247 {
248     fprintf(stderr, "usage: %s [-i interface] -s s_ip -d d_ip -p port list payload\n", name);
249 }
250
251 /* EOF */