2013-06-26 25 views
5

Chciałbym wiedzieć, czy można wykonać memfony za pomocą bitów zamiast bajtów?jest to możliwe do robienia memcpy w bitach zamiast w bajtach?

Piszę kod C dla ramki Ethernet z tagowaniem VLAN, w którym muszę wypełnić różne wartości dla atrybutów nagłówka VLAN (PCP-3bits, DEI-1bit, VID-12bits).

Jak mogę zrobić memcpy do tych bitów lub jakąkolwiek inną możliwość wypełnienia wartości tymi atrybutami w bitach.

Z góry dziękuję!

+0

Najważniejsze pytanie brzmi, czy spodziewasz się przesunięcia bitów w stosunku do 8-bitowych granic jako części kopii; i czy spodziewasz się, że bity mogą się nakładać? –

+1

kopie memcpy n 'bytes' od źródła do miejsca docelowego.Nie możesz użyć 'memcpy' dla bitów. –

+0

Potrzebuję tej funkcji z tego samego powodu. Proszę podać odpowiedź na pytanie, jak rozwiązać ten problem. – jwbensley

Odpowiedz

1

Jeśli trzeba wypełnić pola, można użyć C bit-fields z struct coś takiego:

struct box_props { 
    unsigned first : 1; 
    unsigned second : 3; 
    unsigned : 4; 
}; 

Gdzie 1, na przykład, oznacza, że ​​pole jest 1bit długo. Ostatnie (nienazwane) pole oznacza: wypełnienie 4-bitowe.

Zdefiniuj struct, i odczytaj pola tak, jakby zawierały unsigned. To samo dotyczy pisania.

UWAGA: zawsze pad na bajt całkowity, lub memcpy może mieć niepożądane efekty.

+1

Należy zauważyć, że jest to w pełni zdefiniowana implementacja. Aby uzyskać szczegółowe informacje, patrz [ta odpowiedź] (http://stackoverflow.com/a/1490669/188535), ale zasadniczo jest to kolejność i pakowanie, które nie są przenośne. – detly

+0

Dziękuję ... Spróbuję z metodą struktury. – arr

+0

Należy jednak pamiętać o tym, co inni ludzie mówią, a odpowiedź SO jest powiązana z @detly (chyba powinienem zaktualizować moje C-fu): to nie jest przenośne i mogą pojawić się dziwne błędy. Właściwie Pascal zapewnił ci odpowiedź kanoniczną. –

6

Nr Bity nie są adresowalne (co oznacza, że ​​nie można ich odczytać i tylko bezpośrednio z pamięci, nie mają adresu, tylko bajty mają adresy).

Musisz przeczytać bajt lub słowo, które zawiera interesujące Cię bity i samemu wykonać masking.

1

Wykonałem oznaczanie ramek VLAN 802.1Q dla klienta, który miał tylko 802.3 ramki Ethernet, ale chciał przejść do wersji 802.1Q, ponieważ był zainstalowany nowy przełącznik VLAN aware.

Po pierwsze, nie można kopiować bitów. Skopiowaliśmy tag w bajtach za pomocą memcpy.

Ilustracja (patrz Wikipedia opisy pól): -

VLAN Tag = 4 bajty; składający się z TPID (2 Bytes) i TCI (2 Bytes).

Identyfikator TPID jest prosty i zawsze jest wartością 0x8100 wskazującą ramkę ze znacznikiem VLAN.

TCI składa się z PCP-3bit, DEI-1bit, VID-12bit. Podział TCI na przekąski, np. 4-bitowe. Domyślnie przydział (PCP + DEI) = 0x0 przy założeniu, że priorytet jest wyłączony, a DEI = 0. Pozostałe 3-nibbles (12 bitów) dotyczą samego VLAN-ID. Powiedzmy, że chcesz oznaczyć ramkę dla VLAN-ID = 123. W hexie będzie to = 0x07B.

Grupuj przekąski razem i tam masz swoje 2 bajtowe pole TCI, które można teraz zobaczyć jako 0x007B.

Następnie można wykonać poniższe czynności. (kod nie został skompilowany)

unsigned short int vlanTPID, vlanTCI; 
unsigned char  *dest, *src; 

// Set the VLAN Tag 
vlanTPID = 0x8100; 
vlanTCI = 0x007B; 

// Pointer to the TPID position of ethernet frame 
dest = &vlanTagPosition; 
src = &vlanTPID; 
memcpy(dest, src, sizeof(vlanTPID)); 

// Increment dest pointer by 2 bytes to insert TCI in the ethernet frame 
dest += 2; 
src = &vlanTCI; 
memcpy(dest, src, sizeof(vlanTCI)); 
+0

To jest łatwa część, w której PCP i DEI mają wartość 0, teraz zakładamy, że vlanID 4011 i PCP 7 z DEI 0, chciałbym to zobaczyć (ponieważ naprawdę walczę z tym!). – jwbensley

+0

| 1 1 1 0 | 1 1 1 1 | 1 0 1 0 | 1 0 1 1 | - Jak już powiedziałem, musisz wyobrazić sobie pole TCI jako 16-bitowe lub 4-nibbles. Pierwszy krok to PCP + DEI = 7, a pozostałe 3-nibbles to VLAN-ID = 4011. Po konwersji binarnych bitów na hex twoje pole TCI będzie wynosić 0xEFAB. – ritwick87