Yeah the whole point is that you can see there are multiple packages in the file if you just look at it in another program.
Yeah the whole point is that you can see there are multiple packages in the file if you just look at it in another program.
from that other program I used it is not a valid tcpdump file, and still if binary one still needs to know what order to get the information. Yes/?/
Last edited by userxbw; 12-16-2017 at 04:03 PM.
I don't know if it's a valid anything. I don't even really want to argue if it is or isn't valid. I just want to point out what I saw.
I'll attach a picture since it's really the best that I can do.
I think just seeing this, you can see what the OP is trying to do with the code he has, and it is sort of working. It's just not one big packet... it's one packet per song lyric.
yeah just a bunch of "raw data" and text. I thought I was doing something wrong until I cat the file. Normally one could do something like this.but WE have no real idea of the format in the file
outputCode:#include <stdio.h> #include <stdlib.h> #include "framehdr.h" #define SIZE_ETHERNET 14 #define SIZE_BUFFER 1000 int main() { char buffer[SIZE_BUFFER]; FILE *file = fopen("TCPdump", "rb"); // Get total length of package in bytes int totLenPkg; fscanf(file, "%d", &totLenPkg); printf("Total length of package: %d", totLenPkg); // Read the package only fgets(buffer, SIZE_BUFFER, file); if (file == NULL) { printf("Error"); exit(1); } void* packet = malloc(totLenPkg); printf("\n\n"); printf("--- Ethernet ---\t"); printf("--- IP ---"); printf("\t\t--- TCP ---\n"); // Convert void* pointer to ethernet_hdr* pointer struct ethernet_hdr* getEthernet = (struct ethernet_hdr*)packet; fread(packet, totLenPkg, 1, file); // Convert void* pointer to ip_hdr* pointer and get IP-package struct ip_hdr *getIP = (struct ip_hdr*)(packet + SIZE_ETHERNET); unsigned char *srcAdress = (unsigned char*)&getIP->src; unsigned char *dstAdress = (unsigned char*)&getIP->dst; // Size of IP int sizeIP = IP_HL(getIP); printf("\nsizeIP: %d\n", sizeIP); // The source adress printf("\nsrc: "); int i; for (i = 0; i < 4; i++) { printf("%d.", srcAdress[i]); } // The destination adress printf("\ndst: "); int j; for (j = 0; j < 4; j++) { printf("%d.", dstAdress[j]); } /* // TCP-package struct tcp_hdr* getTCP = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP); int sizeTCP = TH_OFF(getTCP); printf("\nsizeTCP: %d", sizeTCP); // Payload-package struct tcp_hdr* getPayload = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP + sizeTCP); unsigned char *str = (unsigned char*)getPayload; */ printf("\n"); //Notes /* * IP header struct ip_hdr { unsigned char vhl; unsigned char tos; unsigned short len; unsigned short id; unsigned short off; unsigned char ttl; unsigned char p; unsigned short ip_sum; unsigned int src, dst; }; */ struct ip_hdr getPayload; while ( fread(&getPayload, sizeof(getPayload),10, file) == 10 ) { printf("\n%c %c %hu %hu %hu %c %c %hu %d %d\n", getPayload.vhl, getPayload.tos, getPayload.len, getPayload.id, getPayload.off, getPayload.ttl, getPayload.p, getPayload.ip_sum,getPayload.src,getPayload.dst); } free(packet); fclose(file); return 0; }
that is just using the one other struct he has, so I have no idea what to grab and when to grab it and when to change it to another struct to get that filled. and why pointers?Code:userx@slackwhere:~/bin $ ./Laboration3 Total length of package: 100 --- Ethernet --- --- IP --- --- TCP --- sizeIP: 20 src: 194.47.143.36. dst: 172.217.17.35. 1 12336 32778 62086 h à 177 285203216 1157629952 e n 2560 13880 32778 † ò 57448 -619708239 134222079 € 62086 57448 177 Û 4351 1157629952 -330432000 w r 29801 101 12554 0 0 10 285203216 -226066432
the struct and names used may have been changed to protect the innocent.Code:Laboration3.c:45:52: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith] struct ip_hdr *getIP = (struct ip_hdr*)(packet + SIZE_ETHERNET);
Last edited by userxbw; 12-16-2017 at 04:29 PM.
Just saying, it may be awkward, but I think the pointer arithmetic you commented out is important. Besides, after that the song lyric should be in str. Maybe!
Last edited by whiteflags; 12-16-2017 at 04:30 PM.
The structure of the file is given by the OPs program. Here's a look at the first part of the data:
For each "packet" there is a text integer followed by a newline. That tells you how many bytes are in the rest of the message.Code:00000000 31 30 30 0a 00 10 db ff 10 00 80 86 f2 68 e0 b1 |100..........h..| 00000010 08 00 45 00 00 7d e4 d6 40 00 40 06 46 54 c2 2f |..E..}..@[email protected]./| 00000020 8f 24 ac d9 11 23 8d d3 00 50 07 2a c4 ce 44 b3 |.$...#...P.*..D.| 00000030 d0 b5 80 18 00 e5 0c 98 00 00 01 01 08 0a 06 ed |................| 00000040 20 1e 84 78 56 d9 49 27 6d 20 64 72 65 61 6d 69 | ..xV.I'm dreami| 00000050 6e 67 20 6f 66 20 61 20 77 68 69 74 65 20 43 68 |ng of a white Ch| 00000060 72 69 73 74 6d 61 73 00 0a 31 30 30 0a 80 86 f2 |ristmas..100....| 00000070 68 e0 b1 00 10 db ff 10 00 08 00 45 00 02 4e 8e |h..........E..N.| 00000080 73 00 00 37 06 e3 e6 ac d9 11 23 c2 2f 8f 24 00 |s..7......#./.$.| 00000090 50 8d d3 44 b3 d0 b5 07 2a c5 17 80 18 00 a6 45 |P..D....*......E| 000000a0 d1 00 00 01 01 08 0a 84 78 56 f5 06 ed 20 1e 4a |........xV... .J| 000000b0 75 73 74 20 6c 69 6b 65 20 74 68 65 20 6f 6e 65 |ust like the one| 000000c0 73 20 49 20 75 73 65 64 20 74 6f 20 6b 6e 6f 77 |s I used to know| 000000d0 00 0a 39 34 0a 00 10 db ff 10 00 80 86 f2 68 e0 |..94..........h.| etc...
The message structure is:
- ethernet_hdr
- ip_hdr
- tcp_hdr
- extra crap
- the text message
The macro IP_HL gives the size of ip_hdr.
The macro TH_OFF gives the size of tcp_hdr and the extra crap together.
Using all that info, you can find the position and length of the text message.
The OP is actually pretty close, but has gone off the rails at the end.
He basically just needs a loop controlled by his initial fscanf.
A little inaccuracy saves tons of explanation. - H.H. Munro
A loop controlled by my initial fscanf? This one?:
Do you mean that I have to loop like the whole programCode:// Get total length of package in bytes int totLenPkg; fscanf(file, "%d", &totLenPkg); printf("Total length of package: %d", totLenPkg);
from the initial line of fscanf? Or just a loop somehow
using fscanf at the end of the program?
Sorry, but I find this assignment very difficult.
Well, to be specific, in post #29 I pasted what I think you need to loop. There will be minor changes to the program beyond looping that part; you will need to delete other code that isn't doing something helpful and print out the payload.
It would probably be good to address some of the warnings in the program too, particularly the ones about void*. malloc()'s return value isn't meant to stay void, you can call it and have it return to a structure pointer assignment.
Yes. As an example to print out just the text in each packet:
That's assuming that the structs are "packed" (have no extra padding bytes), which they seem to be. And it's only one way of doing it. The final printf works because the strings always end with a '\0' (and then, interestingly, a '\n').Code:#include <stdio.h> #include <stdlib.h> #include "framehdr.h" int main() { FILE *f = fopen("TCPdump", "rb"); if (f == NULL) { perror("fopen"); exit(EXIT_FAILURE); } int len; while (fscanf(f, "%d", &len) == 1) { fgetc(f); // eat the newline char *b = malloc(len); fread(b, len, 1, f); int skip = sizeof(struct ethernet_hdr); int ip_hl = IP_HL((struct ip_hdr*)(b + skip)); skip += ip_hl; int th_off = TH_OFF((struct tcp_hdr*)(b + skip)); skip += th_off; printf("%s\n", b + skip); free(b); } fclose(f); return 0; }
Now that I look more closely I see that each packet is separated by an extra newline that is not part of the count. The reason the above code works is that the fscanf skips whitespace before reading the integer, so it automatically skips the extra newline before the number.
So the structure is:
text integer
'\n'
ethernet_hdr
ip_hdr
tcp_hdr
extra stuff (of size TH_OFF() - sizeof(struct tcp_hdr))
text message ending with a '\0'
'\n'
The fact that the text message ends with '\0''\n' means it is readable by fgets (which stops after reading the newline, but presumably reads the '\0', terminating the string before the newline).
It's an interesting format, part text part binary.
Last edited by john.c; 12-16-2017 at 06:32 PM.
A little inaccuracy saves tons of explanation. - H.H. Munro
Thanks to all replies, but I actually figured out a way to get each package in the payload
using another way.
And it is now printing every sentence of the song
Apparently, it worked in Dev-C++ but not in Visual Studio 2017.
The program crashes when reading the last package. Due to reading
past the allocated memory I was told. It was a '\n' character being
read at the end of the file that shouldn't be read.
Can someone please help me to get that part down since I've
figured out pretty much of the rest I guess.
Code:#pragma warning(disable:4996) #include <stdio.h> #include <stdlib.h> #include <string.h> #include "framehdr.h" #define SIZE_ETHERNET 14 #define SIZE_BUFFER 1000 #define SIZE_SRC_DST 4 FILE* readInFile(); void printPackages(unsigned char* payload, unsigned char* src, unsigned char* dst); void getPayloadPackagesContent(FILE *file, char buffer[]); int main() { char buffer[SIZE_BUFFER]; int pkgCounter = 1; FILE* file = readInFile(); fseek(file, 0, SEEK_END); int endPos = ftell(file); rewind(file); // Using loop to get all payload packages int curpos; do { printf("\n\n"); printf("--- Pkt %d ---\t", pkgCounter++); getPayloadPackagesContent(file, buffer); curpos = ftell(file); } while (endPos != (curpos - 1)); // fgets(buffer, SIZE_BUFFER, file) != NULL //getchar(); fclose(file); return 0; } FILE* readInFile() { char readInFile[SIZE_BUFFER]; printf("What file do you want to use? "); scanf("%s", readInFile); getchar(); FILE *file = fopen(readInFile, "rb"); if (file == NULL) { printf("Error opening file!"); exit(1); } return file; } void printPackages(unsigned char* payload, unsigned char* src, unsigned char* dst) { //if (strcmp(payload, "")) { // Here I need to get to the next sentence somehow printf("\n"); printf("Payload: \t%s", payload); // The source adress printf("\nsrc: \t\t"); int i; for (i = 0; i < SIZE_SRC_DST; i++) { printf("%d.", src[i]); } // The destination adress printf("\ndst: \t\t"); int j; for (j = 0; j < SIZE_SRC_DST; j++) { printf("%d.", dst[j]); } //} } void getPayloadPackagesContent(FILE *file, char buffer[]) { // Get total length of package in bytes int totLenPkg; fscanf(file, "%d", &totLenPkg); // Read the package only fgets(buffer, SIZE_BUFFER, file); char* packet = malloc(totLenPkg); /*printf("\n\n"); printf("--- Pkt %d ---\t", pkgCounter++);*/ // Convert void* pointer to ethernet_hdr* pointer struct ethernet_hdr* getEthernet = (struct ethernet_hdr*)packet; fread(packet, totLenPkg, 1, file); // Convert void* pointer to ip_hdr* pointer and get IP-package struct ip_hdr *getIP = (struct ip_hdr*)(packet + SIZE_ETHERNET); unsigned char *srcAdress = (unsigned char*)&getIP->src; unsigned char *dstAdress = (unsigned char*)&getIP->dst; // Size of IP int sizeIP = IP_HL(getIP); // TCP-package struct tcp_hdr* getTCP = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP); // Size of TCP-package int sizeTCP = TH_OFF(getTCP); // Payload-package struct tcp_hdr* getPayload = (struct tcp_hdr*)(packet + SIZE_ETHERNET + sizeIP + sizeTCP); unsigned char *str = (unsigned char*)getPayload; printPackages(str, srcAdress, dstAdress); free(packet); }
Last edited by DecoratorFawn82; 12-18-2017 at 03:47 AM.
Don't mind previous post. I found a way to solve it