beacon frame captured by libpcap is something strange - c

I captured beacon frame with library libpcap(Ubuntu, c)
I changed wlan mode to monitor and captured by following function calls
// 3000 is large enough number for test
pcd = pcap_open_live(dev,3000,PROMISCUOUS,-1,errbuf)
// filter with "wlan type mgt subtype beacon"
pcap_compile(pcd,&bpg,"wlan type mgt subtype beacon",1,PCAP_NETMASK_UNKNOWN)
pcap_setfilter(pcd, &bpg)
and following is packet_view
void packet_view(
unsigned char *user,
const struct pcap_pkthdr *h,
const unsigned char *p
){
int len;
len = 0;
printf("PACKET\n");
while(len < h->len) {
printf("%02x ", *(p++));
if(!(++len % 16))
printf("\n");
}
printf("\n");
return ;
}
and my got following result (just most significant 32bits)
00 00 12 00 2e 48 00 00 00 02 6c 09 a0 00 bb 01
00 00 80 00 00 00 ff ff ff ff ff ff 00 08 9f bf
but... actually beacon frame must start with bit "08"
because beacon frame's protocol version = 00 type = 00 and subtype = 1000 => 00001000(08)
what is the reason that i got packet start with 00? althougt I filtered with "wlan type mgt subtype beacon" ??

You're missing one pcap call - a call to pcap_datalink().
Unless pcap_datalink() returns DLT_IEEE802_11, the packet does NOT begin with an 802.11 header. If, for example, it returns DLT_IEEE802_11_RADIO, the packet begins with a radiotap header, and has an 802.11 header after it; that looks like what your packet has.
See the tcpdump.org link-layer header types page for information on the values pcap_datalink() can return and the values that appear in pcap and pcap-ng files.

Set your filter to
"link[0] == 0x80"
Works for me!
Since apparently
https://wiki.wireshark.org/CaptureFilters
Capture WLAN traffic without Beacons:
link[0] != 0x80

Related

is there a function in a c lib to print data packets similar to Wireshark format (position then byte by byte)

Is there a function in a C lib to print data packets similar to Wireshark format (position then byte by byte)
I looked up their code and they use trees which was too complex for my task. I could also write my own version from scratch but I don't wanna be reinventing the wheel, so I was wondering if there is some code written that I can utilize. Any suggestions of a lib that I can use?
*The data I have is in a buffer of unsigned ints.
0000 01 02 ff 45 a3 00 90 00 00 00 00 00 00
0010 00 00 00 00 00 00 00 00 00 00 00 00 00
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 ... etc
Thanks!
I doubt such a specific function exists in the libC, but the system is rather simple:
for (unsigned k = 0; k < len; k++)
{
if (k % 0x10 == 0)
printf("\n%04x", k);
if (k % 0x4 == 0)
printf(" ");
printf(" %02x", buffer[k] & 0xff);
}
Replace the first modulo by the line length, and the second by the word length and you're good (of course, try to make one a multiple of the other)
EDIT:
As I just noticed you mentioned the data you have is in a buffer of unsigned ints, you will have to cast it to an unsigned char buffer for this part.
Of course, you can do it with an unsigned buffer with bitwise shifts and four prints per loop, but that really makes for cumbersome code where it isn't necessary

Unable to Display Packet's Ethertype

