./c0de/c/pgmfuzz.txt

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
// pgmfuzz v1.0 - a fuzzing tool for Pragmatic General Multicast options
// Varun Uppal and Andy Davis, IRM 2007
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
 
#define SOCK_ADDR       struct sockaddr_in
#define IN_ADDR         struct in_addr
#define IP              struct ip
#define IP_HDR          struct iphdr
#define TH_OFFSET       5
#define DEFAULT_TTL     255
#define IPPROTO_PGM     0x71
 
/* Function prototypes */
 
void fill_ip_hdr (char *packet,u_int8_t protocol,IN_ADDR sa,IN_ADDR da,u_int16_t len);
int checksum (u_int16_t *buf,int nbytes);
void fill_pgm_pack(unsigned char *tmpbuffer, unsigned char *pgm_header,int pgm_hdr_size, unsigned char *pgm_data, int pgm_data_size,int seq_tracker);
void packet_sender(int sockd, unsigned char *packet, int ip_header_size, int pgm_header_size, int pgm_data_size);
void usage (char *progname);
 
 
unsigned char PGM_header[]=
 
"\x40\x47" //source port (16455)
"\x1d\x7e" //dst port (7550)
"\x04" //type ODATA
"\x01" //options present - set to 03 to include network options
"\x00\x00" //checksum
"\xc0\xa8\x00\x02\xb5\x7e" //Global Source Ident
"\x00\x08" // Transport Service Data Unit Length
"\x00\x00\x00\x00" //seq no
"\x00\x00\x00\x00" //trail edg seq no
 
//PGM options
 
//OPT_LENGTH option
"\x00"          //option type OPT_LENGTH
"\x04"          //length of option (4 bytes)
"\x00\x08"      //total length of options (including OPT_LENGTH)
 
//The option we're using
"\x92"          //option type (this changes)
"\x0c"          //option length (12 bytes)
"\x00\x00"      //option parameters (this changes)
"\x61\x61\x61\x61"      //option data
"\x61\x61\x61\x61";     //option data
 
 
unsigned char PGM_data[]=
"\x61\x61\x61\x61\x61\x61\x61\x61";
 
IN_ADDR src_addr, dst_addr;
SOCK_ADDR sock_addr;
int sockd, on=1;
int dst_port;
int check;
int check1;
int q;
unsigned char *buffer;
char *buffer1;
int seq_tracker=0;
int seq_tracker2;
u_int8_t packet[sizeof(IP)+ sizeof(PGM_header)-1 + sizeof(PGM_data)-1]; //IP header + PGM header + PGM data
 
