Zit een IP adres in een bepaalde range?

Pagina: 1
Acties:

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 25-01 20:45

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Eerst wat context: ik heb enkele honderden servers verspreid over een grote geografische zone en in een paar duizenden subnetten. Ik schrijf een script dat vanalles doet, maar één onderdeel ervan is op netwerkniveau en niet mijn specialiteit: kijken in welk subnet een gegeven IP adres zit.

Ik heb bijvoorbeeld 10.141.0.0/20. Ik zou dit kunnen uitrekenen, ttz. expanden naar een array met alle IP adressen die daarin zitten (10.141.0.1 tem. 10.141.15.254) en kijken of mijn IP adres daarin zit. Alleen: dat is een ontzettend inefficiënte manier, aangezien ik voor elke CIDR x-aantal elementen creëer en mijn loops ontzettend groot maak. Wat je namelijk zou krijgen is iets als volgt in dummycode:

C#:
1
2
3
4
5
6
7
8
9
10
11
ForEach ($Site in Sites)
    {
    ForEach ($Subnet in $Site.Subnets)
        {
        #een hoop code om te expanden die we in een array $arrIPAddress steken
        ForEach ($objIPAddress in $arrIPAddress)
            {
            $IPAddress -EQ $HetIngevoerdeIPAdres
            }       
        }
    }



Drie loops achter elkaar is verschrikkelijk inefficiënt. En die hele loop moet gebeuren voor honderden IP adressen! Waarschijnlijk is er een andere methode om dit te berekenen op binair niveau, maar op dit uur slaag ik er niet meer in om zelf het algoritme te vinden waarmee ik eenvoudig uitvis of, laat ons zeggen, 10.141.15.4 een onderdeel van 10.141.0.0/20 is of niet.

Dank alvast voor jullie input.

(Edit: in werkelijkheid moet ik ongeveer 300 IP adressen opzoeken in iets van een 4000 verschillende subnetten).

[ Voor 10% gewijzigd door YellowOnline op 08-03-2012 14:59 ]


  • Paul
  • Registratie: September 2000
  • Laatst online: 13:58
Je weet al dat het een /20 is :)

Binair heb je dus 11111111.11111111.11110000.0000. Als je dat AND met je beide IP-adressen dan weet je of ze beiden in dezelfde range zitten :)

Nu ja, strict genomen hoef je dat niet om te zetten naar de bit-representatie (dat is immers slechts een representatie) maar nu in de concept-fase is het wel lekker visueel :P

[ Voor 33% gewijzigd door Paul op 08-03-2012 14:59 ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Het lijkt me dat het feit dat netmaskers bitmaskers zijn je op weg zou moeten helpen met het oplossen van dit probleem :)

En logaritmes gaan je niet helpen, algoritmes misschien wel ;)

[ Voor 25% gewijzigd door Herko_ter_Horst op 08-03-2012 14:58 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 25-01 20:45

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Herko_ter_Horst schreef op donderdag 08 maart 2012 @ 14:57:
En logaritmes gaan je niet helpen, algoritmes misschien wel ;)
M'n hoofd zit vol :O

  • ocwil
  • Registratie: Mei 2007
  • Laatst online: 20-02 10:35
Als ik het goed begrijp wil je voor een ingevoerde ip weten welk subnet hij inzit
dan is het een kwestie van bitmasken met de subnetten tot je de goeie hebt

~ Portal 2 maps: linkje ~ LoL (EUW): Ocwil ~


  • devino
  • Registratie: December 2005
  • Laatst online: 13:25

devino

Hoogspanning of Hoge spanning?

In plaats van aan de 'achterkant' van het ip kijken, kan je misschien ook 'aan de voorkant' kijken.
Dus in je script kijken of het 10.141.x.x is in plaats van de laatste 2 bytes (dus x.x.15.4) te controleren.

ook voor mij is het einde van de dag en ik heb ergens een vaag gevoel dat ik het probleem niet helemaal helder heb

De hierboven gemaakte typ- en/of spelfouten zijn mijn handelsmerk


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

