Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-07

Re: Library for network calculation

11 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jorge Aldo G. de F. Junior

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 ?

Paul Nicholls
to Jorge Aldo G. de F. Junior

"Jorge Aldo G. de F. Junior"
wrote in message

Some time ago someone asked for a library able to do network calculations. Here is something that might evolve into such library :

<SNIP>

Show quoted text 7 lines
Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; Begin Result.Mode := False; NetMask.Mode := False; Result.IP := NetMask.IP Xor %11111111111111111111111111111111; End;

<SNIP>

I didn't know that freepascal handled binary formatted numbers?!?

%11111111111111111111111111111111

cheers,
Paul

Lukasz Sokol
to Paul Nicholls
Paul Nicholls wrote 7 lines
I didn't know that freepascal handled binary formatted numbers?!? %11111111111111111111111111111111 cheers, Paul

[pun]
yeah don't tell anyone, we don't want them to play games with pointers ;) like the c-programmers do ;)
[/pun]
L.

Mark Morgan Lloyd
to Jorge Aldo G. de F. Junior: Some time ago someone asked for a library able to do network calculations. Here is…
Jorge Aldo G. de F. Junior wrote
Some time ago someone asked for a library able to do network calculations. Here is something that might evolve into such library :

[Snip]

A library for network calculations would have to include IPv6, and ideally would interwork with (the equivalent of) DHCP etc. so that it could obtain things like router addresses.

The sort of operation that I've found irritating in the past- particularly when it had to be correct for both little- and big-endian architectures- was shifting a mask left or right as part of an attempt to determine whether a host was actually a router onto another subnet.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Sven Barth
to Paul Nicholls: "Jorge Aldo G. de F. Junior" wrote in message <SNIP> <SNIP> I didn't know that freepascal…
Paul Nicholls wrote 20 lines
"Jorge Aldo G. de F. Junior" wrote in message > Some time ago someone asked for a library able to do network calculations. > > Here is something that might evolve into such library : > <SNIP> > Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; > Begin > Result.Mode := False; > NetMask.Mode := False; > Result.IP := NetMask.IP Xor %11111111111111111111111111111111; > End; > <SNIP> I didn't know that freepascal handled binary formatted numbers?!? %11111111111111111111111111111111

There are often new things one can learn about what FPC supports ;) (though binary numbers are already old for me ^^)

The most recent finding (at least for me) was the abbility to initialize local variables.

Regards,
Sven

Jorge Aldo G. de F. Junior
to Sven Barth

I dont like to take local variable initialization for granted.

Even if the manual says that its guaranteed that a local variable will start with 0,
i prefer to initialize everything to a known value myself.

An aditional

Move $varaddress, 00

at startup wont slow things down noticeably when your pc is running at 2ghz...

This unit needs to take care of big endian vs. low endian (maybe a $define ?)

When i wrote that code i did not pay attention to this...

Anything more complex (like interacting with DHCP server) would be too complex and probably dependent on external units (like synapse x lnet etc). Some people might prefer to use other library instead of the default choosen one, etc...

2011/7/26 Sven Barth :

Show quoted text 39 lines
On 26.07.2011 01:23, Paul Nicholls wrote: > > "Jorge Aldo G. de F. Junior" >  wrote in message > >> >> Some time ago someone asked for a library able to do network >> calculations. >> >> Here is something that might evolve into such library : >> > <SNIP> >> >> Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; >> Begin >> Result.Mode := False; >> NetMask.Mode := False; >> Result.IP := NetMask.IP Xor %11111111111111111111111111111111; >> End; >> > <SNIP> > > I didn't know that freepascal handled binary formatted numbers?!? > > %11111111111111111111111111111111 There are often new things one can learn about what FPC supports ;) (though binary numbers are already old for me ^^) The most recent finding (at least for me) was the abbility to initialize local variables. Regards, Sven _______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal
waldo kitty
to Jorge Aldo G. de F. Junior
Jorge Aldo G. de F. Junior wrote 5 lines
I dont like to take local variable initialization for granted. Even if the manual says that its guaranteed that a local variable will start with 0, i prefer to initialize everything to a known value myself.

