Dear All,
I have a function with input parameter as const u_char *p. So when I write like this printf("\n\n Char value p : %.2x",(unsigned int)p[1]). It gives me a hex value. How to print the whole p value which method is best to use. I need to analyse it as this supposed to represent a network data packet.

Recommended Answers

All 55 Replies

If I understand what you want, you have to loop thru the whole "packet" printing each hex byte.
You want the output to look like that of the unix/linux command od:

0000000    cf  fa  ed  fe  07  00  00  01  03  00  00  80  02  00  00  00
0000010    0c  00  00  00  28  07  00  00  85  80  01  00  00  00  00  00
0000020    19  00  00  00  48  00  00  00  5f  5f  50  41  47  45  5a  45
0000030    52  4f  00  00  00  00  00  00  00  00  00  00  00  00  00  00
0000040    00  00  00  00  01  00  00  00  00  00  00  00  00  00  00  00
0000050    00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
0000060    00  00  00  00  00  00  00  00  19  00  00  00  78  02  00  00

Dear Histrung,
Yes I want to view the first few hundred bits of the packet itself. I am running this C programme on centos. So how should I go about it? I can view it in normal string too rite?

printf("\n\n Char value p : %.2x",(unsigned int)*p[1])

try this,

p is a pointer
so you need to see what it point to, by using *P to see what in that address, the value its self

Dear Aboody,
I dont get you want command to apply to view the add. Did you mean just like this printf("\n\n Char value p : %.2x",p)?

I think he wants an output like hexdump -C

$ hexdump -C a.out | more
00001c30  7c 04 00 00 ff 25 7e 04  00 00 ff 25 80 04 00 00  ||....%~....%....|
00001c40  ff 25 82 04 00 00 ff 25  84 04 00 00 ff 25 86 04  |.%.....%.....%..|
00001c50  00 00 ff 25 88 04 00 00  ff 25 8a 04 00 00 ff 25  |...%.....%.....%|
00001c60  8c 04 00 00 ff 25 8e 04  00 00 ff 25 90 04 00 00  |.....%.....%....|
00001c70  45 6e 74 65 72 20 74 68  65 20 74 6f 74 61 6c 20  |Enter the total |
00001c80  6e 75 6d 62 65 72 20 6f  66 20 73 74 75 64 65 6e  |number of studen|
00001c90  74 73 3a 20 00 45 6e 74  65 72 20 74 68 65 20 6e  |ts: .Enter the n|
00001ca0  61 6d 65 20 6f 66 20 73  74 75 64 65 6e 74 20 23  |ame of student #|
00001cb0  20 00 45 6e 74 65 72 20  74 68 65 20 73 63 6f 72  | .Enter the scor|
00001cc0  65 20 6f 66 20 73 74 75  64 65 6e 74 20 23 20 00  |e of student # .|
00001cd0  09 00 41 76 65 72 61 67  65 20 73 63 6f 72 65 20  |..Average score |
00001ce0  69 73 20 00 4c 8d 1d 6d  03 00 00 41 53 ff 25 5d  |is .L..m...AS.%]|

Dear Histrung,
So how loop to capture like what you have shown. Yes I want to capture as per your description. Thank you.

sorry if I made a mistake, if I had the program I can fix it, but then you have a pointer, printing it will give you a hex address,
however, adding * before the name will give you the value in that address

Dear Aboody,
Yes print it give me value just like this (unsigned int)p[1] but now how to know what is the max size of the array? That will help me to loop and next thing how to convert each hex array element into readable char value.

oh ok, Try to do

int size = sizeof(p)/sizeof(p[0]); then loop till you reach the size

let me know if it works lol

Use this as a template. Just make sure that if the packet size is not % 16 you print out the residue.

#include <stdio.h>
#include <ctype.h>
int main(){
   unsigned char x[256],i;

   for ( i=0; i<255; i++){
      x[i] = i;
   }
   int j=0,line=0,packSize=256; 
   while (j<(packSize/16)){
      printf("%06x: ",line++);
      for ( i=0; i<16; i++){
         printf("%02x ",x[j*16+i]);
      }
      printf("  |");
      for ( i=0; i<16; i++){
        if ( isprint(x[j*16+i]))
          printf("%c",x[j*16+i]);
        else
          printf(".");
      }
      printf("|\n");
      j++;
   }
   return 0;
}

Output:

