array an buffer anhängen.

lano

Aktives Mitglied
Moin.
Ich hab da nen Problem. Ich will nen Beacon senden um nen fake accesspoint zu basteln.
Jetzt scheitert das schon an den blöden speichergeschichten.
Ich raff es einfach nicht.
Hier ma der Code:
C:
#include <arpa/inet.h>
#include <errno.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* Defined in include/linux/ieee80211.h */
struct ieee80211_hdr {
  uint16_t /*__le16*/ frame_control;
  uint16_t /*__le16*/ duration_id;
  uint8_t addr1[6];
  uint8_t addr2[6];
  uint8_t addr3[6];
  uint16_t /*__le16*/ seq_ctrl;
} __attribute__((packed));

#define WLAN_FC_TYPE_DATA 0
#define WLAN_FC_SUBTYPE_DATA 8

/*************************** START READING AGAIN ******************************/

/* A bogus MAC address just to show that it can be done */
const uint8_t mac1[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* Destination */
const uint8_t mac2[6] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab}; /* Source */
const uint8_t mac3[6] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xac}; /* BSSID */

static const uint8_t u8aRadiotapHeader[] = {

    0x00,
    0x00, // radiotap version
    0x18,
    0x00, // number of bytes in our header

    0x0f,
    0x80,
    0x00,
    0x00,

    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00, // <-- timestamp

    /**
   * This is the first set of flags, and we've set the bit corresponding to
   * IEEE80211_RADIOTAP_F_FCS, meaning we want the card to add a FCS at the end
   * of our buffer for us.
   */
    0x10,

    0x00, // rate
    0x00,
    0x00,
    0x00,
    0x00, // channel

    0x08,
    0x00,
};

static const uint8_t u8aFixedParameters[] = {
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Timestamp
    0x00, 0x64,                                     // Beacon Interval
    0x31, 0x10,                                     // Capabilities Information
};

static const uint8_t u8aTaggedParameter_00[] = {
    0x00,                         //Tag Number
    0x05,                         // Tag length
    0x58, 0x2d, 0x4d, 0x41, 0x53, //SSID
};

static const uint8_t u8aTaggedParameter_01[] = {
    0x01, //Tag Number
    0x08, // Tag length
    0x82, 0x84, 0x8b, 0x96, 0x8c, 0x12, 0x98, 0x24,
};

int msleep(long msec);

int main(void) {

  /* The parts of our packet */
  uint8_t *rt; /* radiotap */
  struct ieee80211_hdr *hdr;

  uint8_t *FixedParameter;
  uint8_t *TaggedParameter_00;
  uint8_t *TaggedParameter_01;

  /* Other useful bits */
  uint8_t *buf;
  size_t sz;
  uint8_t fcchunk[2]; /* 802.11 header frame control */

  /* PCAP vars */
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_t *ppcap;

  /* Total buffer size (note the 0 bytes of data and the 4 bytes of FCS */

  sz = sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + (sizeof(u8aFixedParameters)) + (sizeof(u8aTaggedParameter_00)) + (sizeof(u8aTaggedParameter_01)) + 4; /* FCS */

  buf = (uint8_t *)malloc(sz);

  /* Put our pointers in the right place */
  rt = (uint8_t *)buf;
  hdr = (struct ieee80211_hdr *)(rt + sizeof(u8aRadiotapHeader));

  FixedParameter = (uint8_t *)(hdr + 1);
  TaggedParameter_00 = (uint8_t *)(FixedParameter + 1);
  TaggedParameter_01 = (uint8_t *)(TaggedParameter_00 + 1);

  /* The radiotap header */
  memcpy(rt, u8aRadiotapHeader, sizeof(u8aRadiotapHeader));
  fcchunk[0] = ((WLAN_FC_TYPE_DATA << 2) | (WLAN_FC_SUBTYPE_DATA << 4));
  fcchunk[1] = 0x02;
  memcpy(&hdr->frame_control, &fcchunk[0], 2 * sizeof(uint8_t));

  hdr->duration_id = 0xffff;
  memcpy(&hdr->addr1[0], mac1, 6 * sizeof(uint8_t));
  memcpy(&hdr->addr2[0], mac2, 6 * sizeof(uint8_t));
  memcpy(&hdr->addr3[0], mac3, 6 * sizeof(uint8_t));
  hdr->seq_ctrl = 0;

  memcpy(FixedParameter, u8aFixedParameters, sizeof(u8aFixedParameters));

  //Tag: SSID parameter
  memcpy(TaggedParameter_00, u8aTaggedParameter_00, sizeof(u8aTaggedParameter_00));

  // Tag: Supported Rates
  memcpy(TaggedParameter_01, u8aTaggedParameter_01, sizeof(u8aTaggedParameter_01));

  /**
   * Finally, we have the packet and are ready to inject it.
   * First, we open the interface we want to inject on using pcap.
   */
  ppcap = pcap_open_live("wlp1s0mon", 800, 1, 20, errbuf);

  if (ppcap == NULL) {
    printf("Could not open interface wlp1s0mon for packet injection: %s", errbuf);
    return 2;
  }

  for (int i = 0; i <= 100; i++) {
    if (pcap_sendpacket(ppcap, buf, sz) == 0) {
      //    pcap_close(ppcap);
      //    return 0;
    }
    msleep(100);
  }

  pcap_perror(ppcap, "Failed to inject packet");
  pcap_close(ppcap);
  return 1;
}

int msleep(long msec) {
  struct timespec ts;
  int res;

  if (msec < 0) {
    errno = EINVAL;
    return -1;
  }

  ts.tv_sec = msec / 1000;
  ts.tv_nsec = (msec % 1000) * 1000000;

  do {
    res = nanosleep(&ts, &ts);
  } while (res && errno == EINTR);

  return res;
}