+10000000000000000000~

this is a leson i learned way back in the TP2 days... i still use it in my TP/BP 6/7 code... either set it to zero or set it to nul(l)...

Show quoted text 5 lines
An aditional Move $varaddress, 00 at startup wont slow things down noticeably when your pc is running at 2ghz...

hummm... some of us still write for and work with >500Mhz machines... i still find it hard to believe that the lazarus executable with debug code is 75Meg or so... i've always prided myself on tight, fast, small code... maybe like turbo power used to do but i've even tightened some of their code in the past but that's another story for another place...

Sven Barth
to Jorge Aldo G. de F. Junior: I dont like to take local variable initialization for granted. Even if the manual says…

Well... seems like you didn't notice this feature yet :D

I'm talking about this:

=== source begin ===

procedure SomeProc;
var
   somevar: Integer = 42;
begin
end;

=== source end ===

This works in FPC, but doesn't in Delphi ;)

Regards
Sven

Jorge Aldo G. de F. Junior wrote 64 lines
I dont like to take local variable initialization for granted. Even if the manual says that its guaranteed that a local variable will start with 0, i prefer to initialize everything to a known value myself. An aditional Move $varaddress, 00 at startup wont slow things down noticeably when your pc is running at 2ghz... This unit needs to take care of big endian vs. low endian (maybe a $define ?) When i wrote that code i did not pay attention to this... Anything more complex (like interacting with DHCP server) would be too complex and probably dependent on external units (like synapse x lnet etc). Some people might prefer to use other library instead of the default choosen one, etc... 2011/7/26 Sven Barth: > On 26.07.2011 01:23, Paul Nicholls wrote: >> >> "Jorge Aldo G. de F. Junior" >> wrote in message >> >>> >>> Some time ago someone asked for a library able to do network >>> calculations. >>> >>> Here is something that might evolve into such library : >>> >> <SNIP> >>> >>> Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; >>> Begin >>> Result.Mode := False; >>> NetMask.Mode := False; >>> Result.IP := NetMask.IP Xor %11111111111111111111111111111111; >>> End; >>> >> <SNIP> >> >> I didn't know that freepascal handled binary formatted numbers?!? >> >> %11111111111111111111111111111111 > > There are often new things one can learn about what FPC supports ;) (though > binary numbers are already old for me ^^) > > The most recent finding (at least for me) was the abbility to initialize > local variables. > > Regards, > Sven > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Dimitri Smits
to Sven Barth

don't have a Delphi in reach for the moment to verify, but you could do that to a const (if you enable the assignable constants setting)

procedure SomeProc;
const
  someconst: Integer = 22;
begin
  //blabla
  someconst := 42;
  //yadda yadda
end;
----- "Sven Barth" wrote 97 lines
Well... seems like you didn't notice this feature yet :D I'm talking about this: === source begin === procedure SomeProc; var somevar: Integer = 42; begin end; === source end === This works in FPC, but doesn't in Delphi ;) Regards Sven Am 26.07.2011 21:27, schrieb Jorge Aldo G. de F. Junior: > I dont like to take local variable initialization for granted. > > Even if the manual says that its guaranteed that a local variable will > start with 0, > i prefer to initialize everything to a known value myself. > > An aditional > > Move $varaddress, 00 > > at startup wont slow things down noticeably when your pc is running at 2ghz... > > This unit needs to take care of big endian vs. low endian (maybe a $define ?) > > When i wrote that code i did not pay attention to this... > > Anything more complex (like interacting with DHCP server) would be too > complex and probably dependent on external units (like synapse x lnet > etc). Some people might prefer to use other library instead of the > default choosen one, etc... > > 2011/7/26 Sven Barth: >> On 26.07.2011 01:23, Paul Nicholls wrote: >>> >>> "Jorge Aldo G. de F. Junior" >>> wrote in message >>> >>>> >>>> Some time ago someone asked for a library able to do network >>>> calculations. >>>> >>>> Here is something that might evolve into such library : >>>> >>> <SNIP> >>>> >>>> Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; >>>> Begin >>>> Result.Mode := False; >>>> NetMask.Mode := False; >>>> Result.IP := NetMask.IP Xor %11111111111111111111111111111111; >>>> End; >>>> >>> <SNIP> >>> >>> I didn't know that freepascal handled binary formatted numbers?!? >>> >>> %11111111111111111111111111111111 >> >> There are often new things one can learn about what FPC supports ;) (though >> binary numbers are already old for me ^^) >> >> The most recent finding (at least for me) was the abbility to initialize >> local variables. >> >> Regards, >> Sven >> >> _______________________________________________ >> fpc-pascal maillist - >> http://lists.freepascal.org/mailman/listinfo/fpc-pascal >> > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Sven Barth
to Dimitri Smits
Dimitri Smits wrote 11 lines
don't have a Delphi in reach for the moment to verify, but you could do that to a const (if you enable the assignable constants setting) procedure SomeProc; const someconst: Integer = 22; begin //blabla someconst := 42; //yadda yadda end;

