array an buffer anhängen.

german

Aktives Mitglied
devCommunity-Experte
Geht alles. Am Ende auch ein Array als data Member.
C:
#include <stdint.h>
#include <stdio.h>

struct FrameControlFieldFlags {
  union {
    uint8_t data;
    struct {
      uint8_t tods : 1;
      uint8_t fromds : 1;
      uint8_t more_fragments : 1;
      uint8_t retry : 1;
      uint8_t pwr_mgt : 1;
      uint8_t more_data : 1;
      uint8_t protected_flag : 1;
      uint8_t order_flag : 1;
    };
  };
} __attribute__((packed));

struct FrameControlField {
  union {
    uint8_t data[2];
    struct {
      uint8_t version : 2;
      uint8_t type : 2;
      uint8_t subtype : 4;
      struct FrameControlFieldFlags flags; // 8
    };
  };
} __attribute__((packed));

int main(void) {
  struct FrameControlField frameCtrlField = {0};
  frameCtrlField.subtype = 8;
  frameCtrlField.flags.tods = 1;
  printf("%02X %02X  size: %zu\n", (unsigned)frameCtrlField.data[0], (unsigned)frameCtrlField.data[1], sizeof(frameCtrlField));

  return 0;
}
Somit bist du in deinem Bitfeld nur noch daran gebunden, dass du ein Vielfaches von 8 Bit drin hast. Einfacher wird das dann aber ggf. nicht, denn möglicherweise wirst du das Bitfeld in 8 Bit Cluster aufteilen und diese Cluster von unten nach oben aufstapeln müssen. (Little Endianness)
 

lano

Aktives Mitglied
Ich hab jetzt alle Breiten zusammen.

C:
struct FrameControlFieldFlags {
  union {
    uint8_t data;
    struct {
      uint8_t tods : 1;
      uint8_t fromds : 1;
      uint8_t more_fragments : 1;
      uint8_t retry : 1;
      uint8_t pwr_mgt : 1;
      uint8_t more_data : 1;
      uint8_t protected_flag : 1;
      uint8_t order_flag : 1;
    };
  };
} __attribute__((packed));

struct FrameControlField {
  union {
    uint16_t data;
    struct {
      uint8_t version : 2;
      uint8_t type : 2;
      uint8_t subtype : 4;
      struct FrameControlFieldFlags flags; // 8
    };
  };
} __attribute__((packed));

///////////////////////////////////////////////////////////////////////////////

/*
Capabilities Information: 0x0411
    .... .... .... ...1 = ESS capabilities: Transmitter is an AP
    .... .... .... ..0. = IBSS status: Transmitter belongs to a BSS
    .... ..0. .... 00.. = CFP participation capabilities: No point coordinator at AP (0x0000)
    .... .... ...1 .... = Privacy: AP/STA can support WEP
    .... .... ..0. .... = Short Preamble: Not Allowed
    .... .... .0.. .... = PBCC: Not Allowed
    .... .... 0... .... = Channel Agility: Not in use
    .... ...0 .... .... = Spectrum Management: Not Implemented
    .... .1.. .... .... = Short Slot Time: In use
    .... 0... .... .... = Automatic Power Save Delivery: Not Implemented
    ...0 .... .... .... = Radio Measurement: Not Implemented
    ..0. .... .... .... = DSSS-OFDM: Not Allowed
    .0.. .... .... .... = Delayed Block Ack: Not Implemented
    0... .... .... .... = Immediate Block Ack: Not Implemented
*/

struct FixedParameters {
  uint64_t Timestamp;
  uint16_t BeaconInterval;
  union {
    uint16_t data;
    struct {
      uint8_t ESS_capabilities : 1;
      uint8_t IBSS_status : 1;
      uint8_t CFP_participation_capabilities : 3; // Problem
      uint8_t Privacy : 1;
      uint8_t Short_Preamble : 1;
      uint8_t PBCC : 1;
      uint8_t Channel_Agility : 1;
      uint8_t Spectrum_Management : 1;
      uint8_t Short_Slot_Time : 1;
      uint8_t Automatic_Power_Save_Delivery : 1;
      uint8_t Radio_Measurement : 1;
      uint8_t DSSS_OFDM : 1;
      uint8_t Delayed_Block_Ack : 1;
      uint8_t Immediate_Block_Ack : 1;
    };
  };
} __attribute__((packed));
////////////////////////////////////////////////////////////////////////////////