So, I have a program to sniff packets, and so far it has been working very well. I am now trying to add additional functionality, but I keep running into problems when I try to decode the ethertype of a captured packet's Ethernet header. To isolate the location in which the error is occurring, I wrote a modified program to dump only the Ethernet header in hexadecimal, and then, using custom headers, decode the the source MAC address, destination MAC address, and ethertype, but this is the output:
Sniffing on device wlan0
308 BYTE PACKET
01 00 5e 00 00 fb 04 e5 36 4a 5d 3a 08 00 | ..^.....6J]:..
SRC 01:00:5e:00:00:fb DST 04:e5:36:4a:5d:3a TYPE 0000
328 BYTE PACKET
33 33 00 00 00 fb 04 e5 36 4a 5d 3a 86 dd | 33......6J]:..
SRC 33:33:00:00:00:fb DST 04:e5:36:4a:5d:3a TYPE ff11
194 BYTE PACKET
01 00 5e 00 00 fb 04 e5 36 4a 5d 3a 08 00 | ..^.....6J]:..
SRC 01:00:5e:00:00:fb DST 04:e5:36:4a:5d:3a TYPE 0000
Captured 3 packets
Apparently, the program has no problem decoding the MAC addresses, which are the first twelve bytes of the fourteen byte header, but, for some reason, when it reaches the final two bytes comprising the ethertype, the program fails to display them properly. The first and third packets' ethertypes are 0x0800, or IP, and the second packet's ethertype is 0x86dd, or IPv6. I have tried displaying the ethertype in numerous formats, but none have yielded proper results.
These are the lines of code responsible for displaying the MAC addresses and ethertype:
ethernet_header = (const struct sniff_ethernet_hdr *)packet;
printf ("SRC %02x", ethernet_header->ether_shost[0]);
for (i = 1; i < ETH_ALEN; i++)
printf (":%02x", ethernet_header->ether_shost[i]);
printf (" DST %02x", ethernet_header->ether_dhost[0]);
for (i = 1; i < ETH_ALEN; i++)
printf (":%02x", ethernet_header->ether_dhost[i]);
printf (" TYPE %.4x", ethernet_header->ether_type);
printf ("\n");
Does anyone have any suggestions or notice any problems with the code?
EDIT: I continued to play with this program, and I discovered something strange. I set a pointer called eth_ptr to point to the thirteenth byte of the packet, where the ethertype begins. When I dereferenced this pointer and printed the result, it was, indeed, the first byte of the ethertype. So, I added a line to the program that prints the addresses of eth_ptr and the ethertype of the Ethernet header struct. These are the results:
Sniffing on device wlan0
104 BYTE PACKET
01 00 5e 00 00 fb 04 e5 36 4a 5d 3a 08 00 | ..^.....6J]:..
SRC 01:00:5e:00:00:fb DST 04:e5:36:4a:5d:3a TYPE 8
eth_ptr # 0x7ffafd0b1944 ether_type # 0x7ffafd0b194c
124 BYTE PACKET
33 33 00 00 00 fb 04 e5 36 4a 5d 3a 86 dd | 33......6J]:..
SRC 33:33:00:00:00:fb DST 04:e5:36:4a:5d:3a TYPE 86
eth_ptr # 0x7ffafd0b1944 ether_type # 0x7ffafd0b194c
319 BYTE PACKET
01 00 5e 00 00 fb 04 e5 36 4a 5d 3a 08 00 | ..^.....6J]:..
SRC 01:00:5e:00:00:fb DST 04:e5:36:4a:5d:3a TYPE 8
eth_ptr # 0x7ffafd0b1944 ether_type # 0x7ffafd0b194c
Captured 3 packets
$ gdb -q
(gdb) p /x 0x7ffafd0b194c - 0x7ffafd0b1944
$1 = 0x8
The type that is being printed is really the dereferenced pointer, which points to the first byte of the ethertype. This pointer is located eight bytes before ethernet_header->ether_type in memory; therefore, the problem is that the ethertype element of the struct is located eight bytes ahead of where it is supposed to be. I do not know why this is, or how to fix this. Can anyone offer an explanation?
EDIT AGAIN: Well, I am a fool. I just took a close look at the Ethernet header structure:
struct sniff_ethernet_hdr
{
uint8_t ether_shost[ETH_ALEN];
uint8_t ether_dhost[ETH_HLEN];
uint16_t ether_type;
} __attribute__ ((__packed__));
The macros:
#define ETH_ALEN 6
#define ETH_HLEN 14
After I fixed this careless mistake, the program ran flawlessly.

How can I change char array to int using C?

