X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/693e2ce95d2225be709499570ea94c324d663562..ba45339b0cda696438a3b1553c829445fd894641:/binipstuff.pas?ds=sidebyside diff --git a/binipstuff.pas b/binipstuff.pas index 0b9fcb8..1d7a7c2 100644 --- a/binipstuff.pas +++ b/binipstuff.pas @@ -13,7 +13,7 @@ interface {$include lcoreconfig.inc} uses -{$ifndef win32} +{$ifndef mswindows} sockets, {$endif} pgtypes; @@ -25,7 +25,7 @@ uses const hexchars:array[0..15] of ansichar='0123456789abcdef'; - {$ifdef win32} + {$ifdef mswindows} AF_INET=2; AF_INET6=23; {$else} @@ -39,7 +39,7 @@ const type {$ifdef ipv6} - {$ifdef win32} + {$ifdef mswindows} {$define want_Tin6_addr} {$endif} {$ifdef ver1_0} @@ -70,55 +70,52 @@ type {$endif} end; - {$ifdef win32} - TInetSockAddr = packed Record - family:Word; - port :Word; - addr :uint32; - pad :array [1..8] of byte; - end; - {$ifdef ipv6} + {zipplet 20170204: FPC 3.0.0 changed the definition of TInetSockAddr: + - http://www.freepascal.org/docs-html/rtl/sockets/tinetsockaddr.html + - http://www.freepascal.org/docs-html/rtl/sockets/sockaddr_in.html + Due to this, TInetSockAddr -> TLInetSockAddr4 / TLInetSockAddr6 + Using our own types no matter what OS or compiler version will prevent future problems. + Adding "4" to non IPv6 record names improves code clarity } - TInetSockAddr6 = packed record - sin6_family: word; - sin6_port: word; - sin6_flowinfo: uint32; - sin6_addr: tin6_addr; - sin6_scope_id: uint32; - end; + {$ifndef mswindows} + //zipplet 20170204: Do we still need to support ver1_0? Perhaps a cleanup is in order. + //For now keep supporting it for compatibility. + {$ifdef ver1_0} + cuint16 = word; + cuint32 = dword; + sa_family_t = word; {$endif} {$endif} - - + TLInetSockAddr4 = packed Record + family:Word; + port :Word; + addr :uint32; + pad :array [0..7] of byte; //zipplet 20170204 - originally this was 1..8 for some reason + end; + {$ifdef ipv6} - {$ifdef ver1_0} - cuint16=word; - cuint32=dword; - sa_family_t=word; - - TInetSockAddr6 = packed record - sin6_family: word; - sin6_port: word; - sin6_flowinfo: uint32; - sin6_addr: tin6_addr; - sin6_scope_id: uint32; - end; - {$endif} + TLInetSockAddr6 = packed record + sin6_family: word; + sin6_port: word; + sin6_flowinfo: uint32; + sin6_addr: tin6_addr; + sin6_scope_id: uint32; + end; {$endif} + + //zipplet 20170204: I did not rename the unioned record. We might want to rename this to TLinetSockAddrv TinetSockAddrv = packed record case integer of - 0: (InAddr:TInetSockAddr); + 0: (InAddr:TLInetSockAddr4); {$ifdef ipv6} - 1: (InAddr6:TInetSockAddr6); + 1: (InAddr6:TLInetSockAddr6); {$endif} end; Pinetsockaddrv = ^Tinetsockaddrv; type - tsockaddrin=TInetSockAddr; - - + tsockaddrin=TLInetSockAddr4; { bin IP list code, by beware @@ -166,6 +163,10 @@ function inaddrvtobinip(inaddrv:tinetsockaddrv):tbinip; function makeinaddrv(addr:tbinip;port:ansistring;var inaddr:tinetsockaddrv):integer; function inaddrsize(inaddr:tinetsockaddrv):integer; +function getbinipbitlength(const ip:tbinip):integer; +function getipstrbitlength(const ip:thostname):integer; +function getfamilybitlength(family:integer):integer; + implementation uses sysutils; @@ -208,14 +209,14 @@ begin inAddr.InAddr.family:=AF_INET; inAddr.InAddr.port:=htons(strtointdef(port,0)); inAddr.InAddr.addr:=addr.ip; - result := sizeof(tinetsockaddr); + result := sizeof(tlinetsockaddr4); 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); + result := sizeof(tlinetsockaddr6); end; {$endif} end; @@ -223,9 +224,9 @@ end; function inaddrsize(inaddr:tinetsockaddrv):integer; begin {$ifdef ipv6} - if inaddr.inaddr.family = AF_INET6 then result := sizeof(tinetsockaddr6) else + if inaddr.inaddr.family = AF_INET6 then result := sizeof(tlinetsockaddr6) else {$endif} - result := sizeof(tinetsockaddr); + result := sizeof(tlinetsockaddr4); end; {internal} @@ -299,7 +300,10 @@ begin {$endif} {try v4} - binip.ip := htonl(longip(s)); + // zipplet: htonl() expects a uint32 but longip() spits out longint. + // Because longip() is deprecated, we do not fix it but typecast. + //binip.ip := htonl(longip(s)); + binip.ip := htonl(uint32(longip(s))); if (binip.ip <> 0) or (s = '0.0.0.0') then begin result := true; binip.family := AF_INET; @@ -334,7 +338,7 @@ written by beware - implementation does not depend on other ipv6 code such as the tin6_addr type, the parameter can also be untyped. -- it is host endian neutral - binary format is aways network order +- it is host endian neutral - binary format is always network order - it supports compression of zeroes - it supports ::ffff:192.168.12.34 style addresses - they are made to do the Right Thing, more efficient implementations are possible @@ -386,7 +390,7 @@ begin end; end; - {run length atleast 2 0 words} + {run length at least 2 0 words} if (runlength = 1) then begin runlength := 0; runbegin := 0; @@ -555,8 +559,8 @@ begin {$ifdef ipv6} if ip.family = AF_INET then begin ip.family := AF_INET6; - ip.ip6.s6_addr32[3] := ip.ip; - ip.ip6.u6_addr32[0] := 0; + ip.ip6.s6_addr32[3] := ip.ip; + ip.ip6.u6_addr32[0] := 0; ip.ip6.u6_addr32[1] := 0; ip.ip6.u6_addr16[4] := 0; ip.ip6.u6_addr16[5] := $ffff; @@ -660,5 +664,26 @@ begin end; end; +function getfamilybitlength(family:integer):integer; +begin + {$ifdef ipv6} + if family = AF_INET6 then result := 128 else + {$endif} + if family = AF_INET then result := 32 + else result := 0; +end; + +function getbinipbitlength(const ip:tbinip):integer; +begin + result := getfamilybitlength(ip.family); +end; + +function getipstrbitlength(const ip:thostname):integer; +var + biniptemp:tbinip; +begin + ipstrtobin(ip,biniptemp); + result := getbinipbitlength(biniptemp); +end; end.