struct SSID_parameter {
  union {
    uint16_t data;
    struct {
      uint8_t TagNumber : 8;
      uint8_t TagLength : 8;
    };
  };
  char *SSID;
} __attribute__((packed));

struct SupportedRate {
  int value;
  struct SupportedRate *next;
} __attribute__((packed));

struct SupportedRates {
  union {
    uint16_t data;
    struct {
      uint8_t TagNumber;
      uint8_t TagLength;
    };
  };
  struct SupportedRate rate;

  //int SupportedRate;
  //int SupportedRate;
  //..
} __attribute__((packed));

struct DS_Parameter {
  uint8_t TagNumber;
  uint8_t TagLength;
  uint8_t CurrentChannel;
} __attribute__((packed));

struct TrafficIndicationMap {
  uint8_t TagNumber;
  uint8_t TagLength;
  uint8_t DTIM_count;
  uint8_t DTIM_period;
  union {
    uint8_t data;
    struct {
      uint8_t Multicast : 1;
      uint8_t Bitmap_Offset : 7;
    };
  };
  uint8_t PartialVirtualBitmap;
} __attribute__((packed));

struct CountryInformation {
  uint8_t TagNumber;
  uint8_t TagLength;
  char Code[2];
  uint8_t Environment;
  uint8_t FirstChannelNumber;
  uint8_t NumberOfChannels;
  uint8_t MaximumTransmitPowerLevel;
} __attribute__((packed));

struct ERP_Information {
  uint8_t TagNumber;
  uint8_t TagLength;
  union {
    uint8_t data;
    struct {
      uint8_t NonERPPresent : 1;
      uint8_t UseProtection : 1;
      uint8_t BarkerPreambleMode : 1;
      uint8_t Reserved : 5;
    };
  };
} __attribute__((packed));

struct ExtendedSupportedRates {
  uint8_t TagNumber;
  uint8_t TagLength;
  uint8_t Extended_Supported_Rate;
  /* ... */
} __attribute__((packed));

struct QBSSLoadElement {
  uint8_t TagNumber;
  uint8_t TagLength;
  uint16_t Station_Count;
  uint8_t Channel_Utilization;
  uint16_t Available_Admission_Capacity;
} __attribute__((packed));

struct RMEnabledCapabilities {
  uint8_t TagNumber;
  uint8_t TagLength;
  union {
    uint8_t data;
    struct {
      uint8_t Link_Measurement : 1;
      uint8_t Neighbor_Report : 1;
      uint8_t Parallel_Measurements : 1;
      uint8_t Repeated_Measurements : 1;
      uint8_t Beacon_Passive_Measurement : 1;
      uint8_t Beacon_Active_Measurement : 1;
      uint8_t Beacon_Table_Measurement : 1;
      uint8_t Beacon_Measurement_Reporting_Conditions : 1;
    };
  };
  /* ... more RM Capabilities */
} __attribute__((packed));

struct OverlappingBSSScanParameters {
  uint8_t TagNumber;
  uint8_t TagLength;
  uint16_t Scan_Passive_Dwell;
  uint16_t Scan_Active_Dwell;
  uint16_t Channel_Width_Trigger_Scan_Interval;
  uint16_t Scan_Passive_Total_Per_Channel;
  uint16_t Scan_Active_Total_Per_Channel;
  uint16_t Width_Channel_Transition_Delay_Factor;
  uint16_t Scan_Activity_Threshold;
} __attribute__((packed));

