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