main(int argc,char *argv[])
        {
        int c, errflg;
        unsigned long pgm_ip;
        unsigned long src_ip;
        unsigned int pgm_port=7550;     //default value
        unsigned char pgm_opt_start=0;  //default value
        unsigned char pgm_opt_end=127;  //default value
        unsigned char pgm_type_start=0; //default value
        unsigned char pgm_type_end=255; //default value
        unsigned int pgm_net_sig=0;     //default value
        unsigned int verbose=0;
        extern char *optarg;
        extern int optind, optopt;
        int q=4;
        int j,count;
        int pops;
        time_t mytime = time(0);
        unsigned char *thepgmbuffer;
 
        pgm_ip=inet_addr("224.0.1.78"); //default value
        src_ip=inet_addr("10.0.0.2");   //default value
        errflg=0;
 
        while ((c = getopt(argc, argv, ":a:i:p:r:s:t:u:nvh")) != -1)
                {
                switch(c)
                        {
                        case 'a':
                                pgm_ip = inet_addr(optarg);
                                break;
                        case 'i':
                                src_ip = inet_addr(optarg);
                                break;
                        case 'p':
                                pgm_port = atoi(optarg);
                                break;
                        case 'r':
                                pgm_opt_start = atoi(optarg);
                                break;
                        case 's':
                                pgm_opt_end = atoi(optarg);
                                break;
                        case 't':
                                pgm_type_start = atoi(optarg);
                                break;
                        case 'u':
                                pgm_type_end = atoi(optarg);
                                break;
                        case 'n':
                                pgm_net_sig = 1;
                                break;
                        case 'v':
                                verbose = 1;
                                break;
                        case 'h':
                                usage(argv[0]);
                        case ':':
                                printf ("Option -%c requires an operand\n", optopt);
                                errflg++;
                                break;
                        case '?':
                                printf("Unrecognized option: -%c\n", optopt);
                                errflg++;
                        }
                }
        if (errflg)
                {
                usage(argv[0]);
                }
 
 
        printf ("------------------------------------------------\n");
        printf ("%s - a fuzzer for PGM options\n",argv[0]);
        printf ("v1.0 by Varun Uppal and Andy Davis, IRM Plc 2007\n\n");
        printf ("For help, type pgmfuzz -h\n");
        printf ("------------------------------------------------\n\n");
 
        if (verbose)
                {
                printf ("Parameter values:\n");
                printf ("Source IP address = %s\n",inet_ntoa(src_ip));
                printf ("Destination IP address = %s\n",inet_ntoa(pgm_ip));
                printf ("PGM port = %d\n",pgm_port);
                printf ("PGM option type start value = %d\n", pgm_opt_start);
                printf ("PGM option type end value = %d\n", pgm_opt_end);
                printf ("PGM packet type start value = %d\n", pgm_type_start);
                printf ("PGM packet type end value = %d\n", pgm_type_end);
                printf ("Network Significant option bit = %d\n\n", pgm_net_sig);
                printf ("Starting to fuzz now...\n\n");
                }
 
        src_addr.s_addr=src_ip;
        dst_addr.s_addr=pgm_ip;
        PGM_header[2]=htons(pgm_port);
        PGM_header[3]=pgm_port;
        pgm_opt_start+=128;
        pgm_opt_end+=128;
 
        if (pgm_net_sig)
                PGM_header[5]=3;
 
 
        //Create a socket
        if((sockd=socket(AF_INET,SOCK_RAW,IPPROTO_PGM))<0)
                {
                perror("Error - socket()\n");
                exit(1);
                }
 
        //Set socket options
        if(setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0)
                {
                perror("Error - setsockopt()\n");
                close(sockd);
                exit(1);
                }
 
 
        for (q=pgm_type_start; q<=pgm_type_end; q++)     //loop through PGM packet types
                {
                PGM_header[4]=q;
 
                for (j=pgm_opt_start;j<=pgm_opt_end;j++)        //loop though PGM option types
                        {
                        PGM_header[28]=j;
                        mytime = time(0);
                        printf("%sPGM packet type:%d PGM option type:%d\n", ctime(&mytime),q,j & 0x7f);
                        for(pops=0;pops<=65535;pops++)  //loop though remainder of option bits
                                {
                                PGM_header[30]=pops;
                                PGM_header[31]=htons(pops);
                                fill_ip_hdr(packet,IPPROTO_PGM,src_addr,dst_addr,sizeof(IP)+ sizeof(PGM_header)-1 + sizeof(PGM_data)-1);
                                thepgmbuffer = (unsigned char *)malloc(sizeof(PGM_header)-1 + sizeof(PGM_data)-1);
                                fill_pgm_pack(thepgmbuffer,(unsigned char *)PGM_header,sizeof(PGM_header)-1,(unsigned char *)PGM_data,sizeof(PGM_data)-1, seq_tracker);
                                seq_tracker=seq_tracker+1;
                                memcpy(packet+sizeof(IP), thepgmbuffer, sizeof(PGM_header)-1 + sizeof(PGM_data)-1);
                                packet_sender(sockd, packet, sizeof(IP), sizeof(PGM_header)-1, sizeof(PGM_data)-1);
                                free(thepgmbuffer);
                                }
 
                        }
                }
 
        close(sockd);
        exit(0);
        }
 
 
void fill_ip_hdr (char *packet,u_int8_t protocol,IN_ADDR sa,IN_ADDR da,u_int16_t len)
        {
        IP_HDR *iphdr;
        iphdr=(IP_HDR*)packet;
        memset((char *)iphdr,'\0',sizeof(IP_HDR));
        iphdr->version=4;
        iphdr->ihl=5;
        iphdr->tot_len=len;
        iphdr->id=htons(getpid());
        iphdr->ttl=DEFAULT_TTL;
        iphdr->protocol=protocol;
        iphdr->saddr=sa.s_addr;
        iphdr->daddr=da.s_addr;
        iphdr->check=(u_int16_t)checksum((u_int16_t *)iphdr,sizeof(IP_HDR));
        }
 
 