struct ExtendedCapabilities {
  uint8_t TagNumber;
  uint8_t TagLength;
  union {
    uint8_t Extended_Capabilities1;
    struct {
      uint8_t BSS_Coexistence_Management_Support : 1;
      uint8_t Reserved : 1;
      uint8_t Extended_Channel_Switching : 1;
      uint8_t Reserved1 : 1;
      uint8_t PSMP_Capability : 1;
      uint8_t Reserved2 : 1;
      uint8_t S_PSMP_Support : 1;
      uint8_t Event : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities2;
    struct {
      uint8_t Diagnostics : 1;
      uint8_t Multicast_Diagnostics : 1;
      uint8_t Location_Tracking : 1;
      uint8_t FMS : 1;
      uint8_t Proxy_ARP_Service : 1;
      uint8_t Collocated_Interference_Reporting : 1;
      uint8_t Civic_Location : 1;
      uint8_t Geospatial_Location : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities3;
    struct {
      uint8_t TFS : 1;
      uint8_t WNM_Sleep_Mode : 1;
      uint8_t TIM_Broadcast : 1;
      uint8_t BSS_Transition : 1;
      uint8_t QoS_Traffic_Capability : 1;
      uint8_t AC_Station_Count : 1;
      uint8_t Multiple_BSSID : 1;
      uint8_t Timing_Measurement : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities4;
    struct {
      uint8_t Channel_Usage : 1;
      uint8_t SSID_List : 1;
      uint8_t DMS : 1;
      uint8_t UTC_TSF_Offset : 1;
      uint8_t TPU_Buffer_STA_Support : 1;
      uint8_t TDLS_Peer_PSM_Support : 1;
      uint8_t TDLS_channel_switching : 1;
      uint8_t Interworking : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities5;
    struct {
      uint8_t QoS_Map : 1;
      uint8_t EBR : 1;
      uint8_t SSPN_Interface : 1;
      uint8_t Reserved3 : 1;
      uint8_t MSGCF_Capability : 1;
      uint8_t TDLS_Support : 1;
      uint8_t TDLS_Prohibited : 1;
      uint8_t TDLS_Channel_Switching_Prohibited : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities6;
    struct {
      uint8_t Reject_Unadmitted_Frame : 1;
      uint8_t Service_Interval_Granularity : 3;
      uint8_t Identifier_Location : 1;
      uint8_t U_APSD_Coexistence : 1;
      uint8_t WNM_Notification : 1;
      uint8_t QAB_Capability : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities7;
    struct {
      uint8_t UTF_8_SSID : 1;
      uint8_t QMF_Activated : 1;
      uint8_t QMF_Reconfiguration_Activated : 1;
      uint8_t Robust_AV_Streaming : 1;
      uint8_t Advanced_GCR : 1;
      uint8_t Mesh_GCR : 1;
      uint8_t SCS : 1;
      uint8_t QLoad_Report : 1;
    };
  };
  union {
    uint8_t Extended_Capabilities8;
    struct {
      uint8_t Alternate_EDCA : 1;
      uint8_t Unprotected_TXOP_Negotiation : 1;
      uint8_t Protected_TXOP_Negotiation : 1;
      uint8_t Reserved4 : 1;
      uint8_t Protected_QLoad_Report : 1;
      uint8_t TDLS_Wider_Bandwidth : 1;
      uint8_t Operating_Mode_Notification : 1;
      uint8_t Max_Number_Of_MSDUs_In_A_MSDU : 1;
    };
  };
} __attribute__((packed));

struct RSNInformation {
  uint8_t TagNumber;
  uint8_t TagLength;
  uint16_t RSN_Version;
  char Group_Cipher_Suite_OUI[3];
  uint8_t Group_Cipher_Suite_type;
  uint16_t Pairwise_Cipher_Suite_Count;
  char Pairwise_Cipher_Suite_OUI[3];
  uint8_t Pairwise_Cipher_Suite_type;
  uint16_t Auth_Key_Management_Suite_Count;
  char Auth_Key_Management_OUI[3];
  uint8_t Auth_Key_Management_type;