In this case "someconst" will keep the assigned value during different functions calls.

For example:

=== source begin ===

procedure SomeProc;
const
   someconst: Integer = 21;
begin
   if someconst = 42 then
     Writeln('The answer')
   else begin
     Writeln('Not the answer');
     someconst := 42;
   end;
end;
begin
   SomeProc;
   SomeProc;
end;

=== source end ===

will print:

=== output begin ===

Not the answer
The answer

=== output end ===

This was considered as the equivalent of a local static variable.

In case of "var" the definitions are normal variables and semantically equivalent to an initialization of the variable at the beginning of the function.

Regards,
Sven

Show quoted text 103 lines
----- "Sven Barth" schreef: > Well... seems like you didn't notice this feature yet :D > > I'm talking about this: > > === source begin === > > procedure SomeProc; > var > somevar: Integer = 42; > begin > > end; > > === source end === > > This works in FPC, but doesn't in Delphi ;) > > Regards > Sven > > Am 26.07.2011 21:27, schrieb Jorge Aldo G. de F. Junior: >> I dont like to take local variable initialization for granted. >> >> Even if the manual says that its guaranteed that a local variable > will >> start with 0, >> i prefer to initialize everything to a known value myself. >> >> An aditional >> >> Move $varaddress, 00 >> >> at startup wont slow things down noticeably when your pc is running > at 2ghz... >> >> This unit needs to take care of big endian vs. low endian (maybe a > $define ?) >> >> When i wrote that code i did not pay attention to this... >> >> Anything more complex (like interacting with DHCP server) would be > too >> complex and probably dependent on external units (like synapse x > lnet >> etc). Some people might prefer to use other library instead of the >> default choosen one, etc... >> >> 2011/7/26 Sven Barth: >>> On 26.07.2011 01:23, Paul Nicholls wrote: >>>> >>>> "Jorge Aldo G. de F. Junior" >>>> wrote in message >>>> > >>>>> >>>>> Some time ago someone asked for a library able to do network >>>>> calculations. >>>>> >>>>> Here is something that might evolve into such library : >>>>> >>>> <SNIP> >>>>> >>>>> Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; >>>>> Begin >>>>> Result.Mode := False; >>>>> NetMask.Mode := False; >>>>> Result.IP := NetMask.IP Xor %11111111111111111111111111111111; >>>>> End; >>>>> >>>> <SNIP> >>>> >>>> I didn't know that freepascal handled binary formatted numbers?!? >>>> >>>> %11111111111111111111111111111111 >>> >>> There are often new things one can learn about what FPC supports ;) > (though >>> binary numbers are already old for me ^^) >>> >>> The most recent finding (at least for me) was the abbility to > initialize >>> local variables. >>> >>> Regards, >>> Sven >>> >>> _______________________________________________ >>> fpc-pascal maillist - >>> http://lists.freepascal.org/mailman/listinfo/fpc-pascal >>> >> _______________________________________________ >> fpc-pascal maillist - >> http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jorge Aldo G. de F. Junior
to Sven Barth

