开发者

how to check a bit is enabled or not in array of hexadecimal digit

开发者 https://www.devze.com 2023-03-17 20:54 出处:网络
#include<iostream> #define check_bit(var,pos) {return (var & (1 << pos))!=0;} using namespace std;
#include<iostream>
#define check_bit(var,pos) {return (var & (1 << pos))!=0;}

using namespace std;

int main()
{
uint8_t temp[150]={0x00,0x02,0x17,0xe2,0x1c,0xa8,0x00,0x30,0x96,0xe1,0x8c, 0x38,
 0x88, 0x47, 0x00 ,0x01 ,
0x30, 0xfe, 0x00, 0x01 ,0x31, 0xfe, 0x45, 0x00,  0x00 ,0x64, 0x3b, 0x89 ,0x00, 0
x00 ,0xfe, 0x01 ,
0x33, 0x5a, 0xc0 ,0xa8 ,0x79 ,0x02 ,0x0a, 0x0a,  0x0a, 0x01, 0x08, 0x00, 0xe3, 0
x86, 0x00, 0xea,
0x01, 0xd2, 0x00, 0x00, 0x00, 0x05, 0x02, 0x6a, 0x95 ,0x98, 0xab ,0xcd ,0xab, 0x
cd ,0xab, 0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,  0xab, 0xcd ,0xab, 0xcd ,0xab ,0
xcd ,0xab, 0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd,  0xab, 0xcd ,0xab ,0xcd ,0xab ,0
xcd, 0xab ,0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd , 0xab, 0xcd ,0xab, 0xcd, 0xab, 0
xcd, 0xab ,0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd , 0xab, 0xcd
};

uint16_t *ptr1=(uint16_t*)&temp[0];

while(!(*(ptr1+0)==0x88 && *(ptr1+1)==0x47))
{
ptr1++;
}

cout<<"MPLS packet";

uint32_t *ptr2=(uint32_t*)&temp[0];

cout<<"4 bytes accessed at a time";

ptr2++;

while(check_b开发者_如何学JAVAit(*(ptr+3),7)!=1)
{
cout<<"bottom of the stack:label 0";
ptr2++;
}
cout<<"mpls label:1";
return 0;
}

The program is intended to identify packet is MPLS or not by accessing two bytes at a time and checking presence of 88 and 47 packets and if MPLS packet then it should access four packets at a time and check 3rd byte(30 in this case) is enabled or not.If not enabled then access next four bytes and check byte is enabled or not.I have written program but it is not working.Please someone help me.I am not able to access individual element of array.if i give cout<<temp[0] it gives garbage value

Please help


First thing I noticed is that your code looks for consecutive 16-bit values of 0x88 and 0x47, but in the packet itself these values seem to be 8-bit (1 byte each). If ptr1 is changed to be uint8_t*, it will be able to find the values. I don't know what the correct behavior for the rest of the code is so I can't check it.

In general, directly reading values that are bigger than 8 bits (e.g. uint16_t or uint32_t) from memory here may not be a good idea because your program will behave differently on little-endian and big-endian processors. And as ydroneaud mentions in a comment, some processors won't be able to read these values because you read them from unaligned addresses.


I think I can fix your program, but you better listen to the other folks who know networking stuff better than myself.

uint8_t *ptr=temp;

while(ptr[0]!=0x88 || ptr[1]!=0x47)
{
    ptr++;
}

cout<<"MPLS packet";

ptr+=2;

cout<<"4 bytes accessed at a time";

while(!check_bit(ptr[2],7))
{
    cout<<"bottom of the stack:label 0";
    ptr+=4;
}
cout<<"mpls label:1";
return 0;

Edit: to print individual bytes from the array you need to cast them to some integer type first. This is because uint8_t is most likely typedeffed as unsigned char which is interpreted by cout as a character code. Then you need to set the cout to hexadecimal mode:

cout << hex << (int)ptr[2] << endl;

Edit 2: there is an error in your check_bit() macro. A macro is not a function, but a piece of text that is copied as is (replacing the arguments) in place where its name is mentioned. It must be

#define check_bit(var,pos) (((var)&(1<<(pos)))!=0)

or define a function instead:

bool check_bit(int var, int pos) {return (var & (1 << pos))!=0;}


A little bit more worked out version of my comment: You should actually decode the network stack to be sure if MPLS is present, the 0x8847 value is not extremely unlikely to occur somewhere in payload, addressing schemes, ... .

To actually get to this you should decode the network stack. Lets assume you begin with an ethernet frame. Note first that most applications will give you data from the destination mac address onwards, preambles and such are discarded. So the 13th and 14th byte are the type field. This tells you what is encapsulated in ethernet, this is usually 0x0800 meaning IP. 0x8847 means a unicast static MPLS label. Other options are possible, for example ipv6 or vlan tags (described below). But note you can determine with certainty which offsets you use. You know what is encapsulated in the mac frame and where this encapsulated data starts (15th octet). Of course you see there are optional q-tags there, I explain these below.

Now as You are looking for 0x8847 I guess you have direct MPLS over ethernet, in which case you shouldn't go any further, but if your stack is more complex you'll have to decode also the next encapsulated data (e.g. IP) and take into account these sizes up until the point where you can find your MPLS header.

For ethernet there are 2 somewhat common options and that are dot1q and qinq tagging, or vlan tags. dot1q adds 4 bytes to the ethernet header, you can recognise this because the type field will be 0x8100, in this case the real type field (of what is encapsulated) will be 4 bytes further one (so the 17th byte) and the encapsulated data will start on the 19th byte. With qinq the type will be 0x9100 and the real type will be 8 bytes further on, so the 21th byte, the encapsulated data can be found from the 23rd byte onwards.

Of course, decoding the whole network stack implementation would be crazy. To start with you can ignore addressing, QoS, ... . You mostly need to find what is the type to the next header and where this starts (this can be influenced by optional fields like dot1q). Usually you know beforehand which kind of stack you have on your system. So it involves studying these headers and finding the fixed offset where you can find your MPLS header, which makes the work quite simple.

0

精彩评论

暂无评论...
验证码 换一张
取 消