Hauptproblem ist das verständniss bei FixedParameter und die TaggedParameter_00 und TaggedParameter_01.
Ich raff das einfach nicht mit dem dämlichen Speicher. Nach meiner logic sieht das gut aus.
Nur wird nicht das in die Luft gejagt was ich eigentlich gedacht hätte.

Jemand ne Idee ?
 

lano

Aktives Mitglied
Ist das wirklich immer +1?
Nein. Da ist auch das Problem.

Im moment hab ich mir so beholfen.
C:
buf = (uint8_t *)malloc(sz);

/* Put our pointers in the right place */

/* Pointer zum beginn von Buffer */
rt = (uint8_t *)buf;

/* Pointer zum beginn von radiotap + Radiotap size*/
hdr = (struct ieee80211_hdr *)(buf + sizeof(u8aRadiotapHeader));

/* Pointer zum beginn von header + header size*/
FixedParameter = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr));

/* Pointer zum beginn von FixedParameter + FixedParameter size*/
TaggedParameter_00 = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_01 = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_03 =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_05 = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) +
                                 sizeof(u8aTaggedParameter_01) + sizeof(u8aTaggedParameter_03));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_07 = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) +
                                 sizeof(u8aTaggedParameter_01) + sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_2a = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) +
                                 sizeof(u8aTaggedParameter_01) + sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_32 =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01) +
                sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) + sizeof(u8aTaggedParameter_2a));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_0b =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01) +
                sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) + sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_46 = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) +
                                 sizeof(u8aTaggedParameter_01) + sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) +
                                 sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) + sizeof(u8aTaggedParameter_0b));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_2d = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) +
                                 sizeof(u8aTaggedParameter_01) + sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) +
                                 sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) + sizeof(u8aTaggedParameter_0b) + sizeof(u8aTaggedParameter_46));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_3d =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01) +
                sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) + sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) +
                sizeof(u8aTaggedParameter_0b) + sizeof(u8aTaggedParameter_46) + sizeof(u8aTaggedParameter_2d));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_4a =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01) +
                sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) + sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) +
                sizeof(u8aTaggedParameter_0b) + sizeof(u8aTaggedParameter_46) + sizeof(u8aTaggedParameter_2d) + sizeof(u8aTaggedParameter_3d));

/* Pointer zum beginn von TaggedParameter_00 + TaggedParameter_00 size*/
TaggedParameter_7f =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01) +
                sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) + sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) +
                sizeof(u8aTaggedParameter_0b) + sizeof(u8aTaggedParameter_46) + sizeof(u8aTaggedParameter_2d) + sizeof(u8aTaggedParameter_3d) + sizeof(u8aTaggedParameter_4a));

TaggedParameter_30 = (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) +
                                 sizeof(u8aTaggedParameter_01) + sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) +
                                 sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) + sizeof(u8aTaggedParameter_0b) + sizeof(u8aTaggedParameter_46) +
                                 sizeof(u8aTaggedParameter_2d) + sizeof(u8aTaggedParameter_3d) + sizeof(u8aTaggedParameter_4a) + sizeof(u8aTaggedParameter_7f));

TaggedParameter_dd =
    (uint8_t *)(buf + sizeof(u8aRadiotapHeader) + sizeof(struct ieee80211_hdr) + sizeof(u8aFixedParameters) + sizeof(u8aTaggedParameter_00) + sizeof(u8aTaggedParameter_01) +
                sizeof(u8aTaggedParameter_03) + sizeof(u8aTaggedParameter_05) + sizeof(u8aTaggedParameter_07) + sizeof(u8aTaggedParameter_2a) + sizeof(u8aTaggedParameter_32) +
                sizeof(u8aTaggedParameter_0b) + sizeof(u8aTaggedParameter_46) + sizeof(u8aTaggedParameter_2d) + sizeof(u8aTaggedParameter_3d) + sizeof(u8aTaggedParameter_4a) +
                sizeof(u8aTaggedParameter_7f) + sizeof(u8aTaggedParameter_30));

anders hab ich es nicht hinbekommen.
 

german

Aktives Mitglied
devCommunity-Experte
Du kannst schon einen Pointer zum anderen addieren, um etwas Code zu sparen wenn du willst. Siehst ja, welche sizeofs sich wiederholen. Der Compiler macht aber daraus sowieso jeweils ein konstantes Offset, da die Typbreiten zur Compilezeit bekannt sind. Heißt, am Maschinencode wird sich nix ändern.
Dass du für den ganzen Kram Arrays statt Structs verwendest ist ein bisschen strange. Aber gut, am Ende stellst du so sicher dass du kein Padding zwischen den einzelnen Werten hast. Lesbarer und verständlicher wird es mit Arrays allerdings nicht gerade...
 

lano

Aktives Mitglied
Dass du für den ganzen Kram Arrays statt Structs verwendest ist ein bisschen strange.
Jaha. erstmal hab ich das so hingekaspert. jetzt überlege ich aber auch wie ich die sachen in structs bekomme. hab aber noch nicht recht so ne idee.
zB sowas:
Code:
static const uint8_t u8aTaggedParameter_32[] = {
/* Tag: Extended Supported Rates 24(B), 36, 48, 54, [Mbit/sec]
Tag Number: Extended Supported Rates (50)
Tag length: 4
Extended Supported Rates: 24(B) (0xb0)
Extended Supported Rates: 36 (0x48)
Extended Supported Rates: 48 (0x60)
Extended Supported Rates: 54 (0x6c)
*/
0x32, 0x04, 0xb0, 0x48, 0x60, 0x6c,
};

