X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/4782a5c5afee47721cc617daa40dd29828342c2b..baf753e54d73673524de916757e66ef8c485bc0d:/binipstuff.pas?ds=sidebyside diff --git a/binipstuff.pas b/binipstuff.pas index ebb9f9c..59d123b 100755 --- a/binipstuff.pas +++ b/binipstuff.pas @@ -6,6 +6,8 @@ unit binipstuff; interface +{$include lcoreconfig.inc} + {$ifndef win32} {$ifdef ipv6} uses sockets; @@ -82,10 +84,53 @@ type {$endif} {$endif} + + + {$ifdef ipv6} + {$ifdef ver1_0} + cuint16=word; + cuint32=dword; + sa_family_t=word; + + {$endif} + {$endif} + TinetSockAddrv = packed record + case integer of + 0: (InAddr:TInetSockAddr); + {$ifdef ipv6} + 1: (InAddr6:TInetSockAddr6); + {$endif} + end; + Pinetsockaddrv = ^Tinetsockaddrv; + + type + tsockaddrin=TInetSockAddr; + + + +{ +bin IP list code, by beware +while this is really just a string, on the interface side it must be treated +as an opaque var which is passed as "var" when it needs to be modified} + + tbiniplist=string; + +function biniplist_new:tbiniplist; +procedure biniplist_add(var l:tbiniplist;ip:tbinip); +function biniplist_getcount(const l:tbiniplist):integer; +function biniplist_get(const l:tbiniplist;index:integer):tbinip; +procedure biniplist_set(var l:tbiniplist;index:integer;ip:tbinip); +procedure biniplist_setcount(var l:tbiniplist;newlen:integer); +procedure biniplist_free(var l:tbiniplist); +procedure biniplist_addlist(var l:tbiniplist;const l2:tbiniplist); +function biniplist_tostr(const l:tbiniplist):string; +function isbiniplist(const l:tbiniplist):boolean; + function htons(w:word):word; function htonl(i:uint32):uint32; function ipstrtobin(const s:string;var binip:tbinip):boolean; +function ipstrtobinf(const s:string):tbinip; function ipbintostr(const binip:tbinip):string; {$ifdef ipv6} function ip6bintostr(const bin:tin6_addr):string; @@ -93,12 +138,18 @@ function ip6strtobin(const s:string;var bin:tin6_addr):boolean; {$endif} function comparebinip(const ip1,ip2:tbinip):boolean; +procedure maskbits(var binip:tbinip;bits:integer); +function comparebinipmask(ip1,ip2:tbinip;bits:integer):boolean; {deprecated} function longip(s:string):longint; procedure converttov4(var ip:tbinip); +function inaddrvtobinip(inaddrv:tinetsockaddrv):tbinip; +function makeinaddrv(addr:tbinip;port:string;var inaddr:tinetsockaddrv):integer; +function inaddrsize(inaddr:tinetsockaddrv):integer; + implementation uses sysutils; @@ -121,6 +172,46 @@ begin {$endif} end; + +function inaddrvtobinip(inaddrv:tinetsockaddrv):tbinip; +begin + result.family := inaddrv.inaddr.family; + if result.family = AF_INET then result.ip := inaddrv.inaddr.addr; + {$ifdef ipv6} + if result.family = AF_INET6 then result.ip6 := inaddrv.inaddr6.sin6_addr; + {$endif} +end; + +function makeinaddrv(addr:tbinip;port:string;var inaddr:tinetsockaddrv):integer; +begin + result := 0; +{ biniptemp := forwardlookup(addr,10);} + fillchar(inaddr,sizeof(inaddr),0); + //writeln('converted address '+addr+' to binip '+ipbintostr(biniptemp)); + if addr.family = AF_INET then begin + inAddr.InAddr.family:=AF_INET; + inAddr.InAddr.port:=htons(strtointdef(port,0)); + inAddr.InAddr.addr:=addr.ip; + result := sizeof(tinetsockaddr); + end else + {$ifdef ipv6} + if addr.family = AF_INET6 then begin + inAddr.InAddr6.sin6_family:=AF_INET6; + inAddr.InAddr6.sin6_port:=htons(strtointdef(port,0)); + inAddr.InAddr6.sin6_addr:=addr.ip6; + result := sizeof(tinetsockaddr6); + end; + {$endif} +end; + +function inaddrsize(inaddr:tinetsockaddrv):integer; +begin + {$ifdef ipv6} + if inaddr.inaddr.family = AF_INET6 then result := sizeof(tinetsockaddr6) else + {$endif} + result := sizeof(tinetsockaddr); +end; + {internal} {converts dotted v4 IP to longint. returns host endian order} function longip(s:string):longint; @@ -173,6 +264,11 @@ begin end; +function ipstrtobinf; +begin + ipstrtobin(s,result); +end; + function ipstrtobin(const s:string;var binip:tbinip):boolean; begin binip.family := 0; @@ -378,6 +474,31 @@ begin result := (ip1.family = ip2.family); end; +procedure maskbits(var binip:tbinip;bits:integer); +const + ipmax={$ifdef ipv6}15{$else}3{$endif}; +type tarr=array[0..ipmax] of byte; +var + arr:^tarr; + a,b:integer; +begin + arr := @binip.ip; + if bits = 0 then b := 0 else b := ((bits-1) div 8)+1; + for a := b to ipmax do begin + arr[a] := 0; + end; + if (bits and 7 <> 0) then begin + arr[bits shr 3] := arr[bits div 8] and not ($ff shr (bits and 7)) + end; +end; + +function comparebinipmask; +begin + maskbits(ip1,bits); + maskbits(ip2,bits); + result := comparebinip(ip1,ip2); +end; + {converts a binary IP to v4 if it is a v6 IP in the v4 range} procedure converttov4(var ip:tbinip); begin @@ -392,4 +513,84 @@ begin {$endif} end; +{-----------biniplist stuff--------------------------------------------------} + +const + biniplist_prefix='bipl'#0; + biniplist_prefixlen=length(biniplist_prefix); + +function biniplist_new:tbiniplist; +begin + result := biniplist_prefix; +end; + +procedure biniplist_add(var l:tbiniplist;ip:tbinip); +var + a:integer; +begin + a := biniplist_getcount(l); + biniplist_setcount(l,a+1); + biniplist_set(l,a,ip); +end; + +function biniplist_getcount(const l:tbiniplist):integer; +begin + result := (length(l)-biniplist_prefixlen) div sizeof(tbinip); +end; + +function biniplist_get(const l:tbiniplist;index:integer):tbinip; +begin + if (index >= biniplist_getcount(l)) then begin + fillchar(result,sizeof(result),0); + exit; + end; + move(l[index*sizeof(tbinip)+1+biniplist_prefixlen],result,sizeof(result)); +end; + +procedure biniplist_set(var l:tbiniplist;index:integer;ip:tbinip); +begin + uniquestring(l); + move(ip,l[index*sizeof(tbinip)+1+biniplist_prefixlen],sizeof(ip)); +end; + +procedure biniplist_setcount(var l:tbiniplist;newlen:integer); +begin + setlength(l,(sizeof(tbinip)*newlen)+biniplist_prefixlen); +end; + +procedure biniplist_free(var l:tbiniplist); +begin + l := ''; +end; + +procedure biniplist_addlist; +begin + l := l + l2; +end; + +function biniplist_tostr(const l:tbiniplist):string; +var + a:integer; +begin + result := '('; + for a := 0 to biniplist_getcount(l)-1 do begin + if result <> '(' then result := result + ', '; + result := result + ipbintostr(biniplist_get(l,a)); + end; + result := result + ')'; +end; + +function isbiniplist(const l:tbiniplist):boolean; +var + i : integer; +begin + for i := 1 to biniplist_prefixlen do begin + if biniplist_prefix[i] <> l[i] then begin + result := false; + exit; + end; + end; + result := true; +end; + end.