Title: IP Masking
Question: Checking an IP against a mask - ideal for server systems when a client connects...
Answer:
While I was coding my many network and Internet related software I found I often had to check on who was connecting to the server. Being an avid user of IRC I found that I could use similar masking techniques it uses.
I came up with the following routine, which will take and IP and a simple mask and let you know if its fits properly:
function IPMatchMask(IP, Mask: String): Boolean;
procedure SplitDelimitedText(Text: String; Delimiter: String; Results: TStrings);
var
TheWord, CommaText: String;
begin
Results.Clear;
CommaText := Text + Delimiter;
while (Pos(Delimiter,CommaText) 0) do
begin
TheWord := Copy(CommaText, 1, Pos(Delimiter, CommaText) - 1);
CommaText := Copy(CommaText, Pos(Delimiter, CommaText) +
Length(Delimiter), Length(CommaText));
Results.Add(TheWord);
end;
end;
var
IPs, Masks: TStringList;
I: Integer;
begin
IPs := TStringList.Create;
try
Masks := TStringList.Create;
try
SplitDelimitedText(LowerCase(IP),'.',IPs);
SplitDelimitedText(LowerCase(Mask),'.',Masks);
Result := True;
if IPs.Count Masks.Count then
begin
Result := False;
Exit;
end;
for I := 0 to IPs.Count - 1 do
begin
if (IPs.Strings[I] Masks.Strings[I]) and
(Masks.Strings[I] '*') then
Result := False;
end;
finally
Masks.Free;
end;
finally
IPs.Free;
end;
end;
The routine isn't very complex. All IP's (and even DNS names) are period donated (period is a full stop incase you didn't know), so working on that it would be easy to split it up. For example take the IP 212.104.58.63, this can be split up into a list like so:
212
104
58
63
Now, you can also do the same for a mask, for example 212.104.*.63, which would become:
212
104
*
63
Now for masking I've used * as a wildcard (meaning anything), so to check our IP against our mask, you can simple iterate the list and check each number to be equal, or in the case of a * skipping it. That's basically all my routine does.
You can use this for example on the TServerSocket OnClientConnect, for example:
procedure ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinsocket);
begin
if not (IPMatchMask(Socket.LocalAddress,'212.*.*.5')) then Socket.Close;
end;
That will terminate anyone trying to connect to the server who doesn't have the IP of 212.*.*.5
Anyhows, have fun!