das würde ich noch hinbekommen.
überlegen tu ich bei sowas:
Code:
static const uint8_t u8aTaggedParameter_2a[] = {
/*  Tag: ERP Information
Tag Number: ERP Information (42)
Tag length: 1
ERP Information: 0x00
.... ...0 = Non ERP Present: Not set
.... ..0. = Use Protection: Not set
.... .0.. = Barker Preamble Mode: Not set
0000 0... = Reserved: 0x00
*/
 0x2a, 0x01, 0x00,
};

und ganz haarig wird es bei sowas:
Code:
static const uint8_t u8aFixedParameters[] = {
/*  Fixed parameters (12 bytes)
Timestamp: 578437695752307201
Beacon Interval: 0,102400 [Seconds]
Capabilities Information: 0x1031
.... .... .... ...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 (0x00)
.... .... ...1 .... = Privacy: AP/STA can support WEP
.... .... ..1. .... = Short Preamble: Allowed
.... .... .0.. .... = PBCC: Not Allowed
.... .... 0... .... = Channel Agility: Not in use
.... ...0 .... .... = Spectrum Management: Not Implemented
.... .0.. .... .... = Short Slot Time: Not in use
.... 0... .... .... = Automatic Power Save Delivery: Not Implemented
...1 .... .... .... = Radio Measurement: Implemented
..0. .... .... .... = DSSS-OFDM: Not Allowed
.0.. .... .... .... = Delayed Block Ack: Not Implemented
0... .... .... .... = Immediate Block Ack: Not Implemented
*/
  0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, // Timestamp
  0x64, 0x00, // Beacon Interval
  0x31, 0x10, // Capabilities Information
};
wobei das augenmerk bei CFP participation capabilities liegt.

ich hab da keine idee.
 

lano

Aktives Mitglied
um da ma nen beispiel zu bringen wie ich denke. wobei ich mir nicht sicher bin ob es nicht mit union oder so sinn macht. wenn ich mich recht erinnere ist das ja immer nen problem nen struct zu senden.
C:
/*
IEEE 802.11 Beacon frame, Flags: ........C
    Type/Subtype: Beacon frame (0x0008)
    Frame Control Field: 0x8000
        .... ..00 = Version: 0
        .... 00.. = Type: Management frame (0)
        1000 .... = Subtype: 8
        Flags: 0x00
            .... ..00 = DS status: Not leaving DS or network is operating in AD-HOC mode (To DS: 0 From DS: 0) (0x00)
            .... .0.. = More Fragments: This is the last fragment
            .... 0... = Retry: Frame is not being retransmitted
            ...0 .... = PWR MGT: STA will stay up
            ..0. .... = More Data: No data buffered
            .0.. .... = Protected flag: Data is not protected
            0... .... = Order flag: Not strictly ordered

*/
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0

struct DsStatus {
  unsigned int tods : 1;
  unsigned int fromds : 1;
};

struct FrameControlFieldFlags {
  struct DsStatus ds_status;
  unsigned int more_fragments : 1;
  unsigned int retry : 1;
  unsigned int pwr_mgt : 1;
  unsigned int more_data : 1;
  unsigned int protected_flag : 1;
  unsigned int order_flag : 1;
};

// FrameControlField
struct FrameControlField {
  unsigned int version : 2;
  unsigned int type : 2;
  unsigned int subtype : 4;
  struct FrameControlFieldFlags flags;
};

struct Beacon {
  struct FrameControlField frameControlField;
} beacon;

int main(void) {

  struct Beacon beacon = {0, 0, 8, {{TRUE, FALSE}, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE}};

  printf("FromDS: %d\n", beacon.frameControlField.flags.ds_status.fromds);
  printf("more-fragments: %d\n", beacon.frameControlField.flags.more_fragments);

  return 0;
}
 

german

Aktives Mitglied
devCommunity-Experte
wenn ich mich recht erinnere ist das ja immer nen problem nen struct zu senden
Naja, du brauchst halt alles perfekt gepackt. Bitfields sind da nicht besonders gut geeignet. Wie man es dreht und wendet, schön wird das nicht. Ich hab nie wirklich verstanden was der Compiler mit Bitfields eigentlich veranstaltet. Adressieren lassen sich einzelne Bits eigentlich nicht. Also werden am Ende ähnliche Mechanismen greifen wie bei bitweisen Operationen. Und genau das wäre eine alternative Lösung.
Bsp.: (wie gesagt ich bin mit deinem Thema komplett außen vor, also gut möglich dass meine Namensgebung für dich nicht wirklich Sinn macht ...)
C:
#include <stdio.h>

#define GET_BITS(bitset_, pos_, cnt_) ((__typeof__(bitset_))(((bitset_) >> (pos_)) & ((1ULL << (cnt_)) - 1)))
#define GET_ESS(bitset_) GET_BITS((bitset_), 0, 1)
#define GET_POINT_COORDINATOR(bitset_) GET_BITS((bitset_), 2, 2)

#define SET_BITS(bitset_, pos_, val_) ((bitset_) |= ((__typeof__(bitset_))(((val_) + 0ULL) << (pos_))))
#define SET_ESS(bitset_) SET_BITS((bitset_), 0, 1)
#define SET_POINT_COORDINATOR(bitset_, val_) SET_BITS((bitset_), 2, (val_))

#define CLEAR_BITS(bitset_, pos_, cnt_) ((bitset_) &= (__typeof__(bitset_))(~(((1ULL << (cnt_)) - 1) << (pos_))))
#define CLEAR_ESS(bitset_) CLEAR_BITS((bitset_), 0, 1)
#define CLEAR_POINT_COORDINATOR(bitset_) CLEAR_BITS((bitset_), 2, 2)

struct Parameters {
  unsigned long long timestamp;
  unsigned short beaconInterval;
  unsigned short capabilitiesInformation;
};

int main(void) {
  struct Parameters fixedParameters = {0x0807060504030201ULL, 0x0064, 0x1030};

  puts("~~~~~~~~~~");
  printf("%X\n", fixedParameters.capabilitiesInformation);
  printf("%u\n", GET_ESS(fixedParameters.capabilitiesInformation));
  puts("~~~~~~~~~~");
  SET_ESS(fixedParameters.capabilitiesInformation);
  printf("%X\n", fixedParameters.capabilitiesInformation);
  printf("%u\n", GET_ESS(fixedParameters.capabilitiesInformation));
  puts("~~~~~~~~~~");
  CLEAR_ESS(fixedParameters.capabilitiesInformation);
  printf("%X\n", fixedParameters.capabilitiesInformation);
  printf("%u\n", GET_ESS(fixedParameters.capabilitiesInformation));
  puts("~~~~~~~~~~");
  puts("~~~~~~~~~~");
  printf("%X\n", fixedParameters.capabilitiesInformation);
  printf("%u\n", GET_POINT_COORDINATOR(fixedParameters.capabilitiesInformation));
  puts("~~~~~~~~~~");
  SET_POINT_COORDINATOR(fixedParameters.capabilitiesInformation, 3);
  printf("%X\n", fixedParameters.capabilitiesInformation);
  printf("%u\n", GET_POINT_COORDINATOR(fixedParameters.capabilitiesInformation));
  puts("~~~~~~~~~~");
  CLEAR_POINT_COORDINATOR(fixedParameters.capabilitiesInformation);
  printf("%X\n", fixedParameters.capabilitiesInformation);
  printf("%u\n", GET_POINT_COORDINATOR(fixedParameters.capabilitiesInformation));
  puts("~~~~~~~~~~");
}
Macros sind natürlich nicht foolproof, aber eine Möglichkeit die Structs übersichtlich zu halten (auch hinsichtlich Alignment). Und anhand der beiden Beispiele sollte klar werden, wie du weitere spezialisierte Macros hinzufügen kannst (hoffe ich). Die SET_... Macros setzen die betroffenen Bits vorher nicht auf 0. Bei Sequenzen die aus mehreren Bits bestehen (wie point coordinator) musst du ggf. vorher mit dem CLEAR_... drüber.
 

lano

Aktives Mitglied
Du kannst schon einen Pointer zum anderen addieren, um etwas Code zu sparen wenn du willst.
Code:
buf = (uint8_t *)malloc(sz);

/* Put our pointers in the right place */

/* Pointer zum beginn von Buffer */
rt = (uint8_t *)buf;

/* Pointer zum beginn von radiotap + Radiotap size*/
hdr = (struct ieee80211_hdr *)(rt + sizeof(u8aRadiotapHeader));

/* Pointer zum beginn von header + header size*/
FixedParameter = (uint8_t *)(hdr + sizeof(struct ieee80211_hdr));

ich habs so probiert aber es bringt nicht das gewünschte Ergebnis.
 

german

Aktives Mitglied
devCommunity-Experte
Wenn du sowas wie ptr + sizeof(x) kalkulierst, musst du sicherstellen dass ptr ein Pointer auf ein Byte ist, weil sizeof Bytes zählt. Ich blick das jetzt nicht in deinem Schnipsel, aber mindestens in Zeile 12 sollte das interessant werden.
FixedParameter = (uint8_t *)hdr + sizeof(struct ieee80211_hdr);
In diesem Fall brauchst du nicht noch mal das Ergebnis casten, da das dann schon ein uint8_t * ist.
 

lano

Aktives Mitglied
Nächste Problem.
Ich hab mir jetzt gedacht ich stopf die ganzen daten in ein struct und bastel dann das Paket.

Nu hab ich keine Ahnung ob ich das mit dem Speicher Richtig mache und ob das überhaupt so klappen könnte.
Kurz um, ich bekomm das nicht hin.

Hier ma mein Versuch:
C:
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
Frame Control Field: 0x8000
    .... ..00 = Version: 0
    .... 00.. = Type: Management frame (0)
    1000 .... = Subtype: 8
*/

struct s_FrameControlField {
  uint8_t version;
  uint8_t type;
  uint8_t subtype;
};

struct s_Beacon {
  struct s_FrameControlField FrameControlField;
};

unsigned int mk_packet(uint8_t *packet, struct s_Beacon Beacon) {

  unsigned int size = 0;

  if (Beacon.FrameControlField.subtype != -1) {
    printf("\t\t Subtype: %d\n", Beacon.FrameControlField.subtype);
    packet = (uint8_t *)realloc(packet, 1);
    packet[0] = (Beacon.FrameControlField.subtype << 4);
    size++;
  }

  if (Beacon.FrameControlField.type != -1) {
    printf("\t\t Type: %d\n", Beacon.FrameControlField.type);
    //packet = (uint8_t*)realloc(packet, 1);
    packet[0] = (Beacon.FrameControlField.type << 2);
  }

  if (Beacon.FrameControlField.version != -1) {
    printf("\t\t Version: %d\n", Beacon.FrameControlField.version);
    packet = (uint8_t *)realloc(packet, 1);
    packet[1] = Beacon.FrameControlField.version;
    size++;
  }

  return size;
}

int main(void) {

  FILE *pFile;

  struct s_Beacon Beacon = {
      {
          // FrameControlField
          0, // version
          0, // type
          8, // subtype
      },
  };

  printf(" Beacon:\n");
  printf("\t FrameControlField:\n");
  printf("\t\t Version: %d\n", Beacon.FrameControlField.version);
  printf("\t\t Type: %d\n", Beacon.FrameControlField.type);
  printf("\t\t Subtype: %d\n", Beacon.FrameControlField.subtype);

  uint8_t *packet = NULL;
  unsigned int size;

  size = mk_packet(packet, Beacon);
  printf("size: %d\n", size);

  pFile = fopen("packet.bin", "wb");
  fwrite(&packet, size, 1, pFile);
  fclose(pFile);

  return 0;
}
 

german

Aktives Mitglied
devCommunity-Experte
Ich verstehe nicht mal denn Sinn für dein struct.
Ich meine, dein Frame Control Field ist 8 Bit aka 1 Byte breit (der Beschreibung der Bits folgend, wobei der resultierende Wert dann 0x80 und nicht 0x8000 ist). Dein struct ist 3 Bytes breit. Warum dann also überhaupt?
C:
uint8_t frameControlField = 0;
SET_BITS(frameControlField, 0, 0); // Version: 0
SET_BITS(frameControlField, 2, 0); // Type: Management frame (0)
SET_BITS(frameControlField, 4, 8); // Subtype: 8
SET_BITS Macro siehe oben. Der pos_ Parameter ist der Index des Bits, angefangen mit 0 für das LSB.
Für das Beispiel braucht es die ersten beiden Macroaufrufe eigentlich nicht, denn frameControlField ist sowieso mit 0 initialisiert.
 

german

Aktives Mitglied
devCommunity-Experte
ist für mich später leichter zu schreiben.
Joa, du bringst dich aber selber durcheinander wenn du da andere Breiten hast als du benötigst.
Anfangen musst du aber sowieso da:
C:
/*
Frame Control Field: 0x8000
    .... ..00 = Version: 0
    .... 00.. = Type: Management frame (0)
    1000 .... = Subtype: 8
*/
Sowas ist extrem hilfreich. Muss aber stimmen. Soll da wirklich 0x8000 rauskommen? Dann sind das 16 Bit. Beschrieben hast du dann aber 8 Bit. Mach das mal schön, dann schreib ich dir fix ein struct runter was dazu passt ....

Wo du dann vermutlich komplett daneben liegst sind deine Reallokationen.
- In Zeile 29 machst du packet 1 Byte breit. Hoffen wir mal dass es ursprünglich ein NULL Pointer war, dann geht da auch realloc statt malloc/calloc. Aber dann ...
- In Zeile 42 steht da wieder eine 1 und dein realloc macht vermutlich nix, denn du hast ja schon einen Speicherbereich von einem Byte allokiert. Ist aber auch egal, den nun kracht's in Zeile 43. Du greifst auf Index 1 zu, wo nur 1 Byte Speicher liegt. Segfault (und falls dein Programm nicht crasht, dann zumindest off-by-one).
 

lano

Aktives Mitglied
Soll da wirklich 0x8000 rauskommen?
Nein. Da kommt noch was danach.

Es geht um nen Beacon Frame vom Wifi. 802.11.
Hier wäre ein Beispiel https://gist.github.com/mortenjust/148b2e3403809e5f12ac

Wie gesagt. Ich hab jetzt das fast allesin structs gepackt. ungeachtet der eigentlichen breiten. erstmal um da überhaupt nen Anfang zu haben.

Meine überlegung erst mal das struct zu füllen und dann das paket zu generieren find ich eigentlich nicht schlecht.
Kurz zur Erklärung. Ein Accesspoint sendet in regelmäßigen abständen die beacon frames aus.
Ein Client erkennt daran das ein wlan in der nähe ist und dessen eigenschaften. Kanal. Verschlüsselung usw.
Mein ziel ist es das beacon komplett frei anzupassen. ZB. die SSID.
Zurück zum Programm. Dann könnte ich das struct füllen. paket generieren und senden. ssid ändern, paket generieren und wieder senden.
Ein Client würde dann schon mal zwei netze anzeigen. Wenn man die beiden beacons alle 100ms sendet.
Es gibt unterschiedlichste implementierungen in den clients zB frist mein altes Blackberry so gut wie jedes becon frame, mein huawei handy nicht. Es geht mir vorrangig aber weniger um einen "pentester" als um einen fake accesspoint. Hintergrund. ZB sendet mein Handy regelmäßig probe requests. Die sind dafür da das ein client netze in der umgebung finden kann. Nu gibt es da zwei arten. einmal welche die an broadcast gesendet werden. Dann meldet sich jedes netz in der umgebung mit einem probe response. oder addressierte. die werden an eine bestimmte mac gesendet. und nur der Accesspoint mit der empfänger mac antwortet dann. Nu ist das so das viele Handys auch die ssid zur mac senden. und das will ich nutzen. empfange ich ein probe request mit ssid soll der fake Accesspoint die anfrage beantworten und so tun als sei er der accesspoint. in der hoffnung das sich das handy versucht sich mit ihm zu verbinden.
Soweit so gut...

Hier hab ich mal versucht das in structs zu packen. Allerdings gibt es da für mich noch einige hürden.
Die Bitfelder stimmen nicht zwingend. und es ist auch noch nicht komplett.
C:
struct DsStatus {
  uint8_t tods : 1;
  uint8_t fromds : 1;
};

struct FrameControlFieldFlags {
  struct DsStatus ds_status;
  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;
};

struct FrameControlField {
  uint8_t version;
  uint8_t type;
  uint8_t subtype;
  struct FrameControlFieldFlags flags;
};

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

struct FixedParameters {
  unsigned int Timestamp;
  unsigned int BeaconInterval;
  uint8_t ESS_capabilities : 1;
  uint8_t IBSS_status : 1;
  uint8_t CFP_participation_capabilities : 1;
  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;
};
////////////////////////////////////////////////////////////////////////////////

struct SSID_parameter {
  /* Tag: SSID parameter set: X-MAS
    Tag Number: SSID parameter set (0)
    Tag length: 5
    SSID: X-MAS
  */
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  char *SSID;
};

struct SupportedRate {
  int value;
  struct SupportedRate *next;
};

struct SupportedRates {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  struct SupportedRate rate;

  //int SupportedRate;
  //int SupportedRate;
  //..
};

struct DS_Parameter {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  uint8_t CurrentChannel;
};

struct TrafficIndicationMap {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  uint8_t DTIM_count;
  uint8_t DTIM_period;
  uint8_t Bitmap_control;
  uint8_t Multicast;
  uint8_t BitmapOffset;
  uint8_t PartialVirtualBitmap;
};

struct CountryInformation {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  char Code[2];
  uint8_t Environment;
  uint8_t FirstChannelNumber;
  uint8_t NumberOfChannels;
  uint8_t MaximumTransmitPowerLevel;
};

struct ERP_Information {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  uint8_t NonERPPresent;
  uint8_t UseProtection;
  uint8_t BarkerPreambleMode;
  uint8_t Reserved;
};

struct ExtendedSupportedRates {};
struct QBSSLoadElement {};
struct RMEnabledCapabilities {};
struct HTCapabilities {};
struct HTInformation {};
struct OverlappingBSSScanParameters {};
struct ExtendedCapabilities {};
struct RSNInformation {};
struct VendorSpecific {};

////////////////////////////////////////////////////////////////////////////////
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 HTCapabilities HT_Capabilities;
  struct HTInformation HT_Information;
  struct OverlappingBSSScanParameters OverlappingBSSScan_Parameters;
  struct ExtendedCapabilities Extended_Capabilities;
  struct RSNInformation RSN_Information;
  struct VendorSpecific Vendor_Specific;
};

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

hier ma der komplette anfangs versuch.
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <pcap.h>

#define TRUE 1
#define FALSE 0

struct DsStatus {
  uint8_t tods : 1;
  uint8_t fromds : 1;
};

struct FrameControlFieldFlags {
  struct DsStatus ds_status;
  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;
};

struct FrameControlField {
  uint8_t version;
  uint8_t type;
  uint8_t subtype;
  struct FrameControlFieldFlags flags;
};

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

struct FixedParameters {
  unsigned int Timestamp;
  unsigned int BeaconInterval;
  uint8_t ESS_capabilities : 1;
  uint8_t IBSS_status : 1;
  uint8_t CFP_participation_capabilities : 1;
  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;
};
////////////////////////////////////////////////////////////////////////////////

struct SSID_parameter {
  /* Tag: SSID parameter set: X-MAS
    Tag Number: SSID parameter set (0)
    Tag length: 5
    SSID: X-MAS
  */
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  char *SSID;
};

struct SupportedRate {
  int value;
  struct SupportedRate *next;
};

struct SupportedRates {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  struct SupportedRate rate;

  //int SupportedRate;
  //int SupportedRate;
  //..
};

struct DS_Parameter {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  uint8_t CurrentChannel;
};

struct TrafficIndicationMap {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  uint8_t DTIM_count;
  uint8_t DTIM_period;
  uint8_t Bitmap_control;
  uint8_t Multicast;
  uint8_t BitmapOffset;
  uint8_t PartialVirtualBitmap;
};

struct CountryInformation {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  char Code[2];
  uint8_t Environment;
  uint8_t FirstChannelNumber;
  uint8_t NumberOfChannels;
  uint8_t MaximumTransmitPowerLevel;
};

struct ERP_Information {
  uint8_t TagNumber : 8;
  uint8_t TagLength : 8;
  uint8_t NonERPPresent;
  uint8_t UseProtection;
  uint8_t BarkerPreambleMode;
  uint8_t Reserved;
};

struct ExtendedSupportedRates {};
struct QBSSLoadElement {};
struct RMEnabledCapabilities {};
struct HTCapabilities {};
struct HTInformation {};
struct OverlappingBSSScanParameters {};
struct ExtendedCapabilities {};
struct RSNInformation {};
struct VendorSpecific {};

////////////////////////////////////////////////////////////////////////////////
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 HTCapabilities HT_Capabilities;
  struct HTInformation HT_Information;
  struct OverlappingBSSScanParameters OverlappingBSSScan_Parameters;
  struct ExtendedCapabilities Extended_Capabilities;
  struct RSNInformation RSN_Information;
  struct VendorSpecific Vendor_Specific;
};

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

unsigned int mk_packet(uint8_t *packet, struct Beacon beacon) {

  unsigned int size = 0;
  packet = (uint8_t *)realloc(packet, 1000);

  if (beacon.frameControlField.subtype != -1) {
    printf("\t\t Subtype: %d\n", beacon.frameControlField.subtype);
    //    packet = (uint8_t*)realloc(packet, 1);
    packet[0] = (beacon.frameControlField.subtype << 4);
    size++;
  }

  if (beacon.frameControlField.type != -1) {
    printf("\t\t Type: %d\n", beacon.frameControlField.type);
    //    packet = (uint8_t*)realloc(packet, 1);
    //packet[0] = (beacon.frameControlField.type << 2);
  }

  if (beacon.frameControlField.version != -1) {
    printf("\t\t Version: %d\n", beacon.frameControlField.version);
    //  packet = (uint8_t*)realloc(packet, 1);
    packet[1] = beacon.frameControlField.version;
    size++;
  }

  return size;
}

int main(void) {

  FILE *pFile;

  struct Beacon beacon = {
      {
          // FrameControlField
          5, // version
          0, // type
          8, // subtype
          {
              // FrameControlFieldFlags
              {
                  // DsStatus
                  0, // FromDS
                  0, // ToDS
              },
              0, //more_fragments,
              0, //retry,
              0, //pwr_mgt,
              0, //more_data,
              0, //protected_flag,
              0, //order_flag,
          },
      },
      0, // Duration
      0, // mac1
      0, // mac2
      0, // mac3
      0, // FragmentNumber
      0, // SequenceNumber
      {
          //FixedParameters
          0, // Timestamp
          0, // Beacon Interval
          0, // Capabilities Information
      },
      {
          // TaggedParameters
          {
              // SSID parameter
              0, // Tag Number
              0, // Tag length
              0, // SSID
          },

      },
      0, // FSC
  };

  printf(" Beacon:\n");
  printf("\t FrameControlField:\n");
  printf("\t\t Version: %d\n", beacon.frameControlField.version);
  printf("\t\t Type: %d\n", beacon.frameControlField.type);
  printf("\t\t Subtype: %d\n", beacon.frameControlField.subtype);
  printf("\t\t\t FrameControlFieldFlags:\n");
  printf("\t\t\t\t DS Status:\n");
  printf("\t\t\t\t\t FromDS: %d\n", beacon.frameControlField.flags.ds_status.fromds);
  printf("\t\t\t\t\t ToDS: %d\n", beacon.frameControlField.flags.ds_status.tods);
  printf("\t\t\t\t more_fragments: %d\n", beacon.frameControlField.flags.more_fragments);
  printf("\t\t\t\t retry: %d\n", beacon.frameControlField.flags.retry);
  printf("\t\t\t\t pwr_mgt: %d\n", beacon.frameControlField.flags.pwr_mgt);
  printf("\t\t\t\t more_data: %d\n", beacon.frameControlField.flags.more_data);
  printf("\t\t\t\t protected_flag: %d\n", beacon.frameControlField.flags.protected_flag);
  printf("\t\t\t\t order_flag: %d\n", beacon.frameControlField.flags.order_flag);
  printf("\t Duration: %d\n", beacon.Duration);
  printf("\t mac1: %d\n", beacon.mac1);
  printf("\t mac2: %d\n", beacon.mac2);
  printf("\t mac3: %d\n", beacon.mac3);
  printf("\t FragmentNumber: %d\n", beacon.FragmentNumber);
  printf("\t SequenceNumber: %d\n", beacon.SequenceNumber);
  printf("\t\t FixedParameters:\n");
  printf("\t\t\t Timestamp: %d\n", beacon.fixedParameters.Timestamp);
  printf("\t\t\t BeaconInterval: %d\n", beacon.fixedParameters.BeaconInterval);
  printf("\t\t\t ESS_capabilities: %d\n", beacon.fixedParameters.ESS_capabilities);
  printf("\t\t\t IBSS_status: %d\n", beacon.fixedParameters.IBSS_status);
  printf("\t\t\t CFP_participation_capabilities: %d\n", beacon.fixedParameters.CFP_participation_capabilities);
  printf("\t\t\t Privacy: %d\n", beacon.fixedParameters.Privacy);
  printf("\t\t\t Short_Preamble: %d\n", beacon.fixedParameters.Short_Preamble);
  printf("\t\t\t PBCC: %d\n", beacon.fixedParameters.PBCC);
  printf("\t\t\t Channel_Agility: %d\n", beacon.fixedParameters.Channel_Agility);
  printf("\t\t\t Spectrum_Management: %d\n", beacon.fixedParameters.Spectrum_Management);
  printf("\t\t\t Short_Slot_Time: %d\n", beacon.fixedParameters.Short_Slot_Time);
  printf("\t\t\t Automatic_Power_Save_Delivery: %d\n", beacon.fixedParameters.Automatic_Power_Save_Delivery);
  printf("\t\t\t Radio_Measurement: %d\n", beacon.fixedParameters.Radio_Measurement);
  printf("\t\t\t DSSS_OFDM: %d\n", beacon.fixedParameters.DSSS_OFDM);
  printf("\t\t\t Delayed_Block_Ack: %d\n", beacon.fixedParameters.Delayed_Block_Ack);
  printf("\t\t\t Immediate_Block_Ack: %d\n", beacon.fixedParameters.Immediate_Block_Ack);
  printf("\t\t TaggedParameters:\n");
  printf("\t\t\t SSID Parameter:\n");
  printf("\t\t\t\t TagNumber: %d\n", beacon.taggedParameters.SSIDParameter.TagNumber);
  printf("\t\t\t\t TagLength: %d\n", beacon.taggedParameters.SSIDParameter.TagLength);
  printf("\t\t\t\t SSID: %s\n", beacon.taggedParameters.SSIDParameter.SSID);

  printf("\t FSC: %d\n", beacon.FSC);

  uint8_t *packet = NULL;
  unsigned int size;

  size = mk_packet(packet, beacon);

  printf("size: %d\n", size);

  pFile = fopen("myfile.bin", "wb");
  fwrite(&packet, size, 1, pFile);
  fclose(pFile);

  return 0;
}

Wo du dann vermutlich komplett daneben liegst sind deine Reallokationen.
Ja das sach ich dir. War ja schon immer scheiße bei mir, aber ist echt gar nix von hängen geblieben. null.
In Zeile 42 steht da wieder eine 1 und dein realloc macht vermutlich nix, denn du hast ja schon einen Speicherbereich von einem Byte allokiert.
Ahha. ich bin davon ausgegangen das dann der speicherbereich um 1 erweitert wird.
st aber auch egal, den nun kracht's in Zeile 43. Du greifst auf Index 1 zu, wo nur 1 Byte Speicher liegt. Segfault (und falls dein Programm nicht crasht, dann zumindest off-by-one).
doch, crashed mit segfault :)

Meinste das
Mach das mal schön, dann schreib ich dir fix ein struct runter was dazu passt ....
Ja nett. Ich pack dir ma ne pcap mit bei. Die kannst du dir mit wireshark ansehen.
Wenn was unklar ist einfach fragen... Aber ich glaub du kommst damit besser zurecht als ich...
 

