1 /*
2  *  $Id: udp1.c,v 1.6 2004/03/01 20:26:12 mike Exp $
3  *
4  *  libnet 1.1
5  *  Build a UDP packet
6  *
7  *  Copyright (c) 1998 - 2004 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 #if (HAVE_CONFIG_H)
34 #include "../include/config.h"
35 #endif
36 #include "./libnet_test.h"
37 #ifdef __WIN32__
38 #include "../include/win32/getopt.h"
39 #endif
40 
41 int
main(int argc,char * argv[])42 main(int argc, char *argv[])
43 {
44     int c, i, j, build_ip;
45     char *cp;
46     libnet_t *l;
47     libnet_ptag_t ip, ipo;
48     libnet_ptag_t udp;
49     char *payload;
50     u_short payload_s;
51     struct libnet_stats ls;
52     u_long src_ip, dst_ip;
53     u_short src_prt, dst_prt;
54     u_char opt[20];
55     char errbuf[LIBNET_ERRBUF_SIZE];
56 
57     printf("libnet 1.1 packet shaping: UDP + IP options[raw]\n");
58 
59     /*
60      *  Initialize the library.  Root priviledges are required.
61      */
62     l = libnet_init(
63             LIBNET_RAW4,                            /* injection type */
64             NULL,                                   /* network interface */
65             errbuf);                                /* errbuf */
66 
67     if (l == NULL)
68     {
69         fprintf(stderr, "libnet_init() failed: %s\n", errbuf);
70         exit(EXIT_FAILURE);
71     }
72 
73     src_ip  = 0;
74     dst_ip  = 0;
75     src_prt = 0;
76     dst_prt = 0;
77     payload = NULL;
78     payload_s = 0;
79     ip = ipo = udp = 0;
80     while ((c = getopt(argc, argv, "d:s:p:")) != EOF)
81     {
82         switch (c)
83         {
84             /*
85              *  We expect the input to be of the form `ip.ip.ip.ip.port`.  We
86              *  point cp to the last dot of the IP address/port string and
87              *  then seperate them with a NULL byte.  The optarg now points to
88              *  just the IP address, and cp points to the port.
89              */
90             case 'd':
91                 if (!(cp = strrchr(optarg, '.')))
92                 {
93                     usage(argv[0]);
94                 }
95                 *cp++ = 0;
96                 dst_prt = (u_short)atoi(cp);
97                 if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
98                 {
99                     fprintf(stderr, "Bad destination IP address: %s\n", optarg);                    exit(EXIT_FAILURE);
100                 }
101                 break;
102             case 's':
103                 if (!(cp = strrchr(optarg, '.')))
104                 {
105                     usage(argv[0]);
106                 }
107                 *cp++ = 0;
108                 src_prt = (u_short)atoi(cp);
109                 if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
110                 {
111                     fprintf(stderr, "Bad source IP address: %s\n", optarg);
112                     exit(EXIT_FAILURE);
113                 }
114                 break;
115             case 'p':
116                 payload = optarg;
117                 payload_s = strlen(payload);
118                 break;
119             default:
120                 exit(EXIT_FAILURE);
121         }
122     }
123 
124     if (!src_ip || !src_prt || !dst_ip || !dst_prt)
125     {
126         usage(argv[0]);
127         exit(EXIT_FAILURE);
128     }
129 
130     for (build_ip = 0, i = 0; i < 10; i++)
131     {
132         udp = libnet_build_udp(
133             src_prt,                                /* source port */
134             dst_prt + i,                            /* destination port */
135             LIBNET_UDP_H + payload_s,               /* packet length */
136             0,                                      /* checksum */
137             (uint8_t*)payload,                     /* payload */
138             payload_s,                              /* payload size */
139             l,                                      /* libnet handle */
140             udp);                                   /* libnet id */
141         if (udp == -1)
142         {
143             fprintf(stderr, "Can't build UDP header: %s\n", libnet_geterror(l));
144             goto bad;
145         }
146 
147         if (1)
148         {
149             build_ip = 0;
150             /* this is not a legal options string */
151             for (j = 0; j < 20; j++)
152             {
153                 opt[j] = libnet_get_prand(LIBNET_PR2);
154             }
155             ipo = libnet_build_ipv4_options(
156                 opt,
157                 20,
158                 l,
159                 ipo);
160             if (ipo == -1)
161             {
162                 fprintf(stderr, "Can't build IP options: %s\n", libnet_geterror(l));
163                 goto bad;
164             }
165 
166             ip = libnet_build_ipv4(
167                 LIBNET_IPV4_H + 20 + payload_s + LIBNET_UDP_H, /* length */
168                 0,                                          /* TOS */
169                 242,                                        /* IP ID */
170                 0,                                          /* IP Frag */
171                 64,                                         /* TTL */
172                 IPPROTO_UDP,                                /* protocol */
173                 0,                                          /* checksum */
174                 src_ip,
175                 dst_ip,
176                 NULL,                                       /* payload */
177                 0,                                          /* payload size */
178                 l,                                          /* libnet handle */
179                ip);                                         /* libnet id */
180             if (ip == -1)
181             {
182                 fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(l));
183                 goto bad;
184             }
185         }
186 
187         /*
188          *  Write it to the wire.
189          */
190         fprintf(stderr, "%d byte packet, ready to go\n",
191             libnet_getpacket_size(l));
192         c = libnet_write(l);
193         if (c == -1)
194         {
195             fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
196             goto bad;
197         }
198         else
199         {
200             fprintf(stderr, "Wrote %d byte UDP packet; check the wire.\n", c);
201         }
202     }
203     libnet_stats(l, &ls);
204     fprintf(stderr, "Packets sent:  %lld\n"
205                     "Packet errors: %lld\n"
206                     "Bytes written: %lld\n",
207                     ls.packets_sent, ls.packet_errors, ls.bytes_written);
208     libnet_destroy(l);
209     return (EXIT_SUCCESS);
210 bad:
211     libnet_destroy(l);
212     return (EXIT_FAILURE);
213 }
214 
215 void
usage(char * name)216 usage(char *name)
217 {
218     fprintf(stderr,
219         "usage: %s -s source_ip.source_port -d destination_ip.destination_port"
220         " [-p payload]\n",
221         name);
222 }
223 /* EOF */
224