IPv4 CIDR notation management

Share your advanced PureBasic knowledge/code with the community.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

IPv4 CIDR notation management

Post by Psychophanta »

Code: Select all

Procedure$ IPv4_RangeToCIDRnotation(IP$)
  ;Convierte un rango válido de direcciones IPv4 a la notación CIDR
  ;El formato de entrada debe ser: 'IP''caracter''IP2'
  Protected ipmask$,iprange.q,IP2$,t.l=1,len.l=Len(IP$),IP.l,IP2.l
  c.a=Asc(Mid(IP$,t,1))
  While c='.' Or (c>='0' And c<='9')
    t+1:c.a=Asc(Mid(IP$,t,1))
  Wend
  IP2$=StringField(IP$,2,Mid(IP$,t,1))
  IP$=StringField(IP$,1,Mid(IP$,t,1))
  If Val(StringField(IP$,4,"."))=1:IP$=RTrim(IP$,"1")+"0":EndIf
  If Val(StringField(IP2$,4,"."))=254:IP2$=RTrim(IP2$,"4")+"5":EndIf
  IP=MakeIPAddress(Val(StringField(IP$,4,".")),Val(StringField(IP$,3,".")),Val(StringField(IP$,2,".")),Val(StringField(IP$,1,".")))
  IP2=MakeIPAddress(Val(StringField(IP2$,4,".")),Val(StringField(IP2$,3,".")),Val(StringField(IP2$,2,".")),Val(StringField(IP2$,1,".")))
  iprange=((IP2-IP)!$FFFFFFFF)&$FFFFFFFF
  ipmask$=Bin(iprange,#PB_Long)
  If ipmask$="0" Or Trim(Trim(ipmask$,"0"),"1"):ProcedureReturn "Not a valid IP range":EndIf
  !mov eax,dword[p.v_IP]
  !bswap eax
  !mov dword[p.v_IP],eax
  ProcedureReturn IPString(IP)+"/"+Str(CountString(ipmask$,"1"))
EndProcedure
Procedure$ IPv4_MaskToCIDRnotation(IP$)
  ;Convierte un rango válido de direcciones IPv4 a la notación CIDR
  ;El formato de entrada debe ser: 'IP''caracter''máscaraIP'
  Protected ipmask$,iprange.q,IP2$,t.l=1,len.l=Len(IP$)
  c.a=Asc(Mid(IP$,t,1))
  While c='.' Or (c>='0' And c<='9')
    t+1:c.a=Asc(Mid(IP$,t,1))
  Wend
  IP2$=StringField(IP$,2,Mid(IP$,t,1))
  IP$=StringField(IP$,1,Mid(IP$,t,1))
  iprange=MakeIPAddress(Val(StringField(IP2$,4,".")),Val(StringField(IP2$,3,".")),Val(StringField(IP2$,2,".")),Val(StringField(IP2$,1,".")))&$FFFFFFFF
  ipmask$=Bin(iprange,#PB_Long)
  If ipmask$="0" Or Trim(Trim(ipmask$,"0"),"1"):ProcedureReturn "Not a valid IP mask":EndIf
  ProcedureReturn IPString(MakeIPAddress(Val(StringField(IP$,1,".")),Val(StringField(IP$,2,".")),Val(StringField(IP$,3,".")),Val(StringField(IP$,4,"."))))+"/"+Str(CountString(ipmask$,"1"))
EndProcedure
Procedure$ IPv4_CIDRnotationToMask(IP$,ToRange.b=0)
  ;Convierte notación CIDR a un rango válido de direcciones IPv4
  ;El formato de entrada debe ser: 'IP''/''valor'
  Protected valor$=StringField(IP$,2,"/"),valor.w=Val(valor$)
  IP$=StringField(IP$,1,"/")
  Protected ipmask$=LSet(RSet("",valor,"1"),32,"0"):ipmask.l=Val("%"+ipmask$)
  If ipmask$="0" Or Trim(Trim(ipmask$,"0"),"1"):ProcedureReturn "Not a valid CIDR notation":EndIf
  Protected IP.l=MakeIPAddress(Val(StringField(IP$,4,".")),Val(StringField(IP$,3,".")),Val(StringField(IP$,2,".")),Val(StringField(IP$,1,".")))
  Protected IP2.l=IP&ipmask+ipmask!$FFFFFFFF
  !mov eax,dword[p.v_IP]
  !bswap eax
  !mov dword[p.v_IP],eax
  !mov eax,dword[p.v_IP2]
  !bswap eax
  !mov dword[p.v_IP2],eax
  !mov eax,dword[p.v_ipmask]
  !bswap eax
  !mov dword[p.v_ipmask],eax
  If ToRange
    ProcedureReturn IPString(IP)+";("+IPString(IP&ipmask)+"-"+IPString(IP2)+")"
  EndIf
  ProcedureReturn IPString(IP)+";"+IPString(ipmask)
EndProcedure
Debug IPv4_RangeToCIDRnotation("192.168.0.1-192.168.0.254")
Debug IPv4_MaskToCIDRnotation("10.0.0.246/255.255.255.0")
Debug IPv4_CIDRnotationToMask("192.168.025.146/23",1)
If you find some bug or mistake, please notice it here.
Next i will do it the same for IPv6, if i have time enough.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: IPv4 CIDR notation management

Post by em_uk »

Very interesting, thanks!
----

R Tape loading error, 0:1
Post Reply