GetIfTable2 - wie funktionierts richtig?

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

GetIfTable2 - wie funktionierts richtig?

Beitrag von GPI »

Ich versuche Gerade GetIfTable2 zum laufen zu bringen.

hier die infos von MS:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
hier die Strucktur:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

Ich hab folgendes bisher gemacht:

Code: Alles auswählen

Global library
library=OpenLibrary(1,"Iphlpapi.dll")
Procedure GetIfTable2(a)
  ProcedureReturn CallFunction(1,"GetIfTable2",a)  
EndProcedure
Procedure  FreeMibTable(a)
  ProcedureReturn CallFunction(1,"FreeMibTable",a)    
EndProcedure

#IF_MAX_STRING_SIZE    = 256
#IF_MAX_PHYS_ADDRESS_LENGTH =32

Structure MIB_IF_ROW2 
  InterfaceLuid.b[8] ; Ein Quad 
   
  InterfaceIndex.l
  InterfaceGuid.b[4+2+2+8]
  Alias.u[#IF_MAX_STRING_SIZE +1];
  Description.u[#IF_MAX_STRING_SIZE +1];
  PhysicalAddressLength.l;
  PhysicalAddress.b[#IF_MAX_PHYS_ADDRESS_LENGTH];
  PermanentPhysicalAddress.b[#IF_MAX_PHYS_ADDRESS_LENGTH];
  Mtu.l;
  Type.l;
  TunnelType.l;?
  MediaType.l;?
  PhysicalMediumType.l;?
  AccessType.l;?
  DirectionType.l;?
  InterfaceAndOperStatusFlags.l
;   #struct {
;     BOOLEAN HardwareInterface  :1;
;     BOOLEAN FilterInterface  :1;
;     BOOLEAN ConnectorPresent   :1;
;     BOOLEAN NotAuthenticated  :1;
;     BOOLEAN NotMediaConnected  :1;
;     BOOLEAN Paused  :1;
;     BOOLEAN LowPower  :1;
;     BOOLEAN EndPointInterface  :1;
;   } InterfaceAndOperStatusFlags;
  OperStatus.l;
  AdminStatus.l;
  MediaConnectState.l;
  NetworkGuid.b[4+2+2+8];
  ConnectionType.l;
  TransmitLinkSpeed.q;
  ReceiveLinkSpeed.q;
  InOctets.q;
  InUcastPkts.q;
  InNUcastPkts.q;
  InDiscards.q;
  InErrors.q;
  InUnknownProtos.q;
  InUcastOctets.q;
  InMulticastOctets.q;
  InBroadcastOctets.q;
  OutOctets.q;
  OutUcastPkts.q;
  OutNUcastPkts.q;
  OutDiscards.q;
  OutErrors.q;
  OutUcastOctets.q;
  OutMulticastOctets.q;
  OutBroadcastOctets.q;
  OutQLen.q;
  fill.l; <--- Strucktur ist um 4 zu klein, aber wo?
EndStructure

buf.l
If GetIfTable2(@buf)=#ERROR_SUCCESS
  count=PeekL(buf)
  Debug PeekL(buf)
  Debug PeekL(buf+4)
  Debug PeekQ(buf)
  Debug "Anzahl:"+Str(count)  
  *line.mib_if_row2=buf+8;<- eigentlich müßte es+4 heißen, aber dann stimmt was nicht!
  For i=1 To count
    Debug "index:"+Str(*line\InterfaceIndex)
    ;Debug @*line\InterfaceIndex-*line
    Debug PeekS(@*line\Description,#IF_MAX_STRING_SIZE,#PB_Unicode)
    Debug PeekS(@*line\Alias,#IF_MAX_STRING_SIZE,#PB_Unicode)
    a$=""
    For b=0 To *line\PhysicalAddressLength-1
      a$+Hex(*line\PhysicalAddress[b] &$FF)
    Next
    ;Debug a$
    b=4
    a=PeekQ(@*line\inOctets+b)
    Debug Str(b)+"x:"+Hex(a)+" "+Str(a)

    
    *line+SizeOf(mib_if_row2)  
  Next
EndIf

    

FreeMibTable(buf)
Ja ist schlampig gemacht ;9

Meine Fragen:
Die Strucktur - irgendwo ist noch ein großer Fehler drin. die ist 4 Bytes zu klein.

Das zweite Problem: Das Datenfeld beginnt bei mir irgendwie 4 Bytes zu weit unten - ansonsten gibt Index bspw. völlig unsinige Werte. Aber InterfaceLuid ist definitv 8 Bytes groß - also kann ich nicht beide Probleme koppeln, wenn ich InterfaceLuid 4 Bytes größer mach.

Hat jemand eine Ahnung, wo mein Denkfehler ist?
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von STARGÅTE »

Vermutung:

Code: Alles auswählen

  InterfaceAndOperStatusFlags.l
;   #struct {
;     BOOLEAN HardwareInterface  :1;
;     BOOLEAN FilterInterface  :1;
;     BOOLEAN ConnectorPresent   :1;
;     BOOLEAN NotAuthenticated  :1;
;     BOOLEAN NotMediaConnected  :1;
;     BOOLEAN Paused  :1;
;     BOOLEAN LowPower  :1;
;     BOOLEAN EndPointInterface  :1;
;   } InterfaceAndOperStatusFlags;
Wieso hast du das auskommentiert ...
scheinbar hat doch InterfaceAndOperStatusFlags eine "Unterstruktur" mit 8 Booleans also Byte ?
somit wäre wenn überhaupt InterfaceAndOperStatusFlags.q richtig aber nicht .l ...
dort wäre also schon mal die 4 Bytes die fehlen...
Und es müsste dann InterfaceAndOperStatusFlags.InterfaceAndOperStatusFlags
heißen
wobei InterfaceAndOperStatusFlags dann eine Struktur wäre:

Code: Alles auswählen

Structure InterfaceAndOperStatusFlags
  HardwareInterface.b
  FilterInterface.b
  ConnectorPresent.b
  NotAuthenticated.b
  NotMediaConnected.b
  Paused.b
  LowPower.b
  EndPointInterface.b
EndStructure
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von GPI »

das original sieht so aus:

Code: Alles auswählen

struct {
    BOOLEAN HardwareInterface  :1;
    BOOLEAN FilterInterface  :1;
    BOOLEAN ConnectorPresent   :1;
    BOOLEAN NotAuthenticated  :1;
    BOOLEAN NotMediaConnected  :1;
    BOOLEAN Paused  :1;
    BOOLEAN LowPower  :1;
    BOOLEAN EndPointInterface  :1;
  } InterfaceAndOperStatusFlags;
:1 beudeutet hier Ein Bit von Typ Boolean. GEsamt also eigent 8 BIt=1Byte

damit wären es aber eigentlich 7Bytes, wo meine Structur zu klein ist :)

Kurzer Test ergab auch, das die Werte dann in den Bereich nicht sinnvoll sind.

Erklärt zudem nicht die allgemeine 4 Byte-Verschiebung
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von Kiffi »

<OT>

Welcome back, GPI! :D

</OT>
a²+b²=mc²
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von DarkDragon »

http://msdn.microsoft.com/en-us/library ... 85%29.aspx

NET_LUID hat 2 quads:

Code: Alles auswählen

InterfaceLuid.b[16] ; Zwei Quads
Ach ne ist ja ne union.. sowas gibts ja auch global, sorry.

[EDIT] (hoffentlich hat ers nicht schon davor gelesen und liest es jetzt nichtmehr)

InterfaceIndex.q muss es heißen.

Ich hab in C einfach mal ein Testprogramm erstellt, welches das hier als semantischen Inhalt hatte:

printf("%d", sizeof(MIB_IF_ROW2));

Und dann habe ich Teile der Struktur parallel in PB und C auskommentiert bis ich den Fehler hatte.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von GPI »

index-als quad kann nicht sein. dann würde ein Index von 51539673088 bspw. rauskommen. das ist falsch...

aber kannst du bitte was anderes machen? Von der C-Structur ein Offset zu jeden punkt in der Liste?

Also:
+0 InterfaceLuid.q ; Ein Quad
+8 InterfaceIndex.l
+12 InterfaceGuid.b[4+2+2+8]

etc?

Dann könnte ich rausbekommen wo der fehler liegt.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von DarkDragon »

GPI hat geschrieben:index-als quad kann nicht sein. dann würde ein Index von 51539673088 bspw. rauskommen. das ist falsch...

aber kannst du bitte was anderes machen? Von der C-Structur ein Offset zu jeden punkt in der Liste?

Also:
+0 InterfaceLuid.q ; Ein Quad
+8 InterfaceIndex.l
+12 InterfaceGuid.b[4+2+2+8]

etc?

Dann könnte ich rausbekommen wo der fehler liegt.

Code: Alles auswählen

0
8
12
542
1056
1056
1092
1124
1124
1128
1132
1136
1140
1144
1148
1152
1156
1160
1164
1168
1184
1192
1200
1208
1216
1224
1232
1240
1248
1256
1264
1272
1280
1288
1296
1304
1312
1320
1328
1336
1344
Generiert mit diesem Code in der main:

Code: Alles auswählen

printf("%d\n", offsetof(MIB_IF_ROW2, InterfaceLuid));
printf("%d\n", offsetof(MIB_IF_ROW2, InterfaceIndex)); 

    //
    // Read-Only fields.
    //
printf("%d\n", offsetof(MIB_IF_ROW2, InterfaceGuid));
printf("%d\n", offsetof(MIB_IF_ROW2, Alias[IF_MAX_STRING_SIZE + 1])); 
printf("%d\n", offsetof(MIB_IF_ROW2, Description[IF_MAX_STRING_SIZE + 1]));
printf("%d\n", offsetof(MIB_IF_ROW2, PhysicalAddressLength));
printf("%d\n", offsetof(MIB_IF_ROW2, PhysicalAddress[IF_MAX_PHYS_ADDRESS_LENGTH]));
printf("%d\n", offsetof(MIB_IF_ROW2, PermanentPhysicalAddress[IF_MAX_PHYS_ADDRESS_LENGTH]));    

printf("%d\n", offsetof(MIB_IF_ROW2, Mtu));
printf("%d\n", offsetof(MIB_IF_ROW2, Type));                // Interface Type.
printf("%d\n", offsetof(MIB_IF_ROW2, TunnelType));     // Tunnel Type, if Type = IF_TUNNEL.
printf("%d\n", offsetof(MIB_IF_ROW2, MediaType)); 
printf("%d\n", offsetof(MIB_IF_ROW2, PhysicalMediumType)); 
printf("%d\n", offsetof(MIB_IF_ROW2, AccessType));
printf("%d\n", offsetof(MIB_IF_ROW2, DirectionType));
printf("%d\n", offsetof(MIB_IF_ROW2, InterfaceAndOperStatusFlags));
    
printf("%d\n", offsetof(MIB_IF_ROW2, OperStatus));  
printf("%d\n", offsetof(MIB_IF_ROW2, AdminStatus));
printf("%d\n", offsetof(MIB_IF_ROW2, MediaConnectState));
printf("%d\n", offsetof(MIB_IF_ROW2, NetworkGuid));
printf("%d\n", offsetof(MIB_IF_ROW2, ConnectionType)); 

    //
    // Statistics.
    //
printf("%d\n", offsetof(MIB_IF_ROW2, TransmitLinkSpeed));
printf("%d\n", offsetof(MIB_IF_ROW2, ReceiveLinkSpeed));

printf("%d\n", offsetof(MIB_IF_ROW2, InOctets));
printf("%d\n", offsetof(MIB_IF_ROW2, InUcastPkts));
printf("%d\n", offsetof(MIB_IF_ROW2, InNUcastPkts));
printf("%d\n", offsetof(MIB_IF_ROW2, InDiscards));
printf("%d\n", offsetof(MIB_IF_ROW2, InErrors));
printf("%d\n", offsetof(MIB_IF_ROW2, InUnknownProtos));
printf("%d\n", offsetof(MIB_IF_ROW2, InUcastOctets));      
printf("%d\n", offsetof(MIB_IF_ROW2, InMulticastOctets));  
printf("%d\n", offsetof(MIB_IF_ROW2, InBroadcastOctets)); 
printf("%d\n", offsetof(MIB_IF_ROW2, OutOctets));
printf("%d\n", offsetof(MIB_IF_ROW2, OutUcastPkts));
printf("%d\n", offsetof(MIB_IF_ROW2, OutNUcastPkts));
printf("%d\n", offsetof(MIB_IF_ROW2, OutDiscards));
printf("%d\n", offsetof(MIB_IF_ROW2, OutErrors));
printf("%d\n", offsetof(MIB_IF_ROW2, OutUcastOctets));     
printf("%d\n", offsetof(MIB_IF_ROW2, OutMulticastOctets)); 
printf("%d\n", offsetof(MIB_IF_ROW2, OutBroadcastOctets));   
printf("%d\n", offsetof(MIB_IF_ROW2, OutQLen));
Komischerweise kommt bei offsetof etwas widersprüchliches raus. Jedoch, wenn ich sizeof mit dem ersten Strukturelement mache komme ich auf 8, mit dem zweiten auf 16. Ich kanns noch so oft wiederholen :? .
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von GPI »

Danke, kleinen Fehler hast du in Programm.

Code: Alles auswählen

PhysicalAddress[IF_MAX_PHYS_ADDRESS_LENGTH]));
damit bestimmst du die position eins nach den ende des feldes. Korrekt wäre hier:

Code: Alles auswählen

PhysicalAddress[0]));
Aber ich hab den Fehler in der Struktur gefunden - und ohne dich vermutlich nie.