void fill_pgm_pack(unsigned char *tmpbuffer, unsigned char *pgm_header,int pgm_hdr_size, unsigned char *pgm_data, int pgm_data_size, int seq_tracker)
{
        int check;
        int tsdu_length;
 
        memcpy(tmpbuffer, pgm_header, pgm_hdr_size);
        memcpy(tmpbuffer+pgm_hdr_size, pgm_data, pgm_data_size);
 
        if(seq_tracker<2)
                {
                tmpbuffer[14] = htons(pgm_data_size);
                tmpbuffer[15] = pgm_data_size;
 
                //calculate sequence number
                tmpbuffer[19]=tmpbuffer[19]+seq_tracker;
                //seq_tracker=seq_tracker+1;
                }
 
        if(seq_tracker>9)
                {
                tmpbuffer[14] = htons(pgm_data_size);
                tmpbuffer[15] = pgm_data_size;
 
                //calculate sequence number
                tmpbuffer[19]=tmpbuffer[19]+(seq_tracker-8);
                //seq_tracker=seq_tracker+1;
                }
 
        if(seq_tracker>=2 && seq_tracker<=9)
                {
                seq_tracker=seq_tracker-2;//reduce tsdu by 2 when data transmitted
 
                //tsdu_length=pgm_data_size-2;
                tmpbuffer[14] = htons(pgm_data_size);
                tmpbuffer[15] = pgm_data_size;
 
                //calculate sequence number
                tmpbuffer[19]=tmpbuffer[19]+seq_tracker;
                //seq_tracker=seq_tracker+1;
                }
 
        //Calculate checksum
        check=(u_int16_t)checksum((u_int16_t *)tmpbuffer,pgm_hdr_size + pgm_data_size);
        tmpbuffer[6] = check;
        tmpbuffer[7] = htons(check);
        }
 
int checksum (u_int16_t *buf,int nbytes)
        {
        u_int32_t sum;
        u_int16_t oddbyte;
        sum = 0;
        while (nbytes > 1)
                {
                sum += *buf++;
                nbytes -= 2;
                }
 
        if (nbytes == 1)
                {
                oddbyte = 0;
                *((u_int16_t *) &oddbyte) = *(u_int8_t *) buf;
                sum += oddbyte;
                }
 
        sum = (sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        return (u_int16_t) ~sum;
        }
 
void packet_sender(int sockd, unsigned char *packet, int ip_header_size, int pgm_header_size, int pgm_data_size)
{
        struct sockaddr_in sock_addr;
        int dst_port;
        int i;
 
        memset(&sock_addr,'\0',sizeof(sock_addr));
        sock_addr.sin_family = AF_INET;
        //sock_addr.sin_port = htons(dst_port);
        sock_addr.sin_addr = dst_addr;
 
        if(sendto (sockd,packet,ip_header_size+ pgm_header_size+ pgm_data_size,0x0,(struct sockaddr *)&sock_addr,sizeof(sock_addr)) != ip_header_size+pgm_header_size+ pgm_data_size)
                                {
                                perror("Error - sendto()\n");
                                close(sockd);
                                exit(1);
                                }
 
}
 
void usage (char *progname)
        {
        printf ("------------------------------------------------\n");
        printf ("%s - a fuzzer for PGM options\n",progname);
        printf ("v1.0 by Varun Uppal and Andy Davis, IRM Plc 2007\n");
        printf ("------------------------------------------------\n\n");
        printf ("Usage:\n");
        printf ("-i <Source IP address>\n");
        printf ("-a <Destination multicast IP address>\n");
        printf ("-p <PGM port>\n");
        printf ("-r <PGM option type start value>\n");
        printf ("-s <PGM option type end value>\n");
        printf ("-t <PGM packet type start value>\n");
        printf ("-u <PGM packet type end value>\n");
        printf ("-n <set the Network Significant option bit>\n");
        printf ("-v <maximum verbosity>\n");
        printf ("-h this page\n\n");
        printf ("Example: pgmfuzz -i 10.0.0.2 -a 224.0.1.78 -p 7550 -r 0 -s 127 -t 0 -u 4 -n\n\n");
        exit(1);
        }
 
 

Back