0

重複の可能性:
C - 構造体へのバイト配列 (dns クエリ)

私はこれらの構造を持っています:

typedef struct dnsQuery {
  char header[12];
  struct dnsQuerySection *querySection;
} TdnsQuery;

typedef struct dnsQuerySection {
  unsigned char *name;
  struct dnsQueryQuestion *question;
} TdnsQuerySection;

typedef struct dnsQueryQuestion {
  unsigned short qtype;
  unsigned short qclass;
} TdnsQueryQuestion;

bufそして、からのバイト配列に DNS クエリがありますrecvfrom。次のようにバイト配列から構造を取得しようとしています:

TdnsQuery* dnsQuery = (TdnsQuery*)buf;

次のようにqtypeにアクセスしようとしたとき:

printf("%u", dnsQuery->querySection->question.qtype);

seg fault 11 が表示されます。

誰かがこれらの構造を手伝ってくれますか? 彼らの何が問題なのですか?構造を追加しようとしました:

typedef struct udpPacket {
  char header[8];
  structr dnsQuery query;
}

この構造をバイト配列からマップしましたが、役に立ちませんでした。誰かがこれらの構造を手伝ってくれますか? UDP プロトコルを使用した DNS クエリの場合、どのように表示されますか?

編集:私の構造は次のようになりました:

 typedef struct {
      unsigned short qtype;
      unsigned short qclass;
 } dnsQueryQuestion;

 typedef struct {

      dnsQueryQuestion *question;
      unsigned char *data[0];
 } dnsQuerySection;

 typedef struct {
      char header[12];
      dnsQuerySection querySection[0];
 } dnsQuery;

 typedef struct udpPacket {
      char header[8];
      dnsQuery query[0];
 } TudpPacket;

解析機能を追加しました:

void parse(unsigned char *data, unsigned short *qtype, unsigned short *qclass) {
    int i = 0;
    while (data[i]) {
        int len = data[i];
        i += len + 1;
    }
    *qtype = (unsigned short) data[i+1];
    *qclass = (unsigned short) data[i+3];
    return;
} 

そして解析しようとしました:

TudpPacket udpPack = (TudpPacket)buf;
parse(udpPack.query.querySection.data, &(udpPack.query.querySection.question.qtype), &(udpPack.query.querySection.question.qclass));
printf("%u\n", udpPack.query.querySection.question.qtype);
4

1 に答える 1

3

まず、これに変更することから始めることができますdnsQuery

typedef struct dnsQuery {
  char header[12];
  struct dnsQuerySection querySection[0];
} TdnsQuery;

ここで長さゼロの配列の使用法を参照してください: http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

ただし、QNAMEDNS の質問の部分は可変長であるため、直接使用して分離して使用することはできない場合がQTYPEありQCLASSますstruct。例えば、

Header

00 01   - ID = 1
01 00   - RD = 1
00 01   - QD = 1
00 00   - AN
00 00   - NS
00 00   - NR

   Question  for www.google.com

   03 77   - 3 w
   77 77   - w w
   06 67   - 6 g
   6f 6f   - o o
   67 6c   - g l
   65 03   - e 3
   63 6f   - c o
   6d 00   - m 0
   00 01   - QTYPE
   00 01   - QCLASS

着信リクエストに質問が1 つしかないことを保証できる場合は、次のことを試してください。

typedef struct dnsQuerySection {
  unsigned char *data[0];
} TdnsQuerySection;

そしてそれを解析する関数を書きます。

編集:以下は、便宜上、解析関数のスケッチです。

char* parse(unsigned char *data, unsigned short *qtype, unsigned short *qclass) {
    int i = 0;
    while (data[i]) {
        int len = data[i];
        i += len + 1;
    }
    /* data[i] == 0 */
    /* you may need to loop data[] again and do strcpy to get the domain name */
    *qtype = (unsigned short) data[i+1];
    *qclass = (unsigned short) data[i+3];
    return /* domain name */;
}
于 2012-11-18T10:56:46.163 に答える