devino schreef op donderdag 08 maart 2012 @ 17:03:
In plaats van aan de 'achterkant' van het ip kijken, kan je misschien ook 'aan de voorkant' kijken.
Dus in je script kijken of het 10.141.x.x is in plaats van de laatste 2 bytes (dus x.x.15.4) te controleren.

ook voor mij is het einde van de dag en ik heb ergens een vaag gevoel dat ik het probleem niet helemaal helder heb
Dat helpt voor geen meter, tenzij je alleen /16's zit te onderzoeken.


Het reeds gegevene, het IP AND'en met het subnetmask en dat dan vergelijken met het netwerkadres (en dat voor de zekerheid ook even AND'en met de mask) is correct.

All my posts are provided as-is. They come with NO WARRANTY at all.


  • DrFlash
  • Registratie: Juli 2009
  • Laatst online: 14-12-2025
er is maar 1 mogelijkheid om dit goed te doen en dat is:

Subnet terugrekenen naar binair, en splitsen op het subnetmasker
IP terugrekenen naar binair en splitsen op het subnetmasker

komt het voorste deel overeen, dan is het goed.

zonder terug te rekenen naar binair is het niet mogelijk dit goed te controleren. denk aan een /22 subnet masker (255.255.252.0) of een /30 (255.255.255.248)
devino schreef op donderdag 08 maart 2012 @ 17:03:
In plaats van aan de 'achterkant' van het ip kijken, kan je misschien ook 'aan de voorkant' kijken.
Dus in je script kijken of het 10.141.x.x is in plaats van de laatste 2 bytes (dus x.x.15.4) te controleren.
Je zal em dus eerst moeten terugrekenen naar binair om meer subnets te ondersteunen dan /8 /16 en /24

[ Voor 35% gewijzigd door DrFlash op 08-03-2012 17:17 ]

Wowhead profiel


  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 25-01 20:45

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Even gewoon zeggen dat ik met jullie suggesties aan het spelen ben (voorbeeld met een 10.141.0.0/20):

code:
1
2
3
4
5
PS C:\Users\YellowOnline\Desktop> .\Get-IPSites.ps1 10.141.5.4
Subnet : 00001010.10001101.00000000.00000000
Address: 00001010.10001101.00000101.00000100
bAnd   : 00001010.10001101.00000000.00000000
Mask   : 11111111.11111111.11110000.00000000

[ Voor 4% gewijzigd door YellowOnline op 08-03-2012 17:31 ]


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Je hoeft helemaal niet te rekenen naar binair, dat doet die computer wel voor je. Je moet 't IP-adres hebben als 32-bit int (inet_addr()). Daarmee kun je direct werken.

Bijvoorbeeld:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char **argv){
    in_addr_t ip, subnet, mask;

    ip = inet_addr(argv[1]);
    mask = inet_addr("255.255.255.0");
    subnet = inet_addr("192.168.1.0");

    if ((ip & mask) == (subnet & mask)) printf("OK!\n"); else printf("No match\n");

}


[cyber@helene tmp]$ ./test 192.168.1.2
OK!
[cyber@helene tmp]$ ./test 192.168.2.2
No match

[ Voor 65% gewijzigd door CyBeR op 08-03-2012 17:44 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


  • Paul
  • Registratie: September 2000
  • Laatst online: 13:58
YellowOnline schreef op donderdag 08 maart 2012 @ 17:30:
Even gewoon zeggen dat ik met jullie suggesties aan het spelen ben (voorbeeld met een 10.141.0.0/20):

code:
1
2
3
4
5
PS C:\Users\YellowOnline\Desktop> .\Get-IPSites.ps1 10.141.5.4
Subnet : 00001010.10001101.00000000.00000000
Address: 00001010.10001101.00000101.00000100
bAnd   : 00001010.10001101.00000000.00000000
Mask   : 11111111.11111111.11110000.00000000
Je bent (visueel, CyBeR heeft de korte versie :P ) een heel eind op weg, maar je moet de twee adressen niet ANDen met elkaar maar met het masker :)

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock

Pagina: 1