i am studying C now, and I am parsing a raw registry file and read it.
i have some problem now,
000011E0 00 00 00 00 60 01 00 00 B9 01 00 00 00 00 00 00
000011F0 20 C0 26 00 FF FF FF FF 00 00 00 00 FF FF FF FF
00001200 10 FC 00 00 FF FF FF FF 4C 00 01 00 00 00 00 00
this is hex value of REGISTRY file.
fseek(fp,0x11F0,SEEK_SET);
char tmp[4];
int now = ftell(fp);
for(int i = 0 ; i < 4 ; i++){
tmp[i] = fgetc(fp);
}
I made this tmp array, but I need 0x0026c020.
how can I change this array to that value? or please suggest me better algorithm.
Thanks.
If you know for a fact that the value is stored with the same endianness as the host OS architecture, you can just do:
int value = *(int *)tmp;
However, you should not read the bytes in backwards order, as you do here -- that alters the endianness and will result in an incorrect value. Try this:
int value;
if (fread(&value, sizeof(value), 1, fp) != 1) {
/* Could not read, handle error. */
}
/* value is set, inspect it */
To convert a string into integer there are already available functions one such function is
strtoul().
you can use standard strtoul() function to convert string into integer values.

Writing data to file but file still contain NULL

Related to my previous post but its not a duplicate of that.Now I have tried something and
Here I am asking you about the logical error in code.
/*u_int8_t ....etc are alias for uint8_t...etc so don't bother about them*/
void crypt(u_int8_t *key, u_int32_t keylen,
u_int8_t *data, u_int32_t datalen)
{
FILE *fp,*fq;
fp=fopen("key","w");
fputs((char *)key,fp);
fq=fopen("file.txt","w");
d=0;
while(data[d]) {
fputc((int)data[d],fq);
d++;
}
fputc('\0',fq);
fclose(fp);
fclose(fq)
}
Output :
udit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $ cat key
kaheudit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $ cat file.txt
udit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $
Key gets printed to file but not the data.
Now when I slightly modify the code :
void
crypt(u_int8_t *key, u_int32_t keylen,
u_int8_t *data, u_int32_t datalen)
{
int d,k;
FILE *fp,*fq;
fp=fopen("key","w");
fputs((char *)key,fp);
fq=fopen("file.txt","w");
for (d=0, k=0; d < datalen; ++d, k = (k+1)%keylen) {
data[d] ^= key[k];
fputc(data[d],fq);
}
fclose(fp);
fclose(fq);
}
Now key as well as data gets printed...although data is not exactly correct(but it is able to be written down into the file)
udit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $ cat key
kaheudit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $ cat file.txt
kthpOWWkahe;c��"�he
kajcudit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $
The call to the crypt function is as follows -
bool
espcrypto(esp_private *epriv, sendip_data *data, sendip_data *pack)
{
u_int32_t keylen;
u_int8_t *key;
static u_int8_t fakekey;
struct ip_esp_hdr *esp = (struct ip_esp_hdr *)pack->data;
if (!epriv->keylen) { /* This isn't going to be very productive... */
key = &fakekey;
keylen = 1;
} else {
key = (u_int8_t *)epriv->key;
keylen = epriv->keylen;
}
/* Encrypt everything past the ESP header */
crypt(key, keylen,
(u_int8_t *)esp->enc_data,
pack->alloc_len + data->alloc_len
- sizeof(struct ip_esp_hdr));
return TRUE;
}
The following packet describe what data I actually need to write down to the file...
udit#udit-Dabba ~/Downloads/sendip-2.5-mec-2/mec $ sendip -v -p ipv6 -dabcd -6s ::1 -p
esp -es 0x20 -eq 0x40 -ek "kahe" -ec crypt.so -p tcp -ts 21 -td 21 ::2
Added 43 options
Initializing module ipv6
Initializing module esp
Initializing module tcp
Finalizing module tcp
Finalizing module esp
Finalizing module ipv6
Final packet data:
60 00 00 00 `...
00 24 32 20 .$2
00 00 00 00 ....
00 00 00 00 ....
00 00 00 00 ....
00 00 00 01 ....
00 00 00 00 ....
00 00 00 00 ....
00 00 00 00 ....
00 00 00 02 ....
00 00 00 20 ...
00 00 00 40 ...#
6B 74 68 70 kthp /*data portion starts from here*/
4F 57 1F 57 OW.W
6B 61 68 65 kahe
3B 63 97 9A ;c..
22 C0 68 65 ".he
0A 03 0B 01 ....
6B 61 6A 63 kajc /*data portion ends here*/
Freeing module ipv6
Freeing module esp
Freeing module tcp
Please help me.... I haven't receiver any satisfactory implementation on my previous post still so trying my own hand.Really need it ..
You're using string semantics to handle binary data. That's not going to work. If you look closely you'll see that the first character in your file.txt example output is k, which is also the first character of the key. That means your data is starting with a NUL byte and the while loop will instantly exit.
First of all you need to open the files in binary mode:
fp=fopen("key","wb");
fq=fopen("file.txt","wb");
To write the key use
fwrite(key, keylen, 1, fp);
and then use the for loop in your second example to write the data. I can't see anything wrong with that one, your problem might simply have been the binary vs text mode.
Edit: Try using hexdump -C file.txt to view your file instead of cat.
Here
while(data[d]) {
fputc((int)data[d],fq);
d++;
}
data[d] is 0 (as it is binary data), so it will leave the loop "too" soon.

How can I access members of a struct when it's not aligned properly?

I'm afraid that I'm not very good at low level C stuff, I'm more used to
using objects in Obj-c, so please excuse me if this is an obvious question, or if I've completely misunderstood something...
I am attempting to write an application in Cocoa/Obj-C which communicates with an external bit of hardware (a cash till.) I have the format of the data the device sends and receives - and have successfully got some chunks of data from the device.
For example: the till exchanges PLU (price data) in chunks of data in the following format: (from the documentation)
Name Bytes Type
Name Bytes Type
PLU code h 4 long
PLU code L 4 long
desc 19 char
Group 3 char
Status 5 char
PLU link code h 4 long
PLU link code l 4 long
M&M Link 1 char
Min. Stock. 2 int
Price 1 4 long
Price 2 4 long
Total 54 Bytes
So I have a struct in the following form in which to hold the data from the till:
typedef struct MFPLUStructure {
UInt32 pluCodeH;
UInt32 pluCodeL;
unsigned char description[19];
unsigned char group[3];
unsigned char status[5];
UInt32 linkCodeH;
UInt32 linkCodeL;
unsigned char mixMatchLink;
UInt16 minStock;
UInt32 price[2];
} MFPLUStructure;
I have some known sample data from the till (below) which I have checked by hand and is valid
00 00 00 00 4E 61 BC 00 54 65 73 74 20 50 4C 55 00 00 00 00 00 00 00 00 00 00 00 09 08 07 17 13 7C 14 04 00 00 00 00 09 03 00 00 05 BC 01 7B 00 00 00 00 00 00 00
i.e.
bytes 46 to 50 are <7B 00 00 00> == 123 as I would expect as the price is set to '123' on the till.
byte 43 is <05> == 5 as I would expect as the 'mix and match link' is set to 5 on the till.
bytes 39 to 43 are <09 03 00 00> == 777 as I would expect as the 'link code' is set to '777' on the till.
Bytes 27,28,29 are <09 08 07> which are the three groups (7,8 & 9) that I would expect.
The problem comes when I try to get some of the data out of the structure programmatically: The early members work correctly right up to, and including the five 'status' bytes. However, members after that don't come out properly. (see debugger screenshot below.)
Image 1 - http://i.stack.imgur.com/nOdER.png
I assume that the reason for this is because the five status bytes push later members out of alignment - i.e. they are over machine word boundaries. Is this right?
Image 2 - i.imgur.com/ZhbXU.png
Am I right in making that assumption?
And if so, how can I get the members in and out correctly?
Thanks for any help.
Either access the data a byte at a time and assemble it into larger types, or memcpy it into an aligned variable. The latter is better if the data is known to be in a format specific to the host's endianness, etc. The former is better if the data follows an external specification that might not match the host.
If you're sure that endianness of host and wire agree, you could also use a packed structure to read the data in a single pass. However, this is compiler-specific and will most likely impact performance of member access.
Assuming gcc, you'd use the following declarations:
struct __attribute__ ((__packed__)) MFPLUStructure { ... };
typedef struct MFPLUStructure MFPLUStructure;
If you decide to use a packed structure, you should also verify that it is of correct size:
assert(sizeof (MFPLUStructure) == 54);

Resources