2
* packETH - ethernet packet generator
3
* By Miha Jemec <m.jemec@iskratel.si>
4
* Copyright 2003 Miha Jemec, Iskratel
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
#include "loadpacket.h"
31
#include "callbacks.h"
33
static GtkWidget *w1, *w2, *w3, *w4, *w5, *w6, *w7;
43
/* this one loads the parameters from file into notebook2 (Gen-b page) */
44
int load_gen_b_data(GtkButton *button, FILE *file_p) {
51
w1 = lookup_widget(GTK_WIDGET (button), "radiobutton35");
52
w2 = lookup_widget(GTK_WIDGET (button), "radiobutton34");
53
w3 = lookup_widget(GTK_WIDGET (button), "optionmenu9");
54
w4 = lookup_widget(GTK_WIDGET (button), "entry109");
55
w5 = lookup_widget(GTK_WIDGET (button), "entry110");
56
w6 = lookup_widget(GTK_WIDGET(button), "checkbutton35");
57
w7 = lookup_widget(GTK_WIDGET(button), "checkbutton37");
58
/* we read the file ohh python, where are you... */
61
/* rules for config files:
62
* - comments start with #
63
* - there can be spaces and newlines
64
* - only digits and - are acceptable characters
67
/* we have to limit the lines we read paramters from */
68
while ( (c = fgetc( file_p )) != EOF ) {
69
/* all the comment lines, starting with # , no limit for comment lines*/
70
if ( (j==0) && (c == 35)) {
71
/* ok, read till the end of line */
72
while ( getc(file_p) != 10);
76
/* let's limit the size */
77
if ( (j > 9) || (k > 2) )
80
/* ok, it is not a comment line so the info: only digits and minus sign are acceptable */
81
if ( (isdigit(c) != 0) || (c == 45) ) {
86
/* no digit is it a newline? */
90
if (strlen(buff) == 0)
92
buff4[k] = strtol(buff, (char **)NULL, 10);
94
strncpy(&buffc[k][j], buff, 9);
97
/* not, ok this is an error */
104
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w2), 1);
105
else if (buff4[0] == 0)
106
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w1), 1);
111
/* adjusting parameters...
112
if ( (buff4[1] >= 0) && (buff4[1] <= 4) )
113
gtk_option_menu_set_history (GTK_OPTION_MENU (w3), buff4[1]);
118
if (buff4[1] == - 3) {
119
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w6), 1);
120
gtk_entry_set_text(GTK_ENTRY(w4), "");
121
gtk_widget_set_sensitive (w4, FALSE);
123
else if ( (buff4[1] > 0) && (buff4[1] <= 9999999) ) {
124
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w6), 0);
125
gtk_widget_set_sensitive (w4, TRUE);
126
gtk_entry_set_text(GTK_ENTRY(w4), &buffc[1][0]);
133
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w7), 1);
134
gtk_entry_set_text(GTK_ENTRY(w5), "");
135
gtk_widget_set_sensitive (w5, FALSE);
137
else if ( (buff4[2] >= 1) && (buff4[2] <= 999999999) ) {
138
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w7), 0);
139
gtk_widget_set_sensitive (w5, TRUE);
140
gtk_entry_set_text(GTK_ENTRY(w5), &buffc[2][0]);
151
/* this one loads the parameters from file into notebook2 (Gen-s page) */
152
int load_gen_s_data(GtkButton *button, FILE *file_p) {
158
char *ptr = NULL, *ptr2 = NULL;
164
/* rules for config files:
165
* - comments start with #
166
* - there can be spaces and newlines
167
* - only digits and - are acceptable characters
170
while ( (c = fgetc( file_p )) != EOF ) {
171
/* all the comment lines, starting with # */
172
if ( (j==0) && (c == 35)) {
173
while ( getc(file_p) != 10);
176
/* all blank lines */
177
if ( (j==0) && (c == 10))
179
/* read the whole lines */
180
if ((isascii(c) != 0) && (j<200) && (c!=10) && (k<11)) {
185
/* , or \n mean end of string */
195
w1 = lookup_widget(GTK_WIDGET (button), "radiobutton36");
196
w2 = lookup_widget(GTK_WIDGET (button), "radiobutton37");
197
w4 = lookup_widget(GTK_WIDGET (button), "entry151");
198
w5 = lookup_widget(GTK_WIDGET (button), "entry152");
199
w6 = lookup_widget(GTK_WIDGET(button), "checkbutton36");
201
/* first line should have three parameters */
202
/* first is absolute or relative delay, allowed values 0 and 1 */
203
if (strncmp(&buffc[0][0], "1", 1) == 0)
204
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w1), 1);
205
else if (strncmp(&buffc[0][0], "0", 1) == 0)
206
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w2), 1);
211
/* second is number of packets: -3 means infinite, or 1 till 9999999) */
212
if (strncmp(&buffc[0][2], "-3", 2) == 0) {
213
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w6), 1);
214
gtk_entry_set_text(GTK_ENTRY(w4), "");
215
gtk_widget_set_sensitive (w4, FALSE);
219
if ( (ptr = strchr(&buffc[0][2], 44)) == NULL) {
223
buff4[0] = strtol(&buffc[0][2], (char **)NULL, 10);
225
if ( (buff4[0] >= 0) && (buff4[0] <= 9999999) ) {
226
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w6), 0);
227
gtk_widget_set_sensitive (w4, TRUE);
228
gtk_entry_set_text(GTK_ENTRY(w4), &buffc[0][2]);
235
/* last parameter is delay between sequences */
236
buff4[0] = strtol(ptr+1, (char **)NULL, 10);
238
if ( (buff4[0] >= 0) && (buff4[0] <= 999999999) ) {
239
gtk_entry_set_text(GTK_ENTRY(w5), ptr+1);
245
/* we have to clean everything */
246
for (j = 0; j < 10; j++) {
247
snprintf(buff, 10, "entry%d", 111+j);
248
w2 = lookup_widget(GTK_WIDGET (button), buff);
249
gtk_entry_set_text(GTK_ENTRY(w2), "");
250
snprintf(buff, 100, "entry%d", 121+j);
251
w3 = lookup_widget(GTK_WIDGET (button), buff);
252
gtk_entry_set_text(GTK_ENTRY(w3), "");
253
snprintf(buff, 100, "entry%d", 131+j);
254
w3 = lookup_widget(GTK_WIDGET (button), buff);
255
gtk_entry_set_text(GTK_ENTRY(w3), "");
256
snprintf(buff, 100, "entry%d", 141+j);
257
w3 = lookup_widget(GTK_WIDGET (button), buff);
258
gtk_entry_set_text(GTK_ENTRY(w3), "");
259
snprintf(buff, 100, "checkbutton%d", 25+j);
260
w2 = lookup_widget(GTK_WIDGET(button), buff);
261
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w2), 0);
264
/* and now all the rest */
265
for (j = 1; j < k; j++) {
266
/* first is packet name */
267
if ( (ptr2 = strchr(&buffc[j][0], 44)) == NULL)
270
if ( (strlen(&buffc[j][0]) > 0 ) && (strlen(&buffc[j][0]) < 70) ) {
271
snprintf(buff, 10, "entry%d", 110+j);
272
w2 = lookup_widget(GTK_WIDGET (button), buff);
273
gtk_entry_set_text(GTK_ENTRY(w2), &buffc[j][0]);
278
/* number of packets */
280
if ( (ptr2 = strchr(ptr, 44)) == NULL) {
284
cc = strtol(ptr, (char **)NULL, 10);
285
if ( (cc < 0) || (cc > 9999999) ) {
288
snprintf(buff, 100, "entry%d", 120+j);
289
w3 = lookup_widget(GTK_WIDGET (button), buff);
290
gtk_entry_set_text(GTK_ENTRY(w3), ptr);
292
/* delay between packets */
294
if ( (ptr2 = strchr(ptr, 44)) == NULL) {
298
cc = strtol(ptr, (char **)NULL, 10);
299
if ( (cc < 0) || (cc > 999999999) ) {
302
snprintf(buff, 100, "entry%d", 130+j);
303
w3 = lookup_widget(GTK_WIDGET (button), buff);
304
gtk_entry_set_text(GTK_ENTRY(w3), ptr);
308
if ( (ptr2 = strchr(ptr, 44)) == NULL) {
312
cc = strtol(ptr, (char **)NULL, 10);
313
if ( (cc < 0) || (cc > 999999999) ) {
316
snprintf(buff, 100, "entry%d", 140+j);
317
w3 = lookup_widget(GTK_WIDGET (button), buff);
318
gtk_entry_set_text(GTK_ENTRY(w3), ptr);
320
/* enable or disable */
322
snprintf(buff, 100, "checkbutton%d", 24+j);
323
w2 = lookup_widget(GTK_WIDGET(button), buff);
325
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w2), 0);
326
else if (*ptr == '0')
327
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w2), 1);
339
/* this one loads the parameters from file into notenook2 (Builder page) */
340
int load_packet_disector(GtkButton *button, FILE *fp) {
343
/* we load the packet contents from file, skiping comments and new lines */
344
while ( (c = fgetc( fp )) != EOF ) {
345
/* skip all the comment lines, starting with # */
347
while ( getc(fp) != 10);
353
/* now the info: only hexadecimal digits are acceptable */
354
if (isxdigit(c) != 0) {
360
error("Can't load packet: Data has wrong format!");
363
/* we check the length here: 1514 bytes or 1518 in case with VLAN field is max allowed
364
* since we don't know yet if there is vlan field included we only raise
365
* an error if it is longer than 1518 bytes (1518*2 + \0 = 3037)
366
* before sending the length is examined again anyway */
368
error("Can't load packet: Data is to long!");
373
remain = j; /* because j starts with 0, we don't need to subtract -1 for \0 */
376
error("Can't load packet: Data length is not an even number!");
381
/* this is how it looks like */
382
//for (j=0; field[j]!='\0'; j++)
383
// printf("%x", field[j]);
386
/* what is the shortest length we still allow?
387
* we don't care if the packet is shorter than actually allowed to go on ethernet
388
* maybe the user just wanted to save packet even if it is to short, so why not load it?
389
* what we do demand is, that every layer must be completed
390
* ok, here at least 14 bytes: 6 dest mac, 6 source mac and 2 for type or length*/
392
error("Can't load packet: Ethernet header is not long enough!");
399
/* first there is destination mac */
400
w1 = lookup_widget(GTK_WIDGET(button), "L_dst_mac");
401
for (i=1; i<=18; i++, ptrt++) {
409
gtk_entry_set_text(GTK_ENTRY(w1), temp);
413
w2 = lookup_widget(GTK_WIDGET(button), "L_src_mac");
414
for (i=1; i<=18; i++, ptrt++) {
422
gtk_entry_set_text(GTK_ENTRY(w2), temp);
424
/* next there is type or length field or 802.1q */
425
i = char2x(ptrf)*256 + char2x(ptrf+2);
427
remain = remain - 14;
429
/* in case of a vlan tag 0x8100 == 33024) */
430
w1 = lookup_widget(GTK_WIDGET(button), "bt_8021q");
431
w2 = lookup_widget(GTK_WIDGET(button), "frame6");
434
error("Can't load packet: Ethernet VLAN field is not long enough!");
440
w3 = lookup_widget(GTK_WIDGET(button), "L_optmenu2_bt");
441
w4 = lookup_widget(GTK_WIDGET(button), "checkbutton39");
442
w5 = lookup_widget(GTK_WIDGET(button), "checkbutton40");
443
w6 = lookup_widget(GTK_WIDGET(button), "L_vlan_id");
444
w7 = lookup_widget(GTK_WIDGET(button), "entry165");
446
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
447
gtk_widget_set_sensitive (w2, TRUE);
452
gtk_option_menu_set_history (GTK_OPTION_MENU (w3), (i>>1));
455
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w4), FALSE);
457
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w4), TRUE);
459
inspar(button, "L_vlan_id", ptrf, 3);
461
i = char2x(ptrf)*256 + char2x(ptrf+2);
463
/* we support now vlan stacking, in case the protocol in once again 0x8100
464
* we just add next 4 bytes in a QinQ field and switch the toggle button */
467
error("Can't load packet: QinQ VLAN field is not long enough!");
474
gtk_widget_set_sensitive (w7, TRUE);
475
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w5), TRUE);
477
inspar(button, "entry165", ptrf, 4);
479
i = char2x(ptrf)*256 + char2x(ptrf+2);
482
gtk_widget_set_sensitive (w7, FALSE);
483
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w5), FALSE);
487
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), FALSE);
488
gtk_widget_set_sensitive (w2, FALSE);
491
/* c will tell us which ethernet type we have */
494
/* ok, from now one, we split the dissection in different routines, depending on what values */
495
/* now if length is <= 1500, we have 802.3 ethernet and this value means length of ethernet packet */
497
next_prot = ethernet_8023(button);
498
/* Values between 1500 and 1536 are forbidden */
499
else if ( (i>1500) && (i<1536) ) {
500
error("Can't load packet: Wrong ethernet length/type field");
503
/* if i >= 1536 - ethernet ver II */
505
next_prot = ethernet_verII(button);
508
/* ok, so we have dissected the ethernet layer and now move on two the next layer.
509
* if the ethernet dissector returns -1, this means an error and we quit
510
* otherwise, the return value can be 2048 == 0x0800 and this means the ipv4
511
* so we try to dissect ipv4 header. in case it is ok, we activate the ippkt_radibt
512
* and this one then calls the callback which fills in ethernet ver II type field
513
* and PID field in 802.3 LLC/SNAP field. It is the same for arp packets
514
* for other packets we will try to open the userdefined window */
516
/* we got an error? */
521
else if (next_prot == 2048) {
522
/* ok, ipv4 should follow, so we call the routine for parsing ipv4 header. */
523
next_prot = ipv4_header(button);
527
/* if the return value from parsing ipv4 header was != 0, then the header parameters
528
* are ok and we can open ipv4 notebook page activate toggle button (button calls
529
* the callback then!!! */
530
w1 = lookup_widget(GTK_WIDGET(button), "ippkt_radibt");
531
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
533
/* here we do the further parsing: tcp, udp, icmp, ...*/
534
if (next_prot == 1) {
535
/* try to parse icmp header */
536
next_prot = icmp_header(button);
537
/* not ok, return an error */
540
/* ok, lets activate the icmp notebook */
542
w1 = lookup_widget(GTK_WIDGET(button), "icmp_bt");
543
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
546
else if (next_prot == 2) {
547
/* try to parse igmp header */
548
next_prot = igmp_header(button);
549
/* not ok, return an error */
552
/* ok, lets activate the igmp notebook */
554
w1 = lookup_widget(GTK_WIDGET(button), "igmp_bt");
555
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
558
else if (next_prot == 6) {
559
/* try to parse tcp header */
560
next_prot = tcp_header(button);
561
/* not ok, return an error */
564
/* ok, lets activate the tcp notebook */
566
w1 = lookup_widget(GTK_WIDGET(button), "tcp_bt");
567
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
570
/* protocols on top of tcp would follow here */
573
else if (next_prot == 17) {
574
/* try to parse udp header */
575
next_prot = udp_header(button);
576
/* not ok, return an error */
579
/* ok, lets activate the udp notebook */
581
w1 = lookup_widget(GTK_WIDGET(button), "udp_bt");
582
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
585
/* protocols on top of udp would follow here */
587
/* protocol we do not support yet; user defined window */
589
next_prot = usedef_insert(button, "text2");
590
w1 = lookup_widget(GTK_WIDGET(button), "ip_user_data_bt");
591
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
595
else if (next_prot == 2054) {
596
/* ok, arp header follows */
597
next_prot = arp_header(button);
601
w1 = lookup_widget(GTK_WIDGET(button), "arppkt_radiobt");
602
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
605
/* when ipv6 will be added, activate ipv6 button instead of userdef button */
606
else if (next_prot == 34525) {
607
//w1 = lookup_widget(GTK_WIDGET(button), "IPv6_rdbt");
608
//gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
609
w1 = lookup_widget(GTK_WIDGET(button), "usedef2_radibt");
610
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
613
inspar(button, "L_ethtype", ptrf, 4);
615
/* -2 means only llc without snap was used, so we don't insert the value in pid field */
616
if (next_prot != -2) {
618
inspar(button, "L_pid", ptrf, 4);
621
/* anything else - user defined */
623
/* setting "usedef2_radibt" toggle button to true will call the callback which will clear
624
eth II type field and 802.3 pid field, so we have to fill this later */
625
w1 = lookup_widget(GTK_WIDGET(button), "usedef2_radibt");
626
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
628
/* we still have c to distinguish between ver II and 802.3 */
632
inspar(button, "L_ethtype", ptrf, 4);
634
/* 802.3 and with LLC SNAP */
635
else if (next_prot != -2) {
637
inspar(button, "L_pid", ptrf, 4);
640
next_prot = usedef_insert(button, "text1");
647
int arp_header(GtkButton *button) {
652
/* arp header length == 28; but packet can be longer, f.e. to satisfy the min packet length */
654
error("Can't load packet: Packet length shorter than ARP header length!");
658
remain = remain - 28;
661
inspar(button, "A_hwtype", ptrf, 4);
664
inspar(button, "A_prottype", ptrf, 4);
667
inspar(button, "A_hwsize", ptrf, 2);
670
inspar(button, "A_protsize", ptrf, 2);
673
if ( (*ptrf == '0') && (*(ptrf+1) == '0') && (*(ptrf+2) == '0') && (*(ptrf+3) == '1') ) {
674
w1 = lookup_widget(GTK_WIDGET(button), "radiobutton10");
675
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
678
else if ( (*ptrf == '0') && (*(ptrf+1) == '0') && (*(ptrf+2) == '0') && (*(ptrf+3) == '2') ) {
679
w1 = lookup_widget(GTK_WIDGET(button), "radiobutton11");
680
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
684
w1 = lookup_widget(GTK_WIDGET(button), "radiobutton17");
685
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
686
inspar(button, "entry81", ptrf, 4);
691
w1 = lookup_widget(GTK_WIDGET(button), "A_sendermac");
692
for (i=1; i<=18; i++, ptrt++) {
700
gtk_entry_set_text(GTK_ENTRY(w1), temp);
705
w1 = lookup_widget(GTK_WIDGET(button), "A_senderip");
706
for (i=1; i<=12; i++, ptrt++) {
710
sprintf(tmp, "%d", x);
712
sprintf(tmp, "%d.", x);
716
tmp[(i-1)%3] = *ptrf++;
719
gtk_entry_set_text(GTK_ENTRY(w1), temp);
723
w1 = lookup_widget(GTK_WIDGET(button), "A_targetmac");
724
for (i=1; i<=18; i++, ptrt++) {
732
gtk_entry_set_text(GTK_ENTRY(w1), temp);
737
w1 = lookup_widget(GTK_WIDGET(button), "A_targetip");
738
for (i=1; i<=12; i++, ptrt++) {
742
sprintf(tmp, "%d", x);
744
sprintf(tmp, "%d.", x);
748
tmp[(i-1)%3] = *ptrf++;
751
gtk_entry_set_text(GTK_ENTRY(w1), temp);
758
int igmp_header(GtkButton *button) {
763
/* well normal igmp type should have at least 8 bytes, so this is min for us */
765
error("Can't load packet: Packet length shorter than IGMP header length!");
774
inspar(button, "entry166", ptrf, 2);
776
w1 = lookup_widget(GTK_WIDGET(button), "optionmenu20");
777
w2 = lookup_widget(GTK_WIDGET(button), "notebook8");
780
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 1);
781
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 1);
784
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 0);
785
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 0);
789
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 2);
790
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 0);
793
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 3);
794
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 0);
797
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 4);
798
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 2);
801
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 5);
802
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 0);
805
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 6);
806
gtk_notebook_set_page(GTK_NOTEBOOK(w2), 0);
809
inspar(button, "entry167", ptrf, 2);
811
/* set checksum button on auto */
812
w2 = lookup_widget(GTK_WIDGET(button), "checkbutton41");
813
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w2), TRUE);
817
if ( (x == 17) && (remain>4) ) { /* IGMP V3 query */
821
w1 = lookup_widget(GTK_WIDGET(button), "entry169");
822
for (i=1; i<=12; i++, ptrt++) {
826
sprintf(tmp, "%d", x);
828
sprintf(tmp, "%d.", x);
832
tmp[(i-1)%3] = *ptrf++;
835
gtk_entry_set_text(GTK_ENTRY(w1), temp);
837
inspar(button, "entry171", ptrf, 4);
838
x1 = (int)retint2(ptrf, 4);
839
inspar(button, "entry172", ptrf, 4);
840
/*#inspar(button, "entry173", ptrf, x1);*/
841
inspar(button, "entry173", ptrf, remain);
844
else if (x==22) { /*IGMP V3 report */
845
inspar(button, "entry176", ptrf, 4);
846
x1 = (int)retint2(ptrf, 4);
847
inspar(button, "entry177", ptrf, 4);
848
inspar(button, "entry178", ptrf, x1);
851
else { /*all the other versions */
855
w1 = lookup_widget(GTK_WIDGET(button), "entry175");
856
for (i=1; i<=12; i++, ptrt++) {
860
sprintf(tmp, "%d", x);
862
sprintf(tmp, "%d.", x);
866
tmp[(i-1)%3] = *ptrf++;
869
gtk_entry_set_text(GTK_ENTRY(w1), temp);
877
int icmp_header(GtkButton *button) {
881
/* well normal icmp type should have at least 8 bytes, so this is min for us */
883
error("Can't load packet: Packet length shorter than ICMP header length!");
892
inspar(button, "entry57", ptrf, 2);
894
w1 = lookup_widget(GTK_WIDGET(button), "optionmenu4");
896
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 0);
898
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 1);
900
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 2);
902
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 3);
905
if (x == 0) { /* echo reply */
906
/* insert code, checksum, identifier and seq number and data if there is some */
907
w1 = lookup_widget(GTK_WIDGET(button), "notebook5");
908
gtk_notebook_set_page(GTK_NOTEBOOK(w1), 0);
909
inspar(button, "entry62", ptrf, 2);
910
//inspar(button, "entry63", ptrf, 4);
912
inspar(button, "entry64", ptrf, 4);
913
inspar(button, "entry65", ptrf, 4);
914
/* set checksum button on auto */
915
w2 = lookup_widget(GTK_WIDGET(button), "checkbutton16");
916
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w2), TRUE);
918
inspar(button, "entry66", ptrf, remain * 2);
920
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton17");
921
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
924
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton17");
925
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), FALSE);
929
else if (x == 3) { /* destination unreacheable */
930
w1 = lookup_widget(GTK_WIDGET(button), "notebook5");
931
gtk_notebook_set_page(GTK_NOTEBOOK(w1), 2);
935
inspar(button, "entry58", ptrf, 2);
937
w1 = lookup_widget(GTK_WIDGET(button), "optionmenu5");
938
if ( (x >= 0) && (x <= 15) )
939
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), x);
941
gtk_option_menu_set_history (GTK_OPTION_MENU (w1), 16);
943
/* insert code, checksum, identifier and seq number and data if there is some */
944
//inspar(button, "entry59", ptrf, 4);
946
inspar(button, "entry60", ptrf, 8);
947
/* set checksum button on auto */
948
w2 = lookup_widget(GTK_WIDGET(button), "checkbutton15");
949
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w2), TRUE);
951
inspar(button, "entry61", ptrf, remain * 2);
953
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton24");
954
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
957
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton24");
958
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), FALSE);
961
else if (x == 8) { /* echo request */
962
w1 = lookup_widget(GTK_WIDGET(button), "notebook5");
963
gtk_notebook_set_page(GTK_NOTEBOOK(w1), 5);
964
/* insert code, checksum, identifier and seq number and data if there is some */
965
inspar(button, "entry74", ptrf, 2);
966
//inspar(button, "entry77", ptrf, 4);
968
inspar(button, "entry75", ptrf, 4);
969
inspar(button, "entry78", ptrf, 4);
970
/* set checksum button on auto */
971
w2 = lookup_widget(GTK_WIDGET(button), "checkbutton20");
972
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w2), TRUE);
974
inspar(button, "entry76", ptrf, remain * 2);
976
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton19");
977
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
980
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton19");
981
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), FALSE);
985
else { /* all the rest */
986
w1 = lookup_widget(GTK_WIDGET(button), "notebook5");
987
gtk_notebook_set_page(GTK_NOTEBOOK(w1), 1);
988
/* insert code, checksum and data if there is some */
989
inspar(button, "entry157", ptrf, 2);
990
//inspar(button, "entry158", ptrf, 4);
992
/* set checksum button on auto */
993
w2 = lookup_widget(GTK_WIDGET(button), "checkbutton38");
994
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w2), TRUE);
996
inspar(button, "entry159", ptrf, (remain + 4) * 2);
1004
int usedef_insert(GtkButton *button, char *entry) {
1009
/* get access to buffer of the text field */
1010
w2 = lookup_widget(GTK_WIDGET(button), entry);
1011
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w2));
1013
/* copy data to tmp field */
1014
for (i=0, j=1; (i < (remain * 3) ); i++, j++) {
1015
tmp[i] = *ptrf++; i++;
1016
tmp[i] = *ptrf++; i++;
1017
/* we allow only 16 bytes in each row - looks nicer */
1018
if ((j % 16) == 0 && (j > 1)) {
1027
/* insert the text in the text field */
1028
gtk_text_buffer_set_text(buffer,tmp,-1);
1036
int tcp_header(GtkButton *button) {
1039
char tmp[4600], tmp2[3], ch;
1041
/* for standard header this is minimum length */
1043
error("Can't load packet: Packet length shorter than TCP header length!");
1047
/* ok, packet is long enough to fill in the standard header, but what is the header length?
1048
* we insert this later but need now to see that the packet is long enough */
1049
x = retint(ptrf+24);
1050
if ( (x * 4) > remain ) {
1051
error("Can't load packet:\nPacket lenght shorter than TCP header length!");
1055
error("Can't load packet:\nTCP header length shorter than 20 bytes!");
1060
insint(button, "entry46", ptrf, 4);
1062
/* destination port */
1063
insint(button, "entry47", ptrf, 4);
1065
/* sequence number */
1066
insint(button, "entry48", ptrf, 8);
1068
/* acknowledgement number */
1069
insint(button, "entry49", ptrf, 8);
1071
/* now we insert value for length */
1072
sprintf(tmp2, "%d", x*4);
1073
w1 = lookup_widget(GTK_WIDGET(button), "entry50");
1074
gtk_entry_set_text(GTK_ENTRY(w1), tmp2);
1076
/* increase by one for length and for another one for 4 bits that are reserved */
1079
/* flags; next byte */
1080
ch = char2x(ptrf) % 0x0100;
1082
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton22");
1083
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x80) > 0 ? TRUE : FALSE);
1085
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton23");
1086
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x40) > 0 ? TRUE : FALSE);
1088
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton7");
1089
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x20) > 0 ? TRUE : FALSE);
1091
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton8");
1092
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x10) > 0 ? TRUE : FALSE);
1094
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton9");
1095
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x08) > 0 ? TRUE : FALSE);
1097
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton10");
1098
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x04) > 0 ? TRUE : FALSE);
1100
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton11");
1101
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x02) > 0 ? TRUE : FALSE);
1103
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton12");
1104
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), (ch & 0x01) > 0 ? TRUE : FALSE);
1109
insint(button, "entry51", ptrf, 4);
1112
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton13");
1113
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1114
//inspar(button, "entry52", ptrf, 4);
1118
insint(button, "entry53", ptrf, 4);
1121
/* - 20 for standard header */
1122
inspar(button, "entry54", ptrf, ( (x*4) - 20) * 2);
1124
remain = remain - x*4;
1126
/* get access to buffer of the text field */
1127
w2 = lookup_widget(GTK_WIDGET(button), "text4");
1128
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w2));
1131
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton14");
1132
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1134
/* copy data to tmp field */
1135
for (i=0, j=1; (i < (remain * 3) ); i++, j++) {
1136
tmp[i] = *ptrf++; i++;
1137
tmp[i] = *ptrf++; i++;
1138
/* we allow only 16 bytes in each row - looks nicer */
1139
if ((j % 16) == 0 && (j > 1)) {
1148
/* insert the text in the text field */
1149
gtk_text_buffer_set_text(buffer,tmp,-1);
1152
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton14");
1153
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), FALSE);
1156
/* since tcp does not have any protocol field we could return destination port value which
1157
* usually describes next layer protocol; currently we return 1 */
1162
int udp_header(GtkButton *button) {
1167
/* for standard header this is minimum length */
1169
error("Can't load packet: Packet length shorter than UDP header length!");
1173
remain = remain - 8;
1176
insint(button, "entry56", ptrf, 4);
1178
/* destination port */
1179
insint(button, "entry41", ptrf, 4);
1182
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton3");
1183
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1184
//insint(button, "entry42", ptrf, 4);
1188
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton4");
1189
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1190
//inspar(button, "entry43", "", 4);
1193
/* get access to buffer of the text field */
1194
w2 = lookup_widget(GTK_WIDGET(button), "text3");
1195
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w2));
1198
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton5");
1199
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1201
/* copy data to tmp field */
1202
for (i=0, j=1; (i < (remain * 3) ); i++, j++) {
1203
tmp[i] = *ptrf++; i++;
1204
tmp[i] = *ptrf++; i++;
1205
/* we allow only 16 bytes in each row - looks nicer */
1206
if ((j % 16) == 0 && (j > 1)) {
1215
/* insert the text in the text field */
1216
gtk_text_buffer_set_text(buffer,tmp,-1);
1219
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton5");
1220
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), FALSE);
1223
/* since udp does not have any protocol field we could return destination port value which
1224
* usually describes next layer protocol; currently we return 1 */
1229
int ipv4_header(GtkButton *button) {
1232
int x, header_l, prot;
1234
/* for standard header this is minimum length */
1236
error("Can't load packet: IPv4 header field is not long enough!");
1240
/* first comes version but we will first check the length and then insert version */
1243
/* check the header length */
1244
/* we don't need to check the return value here, it is already done when reading from file */
1245
header_l = retint(ptrf);
1246
/* header length is the number of 32-bit words in the header, including any options.
1247
* Since this is a 4-bit field, it limits the header to 60 bytes. So the remaining length
1248
* should be at least that long or we exit here */
1249
if ( (header_l * 4) < 20 ) {
1250
error("Can't load packet:\nIPv4 header length shorter than 20 bytes!");
1253
if ( (header_l * 4) > remain ) {
1254
error("Can't load packet:\nPacket lenght shorter than IPv4 header length!");
1259
/* insert version */
1260
inspar(button, "entry26", ptrf, 1);
1262
/* insert header lenght */
1263
inspar(button, "entry27", ptrf, 1);
1266
inspar(button, "entry28", ptrf, 2);
1268
/* insert total length */
1269
w1 = lookup_widget(GTK_WIDGET(button), "checkbutton21");
1270
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1271
//insint(button, "entry29", ptrf, 4);
1274
/* insert identification */
1275
inspar(button, "entry30", ptrf, 4);
1278
*tmp = 0x30; /* 0x30 == 0 */
1281
x = x >> 1; /* use only first 3 bits */
1282
w1 = lookup_widget(GTK_WIDGET(button), "entry31");
1283
sprintf(tmp, "%d", x);
1284
gtk_entry_set_text(GTK_ENTRY(w1), tmp);
1286
/* insert fragment offset */
1287
*tmp = 0x30; /* 0x30 == 0 */
1289
x = (char2x(tmp)%2); /* need only last bit */
1294
strncpy(tmp+1, ptrf+1, 3);
1295
insint(button, "entry32", tmp, 4);
1298
insint(button, "entry44", ptrf, 2);
1300
/* insert protocol */
1301
prot = char2x(ptrf);
1302
insint(button, "entry34", ptrf, 2);
1304
/* insert header checksum */
1305
w1 = lookup_widget(GTK_WIDGET(button), "ip_header_cks_cbt");
1306
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1307
//inspar(button, "entry35", ptrf, 4);
1310
/*insert source ip */
1312
memset(temp, 0, 20);
1313
w1 = lookup_widget(GTK_WIDGET(button), "entry38");
1314
for (i=1; i<=12; i++, ptrt++) {
1318
sprintf(tmp, "%d", x);
1320
sprintf(tmp, "%d.", x);
1324
tmp[(i-1)%3] = *ptrf++;
1327
gtk_entry_set_text(GTK_ENTRY(w1), temp);
1329
/*insert destination ip */
1331
memset(temp, 0, 20);
1332
w1 = lookup_widget(GTK_WIDGET(button), "entry37");
1333
for (i=1; i<=12; i++, ptrt++) {
1337
sprintf(tmp, "%d", x);
1339
sprintf(tmp, "%d.", x);
1343
tmp[(i-1)%3] = *ptrf++;
1346
gtk_entry_set_text(GTK_ENTRY(w1), temp);
1348
/* insert ipv4 options
1349
* header_l * 4 == total header length, - 20 for standard header == options length in bytes*/
1350
inspar(button, "entry39", ptrf, ( (header_l*4) - 20) * 2);
1352
remain = remain - (header_l * 4);
1358
int ethernet_8023(GtkButton *button) {
1360
int dsap, lsap, ctrl;
1364
error("Can't load packet: Ethernet 802.3 LLC field is not long enough!");
1367
remain = remain - 3;
1369
w1 = lookup_widget(GTK_WIDGET(button), "bt_8023");
1370
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1372
//w2 = lookup_widget(GTK_WIDGET(button), "frame7");
1373
//gtk_widget_set_sensitive (w2, TRUE);
1374
//gtk_notebook_set_page(GTK_NOTEBOOK(w3), 1);
1376
w1 = lookup_widget(GTK_WIDGET(button), "entry5");
1377
//inspar(button, "entry5", ptrf, 4);
1379
gtk_widget_set_sensitive (w1, FALSE);
1381
w2 = lookup_widget(GTK_WIDGET(button), "checkbutton2");
1382
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w2), TRUE);
1384
/*now the LLC / LLC-SNAP part */
1385
/* we decode only RFC 1042 format, that means the following value:
1386
dsap == ssap == 0xAA
1390
dsap = char2x(ptrf);
1391
inspar(button, "L_dsap", ptrf, 2);
1392
lsap = char2x(ptrf);
1393
inspar(button, "L_ssap", ptrf, 2);
1394
ctrl = char2x(ptrf);
1395
inspar(button, "L_ctrl", ptrf, 2);
1397
/* in case dsap != ssap != 0xAA or ctrl != 0x03 or remain length < 5 bytes, we have only
1398
* LLC without SNAP and we return value for user defined next layer */
1399
if ( (dsap != 170 ) || (lsap != 170) || (ctrl != 3) || (remain < 5) ) {
1400
w1 = lookup_widget(GTK_WIDGET(button), "L_8023_llc_tbt");
1401
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1402
w1 = lookup_widget(GTK_WIDGET(button), "L_oui");
1403
w2 = lookup_widget(GTK_WIDGET(button), "L_pid");
1404
gtk_widget_set_sensitive (w1, FALSE);
1405
gtk_widget_set_sensitive (w2, FALSE);
1406
/* this means we insert all the data as user defined field */
1409
/* in this case everything is ok but oui in not 0 */
1410
/* <--------------this is oui---------------------> */
1411
else if ( (char2x(ptrf) + char2x(ptrf+2) + char2x(ptrf+4) != 0 ) ) {
1412
w1 = lookup_widget(GTK_WIDGET(button), "L_8023_llc_tbt");
1413
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1414
w1 = lookup_widget(GTK_WIDGET(button), "L_oui");
1415
w2 = lookup_widget(GTK_WIDGET(button), "L_pid");
1416
gtk_widget_set_sensitive (w1, FALSE);
1417
gtk_widget_set_sensitive (w2, FALSE);
1418
/* this means we insert all the data as user defined field */
1422
/* substract 3 for oui and 2 for pid */
1423
remain = remain - 5;
1425
/* ok, so we have dsap and ssap == 0xAA, Ctlr == 0x03, OUI == 0x0 and lenght is long enough */
1426
/* set llc-snap button */
1427
w1 = lookup_widget(GTK_WIDGET(button), "L_8023_llcsnap_tbt");
1428
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1430
/* insert 0x00 into oui field */
1431
inspar(button, "L_oui", ptrf, 6);
1432
pid = char2x(ptrf)*256 + char2x(ptrf+2);
1440
int ethernet_verII(GtkButton *button) {
1444
w1 = lookup_widget(GTK_WIDGET(button), "bt_ver2");
1445
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w1), TRUE);
1447
pid = char2x(ptrf)*256 + char2x(ptrf+2);
1455
/* this one inserts (length) characters from (char *from) into entry named (char *entry). It adds \0
1456
at the end and in moves pointer ptrf (this one points the the next "data" to be inserted) by length */
1457
void inspar(GtkButton *button, char *entry, char *from, int length) {
1463
ptr = malloc(length * sizeof(char) + 1);
1465
widg = lookup_widget(GTK_WIDGET(button), entry);
1467
strncpy(ptr, from, length);
1469
gtk_entry_set_text(GTK_ENTRY(widg), ptr);
1470
ptrf = ptrf + length;
1476
/* this one reads (lengh) characters strating at (*from), converts them to int and inserts them
1477
into field (*entry) as integer. f.e: 0x56 == (int)86 => writes into (*entry) 86
1478
note that max size for length is 10!!! when calling this routine */
1479
void insint(GtkButton *button, char *entry, char *from, int length) {
1483
unsigned long value = 0;
1485
unsigned char x = 0;
1487
widg = lookup_widget(GTK_WIDGET(button), entry);
1489
for (i = 0; i < length; i++) {
1490
if ( (*from >= '0') && (*from <= '9'))
1492
else if ((*from >= 'A') && (*from <= 'F'))
1494
else if ((*from >= 'a') && (*from <= 'f'))
1497
value = value + ((int)x) * ((unsigned long)1 << (4*(length-1-i)) );
1501
ptrf = ptrf + length;
1503
sprintf(tmp, "%lu", value);
1504
gtk_entry_set_text(GTK_ENTRY(widg), tmp);
1508
/* from a character return int */
1509
signed int retint(char *ch) {
1513
if ( (*ch >= '0') && (*ch <= '9'))
1515
else if ((*ch >= 'A') && (*ch <= 'F'))
1517
else if ((*ch >= 'a') && (*ch <= 'f'))
1527
/* this one reads (lengh) characters strating at (*from), and returns integer (max 10 char length) */
1528
unsigned long retint2(char *from, int length) {
1530
unsigned long value = 0;
1532
unsigned char x = 0;
1534
for (i = 0; i < length; i++) {
1535
if ( (*from >= '0') && (*from <= '9'))
1537
else if ((*from >= 'A') && (*from <= 'F'))
1539
else if ((*from >= 'a') && (*from <= 'f'))
1542
value = value + ((int)x) * ((unsigned long)1 << (4*(length-1-i)) );