nice, that was new to me :)

2011/7/27 Sven Barth :

Show quoted text 183 lines
On 27.07.2011 12:22, Dimitri Smits wrote: > > don't have a Delphi in reach for the moment to verify, but you could do > that to a const (if you enable the assignable constants setting) > > procedure SomeProc; > const >   someconst: Integer = 22; > begin >   //blabla >   someconst := 42; >   //yadda yadda > end; > In this case "someconst" will keep the assigned value during different functions calls. For example: === source begin === procedure SomeProc; const  someconst: Integer = 21; begin  if someconst = 42 then    Writeln('The answer')  else begin    Writeln('Not the answer');    someconst := 42;  end; end; begin  SomeProc;  SomeProc; end; === source end === will print: === output begin === Not the answer The answer === output end === This was considered as the equivalent of a local static variable. In case of "var" the definitions are normal variables and semantically equivalent to an initialization of the variable at the beginning of the function. Regards, Sven > > ----- "Sven Barth"  schreef: > >> Well... seems like you didn't notice this feature yet :D >> >> I'm talking about this: >> >> === source begin === >> >> procedure SomeProc; >> var >>    somevar: Integer = 42; >> begin >> >> end; >> >> === source end === >> >> This works in FPC, but doesn't in Delphi ;) >> >> Regards >> Sven >> >> Am 26.07.2011 21:27, schrieb Jorge Aldo G. de F. Junior: >>> >>> I dont like to take local variable initialization for granted. >>> >>> Even if the manual says that its guaranteed that a local variable >> >> will >>> >>> start with 0, >>> i prefer to initialize everything to a known value myself. >>> >>> An aditional >>> >>> Move $varaddress, 00 >>> >>> at startup wont slow things down noticeably when your pc is running >> >> at 2ghz... >>> >>> This unit needs to take care of big endian vs. low endian (maybe a >> >> $define ?) >>> >>> When i wrote that code i did not pay attention to this... >>> >>> Anything more complex (like interacting with DHCP server) would be >> >> too >>> >>> complex and probably dependent on external units (like synapse x >> >> lnet >>> >>> etc). Some people might prefer to use other library instead of the >>> default choosen one, etc... >>> >>> 2011/7/26 Sven Barth: >>>> >>>> On 26.07.2011 01:23, Paul Nicholls wrote: >>>>> >>>>> "Jorge Aldo G. de F. Junior" >>>>>     wrote in message >>>>> >> >> >>>>>> >>>>>> Some time ago someone asked for a library able to do network >>>>>> calculations. >>>>>> >>>>>> Here is something that might evolve into such library : >>>>>> >>>>> <SNIP> >>>>>> >>>>>> Function NetMaskToHostMask(NetMask : TNetworkIP): TNetworkIP; >>>>>> Begin >>>>>> Result.Mode := False; >>>>>> NetMask.Mode := False; >>>>>> Result.IP := NetMask.IP Xor %11111111111111111111111111111111; >>>>>> End; >>>>>> >>>>> <SNIP> >>>>> >>>>> I didn't know that freepascal handled binary formatted numbers?!? >>>>> >>>>> %11111111111111111111111111111111 >>>> >>>> There are often new things one can learn about what FPC supports ;) >> >> (though >>>> >>>> binary numbers are already old for me ^^) >>>> >>>> The most recent finding (at least for me) was the abbility to >> >> initialize >>>> >>>> local variables. >>>> >>>> Regards, >>>> Sven >>>> >>>> _______________________________________________ >>>> fpc-pascal maillist  -   >>>> http://lists.freepascal.org/mailman/listinfo/fpc-pascal >>>> >>> _______________________________________________ >>> fpc-pascal maillist  -   >>> http://lists.freepascal.org/mailman/listinfo/fpc-pascal >> >> _______________________________________________ >> fpc-pascal maillist  -   >> http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > _______________________________________________ > fpc-pascal maillist  -   > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal