struct füllen



  • Hallo,

    es gibt für PPPoE-Header folgende structs (in /usr/src/linux/include/linux/if_pppox.h):

    struct pppoe_hdr {
            __u8 ver : 4;
            __u8 type : 4;
            __u8 code;
            __u16 sid;
            __u16 length;
            struct pppoe_tag tag[0];
    } __attribute__ ((packed));
    
    struct pppoe_tag {
            __u16 tag_type;
            __u16 tag_len;
            char tag_data[0];
    } __attribute ((packed));
    

    und zur allgemeinen Info folgende Konstanten:

    #define PADI_CODE       0x09
    #define PADO_CODE       0x07
    #define PADR_CODE       0x19
    #define PADS_CODE       0x65
    #define PADT_CODE       0xa7
    
    #define PTT_EOL         __constant_htons(0x0000)
    #define PTT_SRV_NAME    __constant_htons(0x0101)
    #define PTT_AC_NAME     __constant_htons(0x0102)
    #define PTT_HOST_UNIQ   __constant_htons(0x0103)
    #define PTT_AC_COOKIE   __constant_htons(0x0104)
    #define PTT_VENDOR      __constant_htons(0x0105)
    #define PTT_RELAY_SID   __constant_htons(0x0110)
    #define PTT_SRV_ERR     __constant_htons(0x0201)
    #define PTT_SYS_ERR     __constant_htons(0x0202)
    #define PTT_GEN_ERR     __constant_htons(0x0203)
    

    Ich erstell mir eine Variable vom Typ struct pppoe_hdr und will es mit zwei (!) pppoe_tags füllen:

    char *ac_name = "ac_name1";
    
    struct pppoe_hdr pppoehdr;
    pppoehdr.code = PADO_CODE;
    pppoehdr.ver = 1;
    pppoehdr.type = 1;
    pppoehdr.sid = 0;
    
    pppoehdr.tag[0].tag_type = PTT_AC_NAME;
    pppoehdr.tag[0].tag_len = strlen(ac_name);
    strcpy(pppoehdr.tag[0].tag_data[0], ac_name);
    
    pppoehdr.tag[1].tag_type = PTT_SRV_NAME;
    
    pppoehdr.length = htons(sizeof(pppoehdr.tag[0]) + pppoehdr.tag[0].tag_len;
    

    Aber in der Zeile

    strcpy(pppoehdr.tag[0].tag_data[0], ac_name);
    

    gibt es (verständlicherweise) eine Speicherschutzverletzung (da ja nur ein Byte reserviert wurde)

    in der Zeile

    pppoehdr.tag[1].tag_type = PTT_SRV_NAME;
    

    Müsste es demnach auch einen geben.

    Aber wie kann ich pppoehdr.tag[0].tag_data[0] so erweitern, dass ac_name reinpasst und pppoehdr.tag auf eine Array der Länge 2 erweitern, damit ich pppoehdr.tag[1] auffüllen kann?

    (Ich hoffe, ihr versteht meine Frage)

    Tschö
    Manuel



  • Beachte die deklaration von tag als Zero Length Array. Das ist eine spezielle GCC Erweiterung, die du glaube ich nicht richtig initialisierst, so dass der Compiler keinen Speicher zur Verfügung stellt.

    http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/gcc/Zero-Length.html



  • ahh, cool.
    Danke für den Hinweis!



  • jetzt hab ich aber doch noch ein Problem.

    ich erstelle mein struct jetzt so:

    int size = = sizeof(struct pppoe_hdr) + strlen(ac_name) + 2*sizeof(struct pppoe_tag);
    
    struct pppoe_hdr *pppoeh = malloc(size);
    struct pppoe_tag *pppoetag;
    pppoeh->code = PADS_CODE;
    pppoeh->ver = 1;
    pppoeh->type = 1;
    pppoeh->sid = rand()*0x100+rand();
    pppoeh->length = htons(iov[i].iov_len - sizeof(struct pppoe_hdr));
    
    pppoetag = pppoeh+1;                          // !!!
    pppoetag->tag_type = PTT_AC_NAME;
    pppoetag->tag_len = htons(strlen(ac_name));
    strcpy(pppoetag->tag_data, ac_name);
    pppoetag = pppoetag + strlen(ac_name)/2 - 1;  // !!!
    pppoetag->tag_type = PTT_SRV_NAME;
    

    Die zwei mit Ausrufezeichen gekennzeichneten Zeilen sind mein Problem.
    Ich krieg es irgendwie nicht hin, diese stellen zu berechnen.

    Ich habe schon versucht den ersten tag mit
    pppoeh->tag[0] anzusprechen. Das geht auch.
    Aber pppoe->tag[1] zeigt nicht auf die richtige Adresse (wohl da der Speicherbereich ac_name nicht beachtet wird)

    Könnt ihr mir nochmal helfen?

    Tschö
    Manuel


Anmelden zum Antworten