Some time ago someone asked for a library able to do network calculations.

Here is something that might evolve into such library :

Uses
        Classes,
        SysUtils,
        StrUtils;

Type
        TNetworkIP = Record Case Mode : Boolean Of
                True : (IP1, IP2, IP3, IP4 : Byte);
                False : (IP : LongWord);
        End;

Function StringToIP(aIP : AnsiString): TNetworkIP;
Begin
        Result.Mode := True;
        Result.IP4 := StrToInt(Copy2SymbDel(aIP, '.'));
        Result.IP3 := StrToInt(Copy2SymbDel(aIP, '.'));
        Result.IP2 := StrToInt(Copy2SymbDel(aIP, '.'));
        Result.IP1 := StrToInt(Copy2SymbDel(aIP, '.'));
End;

Function IPToString(aIP : TNetworkIP): String;
Begin
        aIP.Mode := True;
        Result := IntToStr(aIP.IP4) + '.' + IntToStr(aIP.IP3) + '.' +
IntToStr(aIP.IP2) + '.' + IntToStr(aIP.IP1);
End;

Function IPToBits(aIP : TNetworkIP): String;
Begin
        aIP.Mode := True;
        Result := BinStr(aIP.IP4, 8) + BinStr(aIP.IP3, 8) + BinStr(aIP.IP2,
8) + BinStr(aIP.IP1, 8);
End;

Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP;
Begin
        Result.Mode := False;
        NetMask.Mode := False;
        Result.IP := NetMask.IP Xor %11111111111111111111111111111111;
End;

Function HostMaskToNetMask(HostMask : TNetworkIP): TNetworkIP;
Begin
        Result.Mode := False;
        HostMask.Mode := False;
        Result.IP := HostMask.IP Xor %11111111111111111111111111111111;
End;

Function CIDRToNetMask(Bits : Byte): TNetworkIP;
Var
        CurBit : Byte;
        HostMask : TNetworkIP;
Begin
        HostMask.Mode := False;
        HostMask.IP := 0;
        For CurBit := 1 To 32 - Bits Do
                HostMask.IP := HostMask.IP + (1 Shl (CurBit - 1));
        Result := HostMaskToNetMask(HostMask);
End;

Function NetMaskToCIDR(NetMask : TNetworkIP): Byte;
Var
        CurBit : Byte;
Begin
        Result := 0;
        For CurBit := 32 DownTo 1 Do
                If (NetMask.IP And (1 Shl (CurBit - 1))) = (1 Shl (CurBit - 1)) 
Then
                        Result := CurBit;
End;

Function BroadcastOf(IP, NetMask : TNetworkIP): TNetworkIP;
Var
        HostMask : TNetworkIP;
Begin
        HostMask := NetMaskToHostMask(NetMask);
        Result.Mode := False;
        IP.Mode := False;
        HostMask.Mode := False;
        Result.IP := IP.IP Or HostMask.IP;
End;

Function NetworkOf(IP, NetMask : TNetworkIP): TNetworkIP;
Begin
        IP.Mode := False;
        NetMask.Mode := False;
        Result.Mode := False;
        Result.IP := IP.IP And NetMask.IP;
End;

Function HostCount(NetMask : TNetworkIP): LongWord;
Var
        HostMask : TNetworkIP;
Begin
        HostMask := NetMaskToHostMask(NetMask);
        HostMask.Mode := False;
        Result := HostMask.IP + 1;
End;

Function SubNetCount(DefMask, Mask : TNetworkIP): LongWord;
Var
        DefHosts,
        Hosts : LongWord;
Begin
        DefHosts := HostCount(DefMask);
        Hosts := HostCount(Mask);
        Result := DefHosts Div Hosts;
End;

Function IPToRange(IP, NetMask : TNetworkIP): String;
Var
        Net,
        Broad : TNetworkIP;
Begin
        Net := NetworkOf(IP, NetMask);
        Broad := BroadCastOf(IP, NetMask);
        Net.Mode := False;
        Broad.Mode := False;
        Net.IP := Net.IP + 1;
        Broad.IP := Broad.IP - 1;
        Result := IPToString(Net) + '-' + IPToString(Broad);
End;

Function IncSubNet(BaseIP, Mask : TNetworkIP): TNetworkIP;
Var
        HostMask : TNetworkIP;
Begin
        HostMask := NetMaskToHostMask(Mask);
        HostMask.Mode := False;
        HostMask.IP := HostMask.IP + 1;
        BaseIP.Mode := False;
        Result.Mode := False;
        Result.IP := BaseIP.IP + HostMask.IP;
End;

Function HostCountToCIDR(Hosts : LongWord): Byte;
Var
        CurBit : Byte;
        HostMask : TNetworkIP;
        Last1Bit : Byte;
Begin
        HostMask.Mode := False;
        HostMask.IP := Hosts;
        Last1Bit := 0;
        For CurBit := 1 To 32 Do
                If (HostMask.IP And (1 Shl (CurBit - 1))) = (1 Shl (CurBit - 
1)) Then
                        Last1Bit := CurBit;
        Result := 32 - Last1Bit;
End;

Function HostCountToNetMask(Hosts : LongWord): TNetworkIP;
Begin
        Result := CIDRToNetMask(HostCountToCIDR(Hosts));
End;

Function IsMemberOfSubNet(IP, SubNet : TNetworkIP): Boolean;
Begin
        IP.Mode := False;
        Subnet.Mode := False;
        Result := IP.IP And Subnet.IP = Subnet.IP;
End;

Begin
        WriteLn(IsMemberOfSubNet(StringToIP(ParamStr(1)), 
StringToIP(Paramstr(2))));
End.

Thats old code, i dont remmember what i was thinking when i wrote that.

It surely could be improved (reformated as a unit, for example).

Could this be added to the FCL ?
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to