  /*
  union {
    uint8_t RSN_Capabilities;
    struct {
      uint8_t .... .... .... ...0 = RSN Pre-Auth capabilities: Transmitter does not support pre-authentication:1;
      uint8_t .... .... .... ..0. = RSN No Pairwise capabilities: Transmitter can support WEP default key 0 simultaneously with Pairwise key:1;
      uint8_t .... .... .... 00.. = RSN PTKSA Replay Counter capabilities: 1 replay counter per PTKSA/GTKSA/STAKeySA (0x0):1;
      uint8_t .... .... ..00 .... = RSN GTKSA Replay Counter capabilities: 1 replay counter per PTKSA/GTKSA/STAKeySA (0x0):1;
      uint8_t .... .... .0.. .... = Management Frame Protection Required: False:1;
      uint8_t .... .... 1... .... = Management Frame Protection Capable: True:1;
      uint8_t .... ...0 .... .... = Joint Multi-band RSNA: False:1;
      uint8_t .... ..0. .... .... = PeerKey Enabled: False:1;
      uint8_t ..0. .... .... .... = Extended Key ID for Individually Addressed Frames: Not supported

    };
  };
*/
} __attribute__((packed));

struct VendorSpecific {
  uint8_t TagNumber;
  uint8_t TagLength;
  char OUI[3];
  uint8_t Vendor_Specific_OUI_Type;
  char Vendor_Specific_Data[5];
} __attribute__((packed));

////////////////////////////////////////////////////////////////////////////////
struct TaggedParameters {
  struct SSID_parameter SSIDParameter;
  struct SupportedRates Supported_Rates;
  struct DS_Parameter DSParameter;
  struct TrafficIndicationMap TIM;
  struct CountryInformation Country_Information;
  struct ERP_Information ERPInformation;