000000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f   |................|
000001: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f   |................|
000002: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f   | !"#$%&'()*+,-./|
000003: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f   |0123456789:;<=>?|
000004: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f   |@ABCDEFGHIJKLMNO|
000005: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f   |PQRSTUVWXYZ[\]^_|
000006: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f   |`abcdefghijklmno|
000007: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f   |pqrstuvwxyz{|}~.|
000008: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f   |................|
000009: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f   |................|
00000a: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af   |................|
00000b: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf   |................|
00000c: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf   |................|
00000d: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df   |................|
00000e: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef   |................|
00000f: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe 00   |................|

Dear Aboody,
I tried just sizeof(p) and also sizeof(p)/sizeof(p[0]); both gave me same answer which is 8.

Dear All,
I am very surprise the sizeof(p) give me only 8. But when I tried p[8],p[9],p[10] it still give me 2 hex values. So is the size right or wrong here?

Is p a uchar *?
The answer is 8 because you must have 64-bit machine and a pointer is a 64-bit number which is 8 (sizeof(p)) bytes and p[0] is 1 byte. 8/1 = 8 (int size = sizeof(p)/sizeof(p[0]))

Dear Histrung,
Yes p is confirm u_char. So if just 8 then it will just loop 8 times and stop right? Then I wont get the whole packet am I right?

Yes, if p was defined as u_char *p; , you would have to know the size of the packet to loop over the whole packet.

#include <stdio.h>
#include <ctype.h>
int main(){
   unsigned char x[256],*p;
   printf("sizeof(x): %lu, sizeof(p): %lu\n",sizeof(x),sizeof(p));
   return 0;
}

Output:

$ ./a.out
sizeof(x): 256, sizeof(p): 8

ok wait, what I meant.
you have ONE array of Pointer P.
Size of P
divided by Size of one element of P, will only give how many element of this unknown size of array.

I really dont know what you are looking at, plus if I know what type of data, and code you are dealing with I can help further

Dear Aboody,
Actually I am using a tool called PF_RING. Then I am running a callback sample function given together with the tool. I have manage to analyse the packet header will all the elements. Now I want to look into the payload and grab some portion of the details. So the u_char *p is pointing to whole packet. I do know how to to grab just the payload and not the header details. Hope I am clearer. The callback function is in this form void dummyProcessPacket(const struct pfring_pkthdr *h, const u_char *p, const u_char *user_bytes).

Dear Histrung,
How to know the exact size of the packet then any method? I am still confuse why is that p is just giving size as 8 but it can refer to more then 8 elements. Besides that in the tool I am using it self there is 2 more extra value regarding packet length I can take is u_int32_t caplen; /* length of portion present*/ and u_int32_t len /* length this packet (off wire) */

When calling pfring_open you have to give a capture length, because you want to look at the whole packet this value must be as large as the largest packet you are going to get. If the caplen in the header is less than len then you didn't make the capture length large enough, you should print out an error so you know to increase the capture size.
Use len not caplen.

Dear Histrung,
So your suggestion is run the loop based on len then capture each of the double hex value then convert according to your suggestion is it? I notice most of the time the len is same caplen but at times is rises to a very high number more then 1000, but caplen remain in 100++.

Dear Histrung,
Just I did a small test using your example I did this printf("\n\n Char value p : %c",p[1]) it print just question mark.

You need to loop over the size of the packet.

Dear Histrung,
Ok I will take your advice on that and go with the len. Now my challenge is how to convert each of the 2 hex value into a nice readable character? I tried just like this printf("\n\n Char value p : %c",p[1])

Use the code I posted on page 2. The printing of the array x[ ] is like your packet array.

Dear Histung,
Correct me based on my analysis. So where must I put my looping here? What does this line do while (j<(packSize/16)){? I know the j is keep adding right?

unsigned char x[256],i;
 
   for ( i=0; i<255; i++){
      x[i] = i;
   }
   int j=0,line=0,packSize=256; 
   while (j<(packSize/16)){
      printf("%06x: ",line++);
      for ( i=0; i<16; i++){
         printf("%02x ",x[j*16+i]);
      }
      printf("  |");
      for ( i=0; i<16; i++){
        if ( isprint(x[j*16+i]))
          printf("%c",x[j*16+i]);
        else
          printf(".");
      }
      printf("|\n");
      j++;
   }

In this example x is your p and packetSize is your len.

Dear Histung,
Below are some sample results I got. Do you think it makes sense it looks like the data is being repeated right.

D000000: 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70    |pppppppppppppppp|
000001: d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4    |................|
000002: 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03    |................|
000003: 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36    |6666666666666666|
000004: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7    |................|
000005: 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e 6e    |nnnnnnnnnnnnnnnn|
000006: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61    |aaaaaaaaaaaaaaaa|
000007: 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e 3e    |>>>>>>>>>>>>>>>>|
000008: 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d 6d    |mmmmmmmmmmmmmmmm|
000009: 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62    |bbbbbbbbbbbbbbbb|
D8000000: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30    |0000000000000000|
000001: 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34    |4444444444444444|
000002: a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2    |................|
000003: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b    |kkkkkkkkkkkkkkkk|
D000000: 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70    |pppppppppppppppp|
000001: d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4 d4    |................|
000002: 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03    |................|
000003: b4 b4 b4 b4 b4 b4 b4 b4 b4 b4 b4 b4 b4 b4 b4 b4    |................|
000004: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02    |................|
000005: 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f    |////////////////|
000006: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e    |................|
000007: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61    |aaaaaaaaaaaaaaaa|
000008: 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75    |uuuuuuuuuuuuuuuu|
000009: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61    |aaaaaaaaaaaaaaaa|

Look odd. Post the code calling the print function and the print function you made from mine.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.