Anhänge

  • Beacon.zip
    367 Bytes · Aufrufe: 52

german

Aktives Mitglied
devCommunity-Experte
Die kannst du dir mit wireshark ansehen.
Muharhar :ROFLMAO: Hatte ich schon erwähnt, dass ich von dem Netzwerkkram ... ? Ja hatte ich. Also, ich weiß dass es sowas wie Wireshark gibt. Mehr aber auch nicht.

Die Bitfelder stimmen nicht zwingend.
Ja, da liegt immer der Hase im Pfeffer. Das muss stimmen, und das muss immer die Breite eines der Integertypen ergeben, sonst wird da Müll draus.
Nehmen wir noch mal das Beispiel, mal 8 Bit und mal 16 Bit breit.
C:
#include <stdint.h>
#include <stdio.h>

/*
Frame Control Field: 0x81
    .... ..01 = Version: 1
    .... 00.. = Type: Management frame (0)
    1000 .... = Subtype: 8
*/
struct s_FrameControlField {
  union {
    uint8_t data;
    struct {
      uint8_t version : 2;
      uint8_t type : 2;
      uint8_t subtype : 4;
    };
  };
} __attribute__((packed));

/*
Frame Control Field 2: 0x8001
    .... .... 0000 0001 = Version: 1
    .... 0000 .... .... = Type: Management frame (0)
    1000 .... .... .... = Subtype: 8
*/
struct s_FrameControlField2 {
  union {
    uint16_t data;
    struct {
      uint16_t version : 8;
      uint16_t type : 4;
      uint16_t subtype : 4;
    };
  };
} __attribute__((packed));

int main(void) {
  struct s_FrameControlField frameCtrlField = {0};
  frameCtrlField.version = 1;
  frameCtrlField.type = 0;
  frameCtrlField.subtype = 8;
  printf("%02X  size: %zu\n", (unsigned)frameCtrlField.data, sizeof(frameCtrlField));

  struct s_FrameControlField2 frameCtrlField2 = {0};
  frameCtrlField2.version = 1;
  frameCtrlField2.type = 0;
  frameCtrlField2.subtype = 8;
  printf("%04X  size: %zu\n", (unsigned)frameCtrlField2.data, sizeof(frameCtrlField2));

  return 0;
}
Ausgabe:
Code:
81  size: 1
8001  size: 2
Das ist natürlich nun komplett implementationsspezifisch. Vorausgesetzt habe ich Compiler gcc, und Little Endian Bytereihenfolge.
Das data Member hat einen Typ, der unten auch wieder im Bitfeld auftaucht. Ist der Typ im Bitfeld breiter, wird auch das struct breiter, und das wollen wir auf keinen Fall.
Die Breite des data Members spiegelt exakt die Anzahl Bits im Bitfeld wieder. Nie mehr und nie weniger.
Am besten du bastelst dir so einen Versuchscode wie der oben, um zu sehen dass das nichts schief geht.
 

lano

Aktives Mitglied
Hatte ich schon erwähnt, dass ich von dem Netzwerkkram ... ?
:) Öhm jaa? Ich erinner mich.
Mehr aber auch nicht.
Ist zum klicken und bunt. kann man nicht viel falsch machen. zeigt halt gut die daten an.
Ja, da liegt immer der Hase im Pfeffer.
Ich hasse hasen und pfeffer
Am besten du bastelst dir so einen Versuchscode wie der oben, um zu sehen dass das nichts schief geht.
ok, ich probier das mal.

wofür ist uint8_t data; im struct ?
 

german

Aktives Mitglied
devCommunity-Experte
wofür ist uint8_t data; im struct ?
Damit der Compiler weiß was du mit der union vorhast. Nämlich ein vernünftiges Alignment zu bekommen. Und das geht nur unter den Bedingungen die ich oben geschrieben habe. Versuch so was wie ...
C:
struct DsStatus {
  uint8_t tods : 1;
  uint8_t fromds : 1;
};
... gar nicht erst. Es wird kein struct geben das nur 2 Bit breit ist. Das Ding ist 8 Bit breit. Und da das ganze ja anschließend ein zusammenhängender Speicherbereich werden soll, kannst du dir "Löcher" durch ein Padding nicht leisten. Du must die Bitliste immer so arrangieren, dass du die Breite eines der Integer Typen erreichst. Und dein data Member ist das Maß dafür. Also uintN_t mit N = 8, 16, 32 oder 64, sowie respektive 8, 16, 32 oder 64 Bit in der Bitliste. Lies den letzten Abschnitt oben noch mal. Da hatte ich die Regeln erklärt.
Und wenn du dann die einzelnen structs noch mal in ein übergreifendes zusammenführst, vergiss bloß das __attribute__((packed)) nicht, sonst ist Padding zwischen den einzelnen structs fast schon vorprogrammiert...
 

lano

Aktives Mitglied
Ehhh... ich muss da noch ma fragen.
Macht das dann so sinn ?

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));
 

german

Aktives Mitglied
devCommunity-Experte
Kannst du machen, aber ... Wenn du das vorhergehende struct immer mit in das Bitfeld packst, bist du mit den Typbreiten für data ziemlich schnell am Ende ;)
C:
struct FrameControlField {
  union {
    uint8_t data;
    struct {
      uint8_t version : 2;
      uint8_t type : 2;
      uint8_t subtype : 4;
    };
  };
  struct FrameControlFieldFlags flags; // 8
} __attribute__((packed));
Macht dann 16 Bit in Summe. Die Member der union teilen sich denselben Speicherbereich. Also data und das Bitfeld. Das sind einmal 8 Bit. Dazu dann die 8 Bit von FrameControlFieldFlags.
 
Oben Unten