  struct ExtendedSupportedRates ExtendedSupported_Rates;
  struct QBSSLoadElement QBSSLoad_Element;
  struct RMEnabledCapabilities RMEnabled_Capabilities;
  struct OverlappingBSSScanParameters OverlappingBSSScan_Parameters;
  struct ExtendedCapabilities Extended_Capabilities;
  struct RSNInformation RSN_Information;
  struct VendorSpecific Vendor_Specific;
} __attribute__((packed));

struct Beacon {
  struct FrameControlField frameControlField;
  uint8_t Duration;
  short mac1;
  short mac2;
  short mac3;
  union {
    uint16_t data;
    struct {
      uint16_t FragmentNumber : 4;
      uint16_t SequenceNumber : 12;
    };
  };
  struct FixedParameters fixedParameters;
  struct TaggedParameters taggedParameters;
  uint16_t FSC;
} __attribute__((packed));

Bei manchem weis ich nicht wie ich dem begegnen soll. ich hoffe das stimmt jetzt soweit erstmal.
 

german

Aktives Mitglied
devCommunity-Experte
uint8_t CFP_participation_capabilities : 3; // Problem
Ja, weil du dein Schema schon verkehrt aufgebaut hast.
Code:
/*
Capabilities Information: 0x0411
    .... .... .... ...1 = ESS capabilities: Transmitter is an AP
    .... .... .... ..0. = IBSS status: Transmitter belongs to a BSS
    .... .... .... 00.. = CFP Lo participation capabilities: No point coordinator at AP (0x0000)
    .... .... ...1 .... = Privacy: AP/STA can support WEP
    .... .... ..0. .... = Short Preamble: Not Allowed
    .... .... .0.. .... = PBCC: Not Allowed
    .... .... 0... .... = Channel Agility: Not in use
    .... ...0 .... .... = Spectrum Management: Not Implemented
    .... ..0. .... .... = CFP Hi
    .... .1.. .... .... = Short Slot Time: In use
    .... 0... .... .... = Automatic Power Save Delivery: Not Implemented
    ...0 .... .... .... = Radio Measurement: Not Implemented
    ..0. .... .... .... = DSSS-OFDM: Not Allowed
    .0.. .... .... .... = Delayed Block Ack: Not Implemented
    0... .... .... .... = Immediate Block Ack: Not Implemented
*/
Das sind einmal 2 und später noch mal 1 Bit. Und so muss auch dein Bitfeld aussehen. Ich hab da jetzt einfach mal Lo und Hi drangeschrieben. Vermutlich gibt's sinnvollere Bezeichnungen, wenn man weiß was CFP oder AP bedeutet. Mir sagt das nix.
 

lano

Aktives Mitglied
Contention Free Period müsste das sein... aber egal.

So war dann auch mein gedanke. aber wie fülle ich das dann? bastel ich für alles ne extra funktion ?
so ala set_Contention_Free_Period(..)

ich glaub schon fast das das das beste wäre.
 

lano

Aktives Mitglied
ich bin jetzt bis zur ssid gekommen. Ich hab da Pointer...
jetzt muss ich doch irgendwie speicher und so...

C:
struct s_SSID_Parameter {
  union {
    uint16_t data;
    struct {
      uint8_t TagNumber : 8;
      uint8_t TagLength : 8;
    };
  };
  char *SSID;
} __attribute__((packed));

So sieht das übel jetzt aus.
 

german

Aktives Mitglied
devCommunity-Experte
bastel ich für alles ne extra funktion ?
Für so außergewöhnliche Kombinationen musst du natürlich ne Extrawurst haben. Wie würde denn ein Wert aussehen, den du da reinbringen musst und wie muss er auf die 3 Bits aufgeteilt werden?
So sieht das übel jetzt aus.
Das sieht übel aus :D
Du hast unten einen Pointer drin. Das klingt (für mich) nicht richtig. Ein Pointer ist eine Speicheradresse und das ist kaum etwas das du weitergeben willst. Warum hast du da einen Pointer? Weil die SSID unterschiedliche Längen haben kann? Falls ja, musst du dort einen Platzhalter anhängen, à la char SSID[1]; und Speicher allokieren der groß genug ist um den eigentlichen String reinzukopieren. Musst dir natürlich merken wie groß der Speicherbereich am Ende ist, denn ein sizeof zieht dann nur den Platzhalter mit rein...
 

lano

Aktives Mitglied
Wie würde denn ein Wert aussehen, den du da reinbringen musst und wie muss er auf die 3 Bits aufgeteilt werden?
hehe. du stellst fragen. ich weis es noch nicht.
Das klingt (für mich) nicht richtig.
hmmm...
Weil die SSID unterschiedliche Längen haben kann?
genau.
denn ein sizeof zieht dann nur den Platzhalter mit rein...
wie jetzt. sizeof dem struct?
 

lano

Aktives Mitglied
ok, bevor ich jetzt wieder nen halben tag versuche unsinnig speicher zu bekommen.
wie ging das noch mal ?

C:
beacon.Tagged_Parameters.SSID_Parameter.SSID = realloc(beacon.Tagged_Parameters.SSID_Parameter.SSID, 5);
strcpy(beacon.Tagged_Parameters.SSID_Parameter.SSID, "X-Mas");
printf("\t\t\t\t SSID: %s\n", beacon.Tagged_Parameters.SSID_Parameter.SSID);

bin damit jetzt schon auf die fresse geflogen.
 

german

Aktives Mitglied
devCommunity-Experte
wie jetzt. sizeof dem struct?
Ja genau. Sobald du variable Längen irgendwo drin hast, kannst du leider den Gedanken begraben, dass du sowas wie den Speicherbereich eines "Gesamt-structs" senden kannst. Da musst du dann für den ganzen Kram am Ende Speicher allokieren und mit memcpy die Daten zusammenkopieren. Schade, aber dafür gibt es keinen anderen Weg.

wie ging das noch mal ?
Warte, muss ich schnell mal in der IDE zusammenwürfeln ... Komme wieder.
 

lano

Aktives Mitglied
Schade, aber dafür gibt es keinen anderen Weg.
hmm... und wenn ich die ssid quasi alleine lasse?
nehmen wir an es gibt eine funktion set_ssid. die könnte ja in das struct die länge der ssid schreiben und die ssid dann seperat ablegen.
beim zusammen bauen müsste ich dann nur gucken wie lang die ssid ist und nach dem kopieren vom struct die ssid hinter her. und denn quasi weiter wie gewohnt.

da kommen auch noch mehr hürden ähnlicher art.
 

german

Aktives Mitglied
devCommunity-Experte
C:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct s_SSID_Parameter {
  union {
    uint16_t data;
    struct {
      uint8_t TagNumber : 8;
      uint8_t TagLength : 8;
    };
  };
  char SSID[1];
} __attribute__((packed));

int main(void) {
  char mySSID[] = "X-Mas";

  const size_t mySSIDLength = strlen(mySSID);

  struct s_SSID_Parameter *pSSID_Param = NULL;
  pSSID_Param = malloc(sizeof(struct s_SSID_Parameter) + mySSIDLength);
  if (!pSSID_Param)
    return 1;

  memcpy(pSSID_Param->SSID, mySSID, mySSIDLength + 1);

  puts(pSSID_Param->SSID);

  free(pSSID_Param);
  return 0;
}
... mit sizeof(struct s_SSID_Parameter) + mySSIDLength der Gesamtgröße schon incl. Nullterminierung (auch wenn's auf Anhieb nicht so aussieht).
Beachte den Platzhalter, wie oben geschrieben.
 

german

Aktives Mitglied
devCommunity-Experte
nehmen wir an es gibt eine funktion set_ssid. die könnte ja in das struct die länge der ssid schreiben und die ssid dann seperat ablegen.
Kannst du ja machen, wird dich aber nicht davor bewahren noch mal alles zusammenhängend in einen Speicherbereich zu kopieren, bevor du die Daten senden kannst.
 

lano

Aktives Mitglied
wird dich aber nicht davor bewahren noch mal alles zusammenhängend in einen Speicherbereich zu kopieren
ja, das werd ich eh nicht packen. ums zwischen kopieren komm ich wohl beim zusammen bauen nicht drum rum.
ich werd mich erstma hin haun und denn ma weiter gucken. so langsam wird das dank deiner hilfe.
 

german

Aktives Mitglied
devCommunity-Experte
Du musst auch höllisch aufpassen, wenn ich mir so deinen Versuch oben ansehe. struct s_SSID_Parameter gibt es jetzt nur noch als Interface und nicht mehr real. Heißt, du kannst es nur noch als Pointer verwenden. Und das wiederum bedeutet, dass es beacon.Tagged_Parameters.SSID_Parameter.SSID nicht geben wird. Das wäre Speicher auf dem Stack und das ist nicht mehr möglich wenn du dir für irgendein Member Speicher per malloc vom Heap holen musst. Mit variablen Größen von Members musst du dein Konzept noch mal neu stricken ...
 

german

Aktives Mitglied
devCommunity-Experte
Wenn ich's mir recht überlege, lass SSID beim Pointer. Den kannst du separat allokieren und reinhängen. Die Serialisierung machst du dann beim finalen Zusammenkopieren. So brauchst du wenigstens nicht alles umwerfen und kannst erst mal deine Stackvariablen weiterverwenden.
 

Rushh0ur

Neues Mitglied

german

Aktives Mitglied
devCommunity-Experte
Laut Norm ist die maximale Länge der SSID auf 32 Zeichen begrenzt
Na das ist doch mal übersichtlich :)

Ich würde die Länge des Arrays einfach auf 32 bzw. 33 setzen
Hmm. 33 oder irgendwas größeres was nicht so eine krumme Zahl ist. Platz für die Nullterminierung sollt schon bleiben.

und die tatsächliche Größe zur Laufzeit ermitteln.
Ja das ist so mehr oder weniger mein letzter Vorschlag. Der ganze Kram muss eben noch serialisiert werden, bevor er versendet werden kann. Da denke ich halt dass auch ein Array mit einer fixen Breite im struct nicht funktionieren wird. Statt dessen muss trotzdem in einen konsekutiven Speicherbereich zusammenkopiert werden, mit lediglich der jeweiligen tatsächlichen Stringlänge ... @lano weiß das aber besser wie ich.
 

lano

Aktives Mitglied
@lano weiß das aber besser wie ich.
Hä?


Laut Norm ist die maximale Länge der SSID auf 32 Zeichen begrenzt
ist richtig.
Ich würde die Länge des Arrays einfach auf 32 bzw. 33 setzen und die tatsächliche Größe zur Laufzeit ermitteln.
hab ich auch schon dran gedacht. kann ich mich aber irgendwie nicht so ganz anfreunden mit.
Nehmen wir an die ssid ist gar nicht gesetzt. also wildcard ssid. dann ist die tag länge 0 und es kommt auch nix mehr danach.
also beim eigentlichen paket zusammen bau könnte ich den tagged parameter für die ssid einfach kopieren in dem ich das struct rein kloppfe, dann würde ich nach der tag länge gucken und ggf vom array ssid[33] soviele bytes kopieren wie nötig.

um so funktionen wie set_ssid und add_supported_rate werd ich eh nicht drum rum kommen.
 
Oben Unten