ConnectionType ist ein Quad! - darauf muss man auch erstmal kommen...

Und anscheinend startet die Daten tatsächlich bei +8 (die Anzahl der Interfaces wird wohl auch in Quad übergeben - keine ahnung warum da die über 1 Mio nicht ausreicht, das mit 32-bit möglich wäre :) )
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von freak »

GPI hat geschrieben:ConnectionType ist ein Quad! - darauf muss man auch erstmal kommen...

Und anscheinend startet die Daten tatsächlich bei +8 (die Anzahl der Interfaces wird wohl auch in Quad übergeben - keine ahnung warum da die über 1 Mio nicht ausreicht, das mit 32-bit möglich wäre :) )
Das sind keine Quad, sondern Long mit 4 byte padding (4 ungenutzte Byte) dahinter. Die existieren damit die danach kommenden größeren Werte (wie zum Beispiel ULONG64) korrektes Alignment haben.

Daraus muss man ein Long machen und dann einen Dummy-Feld einfügen. Wenn du ein Quad draus machst ließt du eventuell ungenützte Bytes mit in den Wert ein (und die müssen ja nicht immer 0 sein).
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von GPI »

Woran erkennt man sowas? Sieht für mich mehr oder minder so aus, als werden die willkürlich eingefügt. Oder werden Quads in C immer an durch 4 Teilbare adressen erzeugt?
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Antworten