2013-10-29 1 views
0

배경 :읽기 필드

내가 필드의 집합을 정의하는 비트 배열/비트 맵 작업에 관심이 있어요. 특히, 나는 radiotap 헤더를 구문 분석하고 싶습니다만, 개념적으로 문제가있는 것입니다 (또는, 아마도이 모든 것이 어떻게 작동하는지에 대해 뭔가 빠져있는 것 같습니다).

비트 맵에 의해 설명 된 필드 인 radiotap 헤더는 위의 링크에서 정의됩니다.

질문 : 내 데이터를하고 u char 스트림 인 경우 비트 맵과 필드의 값을 읽는 가겠어요 그렇다면 예를 들어

(편집)? 비트 맵에서 비트 맵의 ​​존재를 알 수있는 특정 필드에 어떻게 액세스합니까?

여기 해결책은 비트 시프 팅/마스킹과 관련이있을 것 같지만 이것이 로우 쉐어 프로그래밍에 대한 나의 첫 번째 시도이며이 문제를 해결하는 방법을 알지 못합니다.

편집 :

나는의 u_char 포인터에서 802.11 프레임에서 읽고 있어요 내 문제에 대한 현재

,하지만 난 프로그래밍 방식으로 내가 알고있는 헤더 및 필드를 액세스하려면 여기에서 이동하는 위치에 붙어 먼저, 무선 태그 헤더가된다.

//defined by library I'm using 
struct packet_header { 

    struct timeval ts; /*timestamp*/ 
    bpf_u_int32 caplen; /*number of stored bytes*/ 
    bpf_u_int32 length; /*total length of packet*/ 

} 

struct packet_header hdr; //see above, basic info 
u_char *packet //the data 

for(int i = 0; i < hdr->length; i++){ 

    //parse/analyse data contained in the frame/packet (1st radiotap) 
    packet[i] //do something with u_char here, but what exactly? 


} 
+0

코드 표시 (여기)주세요! –

+0

@ g-makulik 여기에 유용한 코드가 없습니다.이와 같은 문제에 착수하여 구조 작업 방법을 아는 것이 더 중요합니다. – amoeba

+0

링크 된 페이지의 일부를 읽을 수도 있습니다. 파싱 ​​라이브러리에 대한 링크뿐만 아니라 작동 원리를 설명합니다. –

답변

2

나는 당신이 매우 신중하게이 페이지를 공부할 것을 제안 : http://www.radiotap.org/Radiotap

헤더의 it_present 필드는 필드가 헤더에 따라 무엇을 나타냅니다. 그리고 존재하는 필드는 가장 낮은 것부터 가장 높은 것까지 순서대로 비트 수에 따라 정렬됩니다. 예를 들어 it_present의 첫 번째 0이 아닌 비트가 비트 3이면 헤더 다음의 첫 번째 필드가 채널이됩니다.

이 프로토콜은 매우 복잡하며 따라야하는 많은 규칙이 있습니다. 예를 들어 비트 31이 it_present으로 설정되면 머리글 바로 다음에 오는 필드 대신 먼저 존재 비트가 더 많습니다. 또한 필드의 정렬을 알고 있어야합니다. 32 비트 필드가 4 바이트 경계에 정렬되고 64 비트 필드가 8 바이트 경계에 정렬되도록 필드 사이에 패딩이있을 수 있습니다.

편집 : packet이 radiotap 헤더의 시작 부분을 가리키고 pkt_len이 바이트 수라고 가정 해 봅시다. 다음과 같이 시작할 수 있습니다.

pkt_len = hdr.length; 
if (pkt_len >= sizeof(ieee80211_radiotap_header)) 
{ 
    u_int16_t it_len; 
    u_int32_t it_present; 
    u_int32_t tmpMask; 
    u_int32_t* pExtraMask; 
    u_int32_t* pNextMask; 
    u_int32_t uMask; 
    int  iFldNum; 

    ieee80211_radiotap_header* pPktHdr = (ieee80211_radiotap_header*) packet; 
    pkt_len -= sizeof(ieee80211_radiotap_header); 
    packet += sizeof(ieee80211_radiotap_header); 
    it_len = le16_to_cpu(pPktHdr->it_len);   // Get radiotap packet length from header 
    it_present = le32_to_cpu(pPktHdr->it_present); // Get present field bitmask 

    // Find end of radiotap header 
    tmpMask = it_present; 
    pExtraMask = pNextMask = (u_int32_t*) packet; 
    while ((tmpMask & 0x80000000) && (pkt_len >= sizeof(u_int32_t))) 
    { 
    tmpMask = le32_to_cpu(*pNextMask++); 
    pkt_len -= sizeof(u_int32_t); 
    packet += sizeof(u_int32_t); 
    } 
    // packet should now point to the first field 
    for (iFldNum = 0, uMask = 1; (iFldNum < 31) && pkt_len; ++iFldNum, uMask <<= 1) 
    { 
    if ((it_present & uMask)) 
    { 
     u_int16_t uFldLen; 

     // We have a non-zero bit in the mask, iFldNum is the field number 
     // Call function to extract the field at packet and return number of bytes used 
     // process_field() is responsible for data alignment and preventing buffer overrun 
     uFldLen = process_field(packet, pkt_len, iFldNum); 
     pkt_len -= uFldLen; 
     packet += uFldLen; 
    } 
    } 
    // Here you would check if it_present had bit 31 set 
    // If so, process additional masks starting at pExtraMask 
} 

자세히 알 수 있듯이 약간 털이 많습니다.

+0

편집을 살펴 보겠습니다.이 데이터를 처음 보았을 때 내 이해가 무너진 부분에 대해 더 구체적으로 설명하려고 시도했습니다. – amoeba

0

나는 당신의 질문이 맞는지 확실하지 않습니다. 나는 비트 3에서 어떤 값을 읽는 방법을 묻고있다.

따라서 값을 평상시에 읽고 왼쪽으로 3 자리 옮긴다.

x = 1; x = x < < 3;

+0

나는 ' 내 질문의 언어를 분명히했습니다. 편집 된 질문 섹션을 참조하십시오. – amoeba