Recent

Author Topic: Synapse: how to use its PING feature without needing root rights (Linux)?  (Read 23118 times)

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
hello,
may be the better solution is to use the system ping of your O.S because often you can execute it with any user.
With Tprocess or better TprocessEx  from processutils unit of the fpcupdeluxe project because you can display output in RealTime , you can easily launch the system ping and get output to see if it is OK.
in attachments :
1 - project to launch a console command from Lazarus GUI and display the output in a Tmemo.
2 - Animated Gif of execution of this project on Xubuntu 22.04 and Windows 11
code using TProcessEx in the project :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Bt_GoExClick(Sender: TObject);
  2. var
  3.   Command: String;
  4.   Param : String;
  5.   ParamStr : String;
  6.   Params : TStringArray;
  7. begin
  8.   if pos(' ',Ed_Cmd.text) = 0 then
  9.      Command := Ed_Cmd.Text
  10.   else
  11.    begin
  12.      Command := LeftStr(Ed_Cmd.Text,pos(' ',Ed_Cmd.text)- 1);
  13.      ParamStr := RightStr(Ed_Cmd.Text, length(Ed_Cmd.text) - pos(' ',Ed_Cmd.text));
  14.    end;
  15.   try
  16.     Proc := TProcessEx.Create(nil);
  17.     Proc.Executable :=  Command;
  18.     if Length(ParamStr) > 0  then
  19.        begin
  20.           Params := ParamStr.Split(' ');
  21.           For Param in Params do  Proc.Parameters.Add(Param);
  22.        end;
  23.     Proc.OnErrorM:=@(ProcessError);
  24.     Proc.OnOutputM:=@(ProcessOutput);
  25.     Proc.Execute();
  26.   finally
  27.      Proc.Free;
  28.      Proc := nil;
  29.    end;
  30. end;


Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

MarkMLl

  • Hero Member
  • *****
  • Posts: 8504
may be the better solution is to use the system ping of your O.S because often you can execute it with any user.

If that is precisely what's needed then I agree, since the binary normally has the appropriate capabilities set when it was installed (historically, it was setuid root).

Code: [Select]
/usr//bin$ sudo getcap *

kwin_wayland cap_sys_resource=ep
ping cap_net_raw=ep

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
here is a code to run a ping with one request and timeout of 1 second on Windows and linux  using TProcess . The function RunPing return True if ping is OK  :
Code: Pascal  [Select][+][-]
  1. program pingTprocess;
  2. {$mode objfpc}{$H+}
  3. uses Classes,sysutils, Process;
  4.  
  5. Function RunPing(const Host: string) : Boolean;
  6. var
  7.   Proc: TProcess;
  8.   SL_stdout: TStringList;
  9.   SL_stderr: TStringList;
  10. begin
  11.   RunPing := False;
  12.   Proc := TProcess.Create(nil);
  13.   SL_stdout := TStringList.Create;
  14.   SL_stderr := TStringList.Create;
  15.   try
  16.     // Command    : one request , max response time  1 second
  17.    {$IFDEF LINUX}
  18.       Proc.Executable :=  '/bin/ping';
  19.       Proc.Parameters.AddCommaText('-c,1,-W,1,' + Host);
  20.    {$ELSE}
  21.       Proc.Executable :=  'ping.exe';
  22.       Proc.Parameters.AddCommaText('/n,1,/w,1000,' + Host);
  23.    {$ENDIF}
  24.       // Options
  25.       Proc.Options := Proc.Options + [poUsePipes, poWaitOnExit];
  26.       Proc.Execute();
  27.       // Read Output
  28.       SL_stdout.LoadFromStream(Proc.Output);
  29.       SL_stderr.LoadFromStream(Proc.StdErr);
  30.       writeln(SL_stdout.Text);
  31.       if SL_stderr.Text <> '' then  writeln(SL_stderr.Text);
  32.       {$IFDEF LINUX}  // to be adjust with ping local language setting
  33.       if pos('rtt', SL_stdout.Text) > 0 then RunPing := True;
  34.       {$ELSE}     // to be adjust with ping local language setting
  35.       if pos('Dur', SL_stdout.Text) > 0 then RunPing := True;
  36.       {$ENDIF}
  37.    finally
  38.       Proc.Free;
  39.       SL_stdout.Free;
  40.       SL_stderr.Free;
  41.       Proc := nil;
  42.    end;
  43. end;
  44.  
  45. var res : Boolean;
  46. begin
  47.     // use first parameter for host
  48.   if ParamCount > 0 then
  49.      begin
  50.      res :=  RunPing(ParamStr(1));
  51.      writeln('Ping Result : ', res)
  52.      end
  53.   else
  54.      Writeln('No Host passed.');
  55. end.
« Last Edit: August 22, 2025, 09:31:48 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

rvk

  • Hero Member
  • *****
  • Posts: 6885
Aren't SOCK_DGRAM and IPPROTO_ICMP already available on older versions? And isn't it just that Trixie is only implementing this now in ping versions?
In that case you could create your own ping function with SOCK_DGRAM and IPPROTO_ICMP without needing privileges.

https://stackoverflow.com/questions/8290046/icmp-sockets-linux
Like I stated before... wouldn't it be more useful to just create a ping procedure yourself which uses the SOCK_DGRAM and IPPROTO_ICMP ?? Because the netroup_range is normally set very wide, all users have access.
(test with sysctl net.ipv4.ping_group_range)

Here is a minimalistic ping program (uses just fpc functions).
It just uses IP but you could easily expand it to also take host-names and resolve those to IPs).

Code: Pascal  [Select][+][-]
  1. program minimalping;
  2.  
  3. {$mode objfpc}
  4. uses
  5.   SysUtils, Sockets, BaseUnix, DateUtils;
  6.  
  7. const
  8.   ICMP_ECHO      = 8;
  9.   ICMP_ECHOREPLY = 0;
  10.   TIMEOUT_SEC    = 2;
  11.  
  12. type
  13.   TICMPHeader = packed record
  14.     icmp_type   : byte;
  15.     icmp_code   : byte;
  16.     icmp_cksum  : word;
  17.     icmp_id     : word;
  18.     icmp_seq    : word;
  19.   end;
  20.  
  21. function Checksum(const Buf; Len: integer): word;
  22. var
  23.   sum: cardinal = 0;
  24.   i: integer;
  25.   p: PByte;
  26. begin
  27.   p := @Buf;
  28.   i := 0;
  29.   while i < Len - 1 do
  30.   begin
  31.     sum := sum + (p[i] shl 8 + p[i + 1]);
  32.     Inc(i,2);
  33.   end;
  34.   if (Len mod 2) <> 0 then
  35.     sum := sum + (p[Len-1] shl 8);
  36.  
  37.   sum := (sum shr 16) + (sum and $FFFF);
  38.   sum := sum + (sum shr 16);
  39.   Result := not word(sum);
  40. end;
  41.  
  42. procedure Ping(const Host: string);
  43. var
  44.   sock: cint;
  45.   sa: TInetSockAddr;
  46.   icmp: TICMPHeader;
  47.   buf: array[0..63] of byte;
  48.   n: integer;
  49.   id, seq: word;
  50.   sendTime, recvTime: TDateTime;
  51.   ms: integer;
  52.   fdset: TFDSet;
  53.   timeout: TTimeVal;
  54. begin
  55.   FillChar(sa, SizeOf(sa), 0);
  56.   sa.sin_family := AF_INET;
  57.   sa.sin_addr := StrToNetAddr(Host);
  58.  
  59.   sock := fpSocket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
  60.   if sock = -1 then
  61.     raise Exception.Create('Socket error');
  62.  
  63.   id := word(FpGetPid);
  64.   seq := 1;
  65.   FillChar(icmp, SizeOf(icmp), 0);
  66.   icmp.icmp_type := ICMP_ECHO;
  67.   icmp.icmp_code := 0;
  68.   icmp.icmp_id := htons(id);
  69.   icmp.icmp_seq := htons(seq);
  70.   icmp.icmp_cksum := 0;
  71.   icmp.icmp_cksum := Checksum(icmp, SizeOf(icmp));
  72.  
  73.   Move(icmp, buf, SizeOf(icmp));
  74.   sendTime := Now;
  75.   n := fpSendTo(sock, @buf, SizeOf(icmp), 0, @sa, SizeOf(sa));
  76.   if n < SizeOf(icmp) then
  77.     raise Exception.Create('Send error');
  78.  
  79.   fpFD_ZERO(fdset);
  80.   fpFD_SET(sock, fdset);
  81.   timeout.tv_sec := TIMEOUT_SEC;
  82.   timeout.tv_usec := 0;
  83.   n := fpSelect(sock+1, @fdset, nil, nil, @timeout);
  84.   if n > 0 then
  85.   begin
  86.     n := fpRecv(sock, @buf, SizeOf(buf), 0);
  87.     recvTime := Now;
  88.     ms := MilliSecondsBetween(sendTime, recvTime);
  89.     WriteLn('Reply received! time=', ms, ' ms');
  90.   end
  91.   else
  92.   begin
  93.     WriteLn('Request timed out after ', TIMEOUT_SEC, ' seconds.');
  94.   end;
  95.   fpClose(sock);
  96. end;
  97.  
  98. begin
  99.   if ParamCount <> 1 then
  100.   begin
  101.     WriteLn('Usage: minimalping <ip>');
  102.     Halt(1);
  103.   end;
  104.   Ping(ParamStr(1));
  105. end.

Quote
$ ./minimalping 1.1.1.1
Reply received! time=9 ms
$ ./minimalping 1.1.2.1
Request timed out after 2 seconds.
$ ./minimalping google.com    # hostnames not yet implemented
Reply received! time=0 ms
$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 0   2147483647
$

Dzandaa

  • Hero Member
  • *****
  • Posts: 501
  • From C# to Lazarus
Hi,

@rvk:

Thank you for the code.

I will test it in one of my programs.



B->
Regards,
Dzandaa

Hartmut

  • Hero Member
  • *****
  • Posts: 1000
may be the better solution is to use the system ping of your O.S because often you can execute it with any user.
With Tprocess or better TprocessEx  from processutils unit of the fpcupdeluxe project because you can display output in RealTime , you can easily launch the system ping and get output to see if it is OK.
Thanks a lot Jurassic Pork for that demo and for including unit 'processutils' from the fpcupdeluxe project because I did not have it before. I tested it and it works great. I included your code to my collection of useful sources.

here is a code to run a ping with one request and timeout of 1 second on Windows and linux  using TProcess . The function RunPing return True if ping is OK
Thanks again. I learned something new because you used some features of TProcess I was not aware of.



wouldn't it be more useful to just create a ping procedure yourself which uses the SOCK_DGRAM and IPPROTO_ICMP ??
...
Here is a minimalistic ping program (uses just fpc functions).
Thank you too rvk for this code. It's good to have an alternative. As a beginner to all this network stuff I understand nothing what you are doing there. Please: what are the advantages of using your code compared with the very simple code of Jurassic Pork in reply #11? In which cases would your code give better results?



Does that mean:
 - I create a new group and give it raw socket capability
 - then I add the current user to this group
 - after this, all programs which are started by the current user, do not need sudo any longer to use the PING feature of Synapse?
This would be a great solution!
Did you mean this?
Yes, if understand correct then solution sysctl by rvk make possible and have that. Not have tested myself. If need help I need read instruction first
Thanks Thausand for your reply. If I understand you correctly, it is possible to create a new group and give raw socket capability to this group. Your mentioned 'sysctl' I found only in reply #8 by rvk:

I just checked in Bookworm and got this:
Quote
$ sudo sysctl -a | grep ping
net.ipv4.ping_group_range = 0   2147483647
net.ipv4.tcp_pingpong_thresh = 1

Please can you tell me how to give raw socket capability to the new group?

Thausand

  • Sr. Member
  • ****
  • Posts: 389
Thank you too rvk for this code. It's good to have an alternative. As a beginner to all this network stuff I understand nothing what you are doing there. Please: what are the advantages of using your code compared with the very simple code of Jurassic Pork in reply #11? In which cases would your code give better results?
Not name rvk but advantage rvk code is have all control (in code) and not rely 3th party executable (maybe some distribution/user not install ping).

Quote
Thanks Thausand for your reply. If I understand you correctly, it is possible to create a new group and give raw socket capability to this group. Your mentioned 'sysctl' I found only in reply #8 by rvk:
Yes, correct but not exact. Have note I have not test.

Make change option net.ipv4.ping_group_range make possible to have set groupID to restrict to GID. So make group, write groupIDd to option net.ipv4.ping_group_range <GID> , example group network have GID 100 then:
Code: [Select]
echo 'net.ipv4.ping_group_range = 100 100' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

But have seen f.e. fedora set for all user and groupID (range 0..2147483647).

Hartmut

  • Hero Member
  • *****
  • Posts: 1000
Thank you too rvk for this code. It's good to have an alternative. As a beginner to all this network stuff I understand nothing what you are doing there. Please: what are the advantages of using your code compared with the very simple code of Jurassic Pork in reply #11? In which cases would your code give better results?
Not name rvk but advantage rvk code is have all control (in code) and not rely 3th party executable (maybe some distribution/user not install ping).
I think you misunderstood. The simple code of Jurassic Pork in reply #11 does not rely on 3th party executable (as far as I can see). Only his demos in reply #30 and #32 do call 3th party executable.

Quote
Quote
Thanks Thausand for your reply. If I understand you correctly, it is possible to create a new group and give raw socket capability to this group. Your mentioned 'sysctl' I found only in reply #8 by rvk:
Yes, correct but not exact. Have note I have not test.

Make change option net.ipv4.ping_group_range make possible to have set groupID to restrict to GID. So make group, write groupIDd to option net.ipv4.ping_group_range <GID> , example group network have GID 100 then:
Code: [Select]
echo 'net.ipv4.ping_group_range = 100 100' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

But have seen f.e. fedora set for all user and groupID (range 0..2147483647).

Thanks a lot Thausand. I tried this, but unfortunately it did not work:
Code: Text  [Select][+][-]
  1. # create a new group:
  2. hg6@a2100:/media/D/Tst$ sudo addgroup newgroup1
  3. info: Lege Gruppe »newgroup1« (GID 1002) an …
  4.  
  5. # add current user to this group:
  6. sudo usermod -aG newgroup1 $USER
  7.  
  8. # did logoff + logon so that last command works
  9.  
  10. # check GID of new group:
  11. hg6@a2100:/media/D/Tst$ getent group newgroup1
  12. newgroup1:x:1002:hg6
  13.  
  14. # show current setting of net.ipv4.ping_group_range:
  15. hg6@a2100:/media/D/Tst$ sysctl net.ipv4.ping_group_range
  16. net.ipv4.ping_group_range = 1   0
  17.  
  18. # allow new group temporary:
  19. hg6@a2100:/media/D/Tst$ sudo sysctl net.ipv4.ping_group_range='1002 1002'
  20. [sudo] Passwort für hg6:
  21. net.ipv4.ping_group_range = 1002 1002
  22.  
  23. # verify new setting:
  24. hg6@a2100:/media/D/Tst$ sysctl net.ipv4.ping_group_range
  25. net.ipv4.ping_group_range = 1002        1002

But when I start now a program, which uses the PING feature of FPC package Synapse (which uses RAW sockets, for more details please see my very 1st post) it does not work. My goal is not enabling /usr/bin/ping, my goal is enabling  the PING feature of FPC package Synapse in a self written program, as I asked for:

Does that mean:
 - I create a new group and give it raw socket capability
 - then I add the current user to this group
 - after this, all programs which are started by the current user, do not need sudo any longer to use the PING feature of Synapse?
This would be a great solution!
Did you mean this?

Did we misunderstood?
Or did I something wrong?

rvk

  • Hero Member
  • *****
  • Posts: 6885
Did we misunderstood?
Or did I something wrong?
net.ipv4.ping_group_range doesn't control the SOCK_RAW.
It controls the  SOCK_DGRAM and capability to use IPPROTO_ICMP on that (it's via SOCK_DGRAM, so UDP).

Some time ago... original ping used SOCK_RAW+IPPROTO_ICMP to send pings.
Because RAW sockets where only for admin/root access, the ping program was tagged +s (setuid) so it executed as user root. Even if it was executed by a random non privileged user.

There is an option to allow RAW for users (with groups and maybe for executable via setcap) but I'm not familiar with that.

Later on... ping switched to SOCK_DGRAM+IPPROTO_ICMP, so no RAW sockets where needed.
The ability of sending ICMP via SOCK_DGRAM is regulated by that sysctl net.ipv4.ping_group_range.
(That's how I understand it now, but I could be wrong)

For a raspberry pi it's standard set as net.ipv4.ping_group_range = 0   2147483647
Is this for you 0 1 ?
What Linux are you running and what version??

On raspberry pi I can't even change the net.ipv4.ping_group_range. So could you test this app on a non privileged user with net.ipv4.ping_group_range set as 0 1 and as 0   2147483647 ??

(For this one you can pass hostnames like google.com etc.)

Code: Pascal  [Select][+][-]
  1. program minimalping;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   SysUtils, Sockets, BaseUnix, netdb, Unix, DateUtils;
  7.  
  8. const
  9.   ICMP_ECHO = 8;
  10.   TIMEOUT_SEC = 2;
  11.  
  12. type
  13.   TICMPHeader = packed record
  14.     icmp_type: byte;
  15.     icmp_code: byte;
  16.     icmp_cksum: word;
  17.     icmp_id: word;
  18.     icmp_seq: word;
  19.   end;
  20.  
  21.   function myGetTickCount: qword;
  22.   var
  23.     tv: ttimeval;
  24.   begin
  25.     fpgettimeofday(@tv, nil);
  26.     Result := Int64(tv.tv_sec) * 1000000 + tv.tv_usec;
  27.   end;
  28.  
  29.   function Checksum(const Buf; Len: integer): word;
  30.   var
  31.     sum: cardinal = 0;
  32.     i: integer;
  33.     p: pbyte;
  34.   begin
  35.     p := @Buf;
  36.     i := 0;
  37.     while i < Len - 1 do
  38.     begin
  39.       sum := sum + (p[i] shl 8 + p[i + 1]);
  40.       Inc(i, 2);
  41.     end;
  42.     if (Len mod 2) <> 0 then
  43.       sum := sum + (p[Len - 1] shl 8);
  44.  
  45.     sum := (sum shr 16) + (sum and $FFFF);
  46.     sum := sum + (sum shr 16);
  47.     Result := not word(sum);
  48.   end;
  49.  
  50.   function IsValidIP(IP: string): boolean;
  51.   var
  52.     H: THostEntry;
  53.   begin
  54.     Result := ResolveHostByAddr(StrToHostAddr(IP), H);
  55.   end;
  56.  
  57.   function GetHostIP(HostName: string): string;
  58.   var
  59.     H: THostEntry;
  60.   begin
  61.     if ResolveHostByName(HostName, H) then
  62.       Result := HostAddrToStr(NetToHost(H.Addr))
  63.     else
  64.       Result := '';
  65.   end;
  66.  
  67.   function PingHost(const Host: string; var IP: string): double;
  68.   var
  69.     sock: cint;
  70.     sa: TInetSockAddr;
  71.     icmp: TICMPHeader;
  72.     buf: array[0..63] of byte;
  73.     n: integer;
  74.     id, seq: word;
  75.     sendTime, recvTime: qword;
  76.     ms: double;
  77.     fdset: TFDSet;
  78.     timeout: TTimeVal;
  79.   begin
  80.     Result := -99;
  81.  
  82.     ip := host;
  83.     if not IsValidIP(ip) then
  84.     begin
  85.       ip := GetHostIP(host);
  86.       if ip = '' then
  87.         exit(-1); // WriteLn('Could not resolve ', host);
  88.     end;
  89.     writeln('ip ', ip);
  90.  
  91.     FillChar(sa, SizeOf(sa), 0);
  92.     sa.sin_family := AF_INET;
  93.     sa.sin_addr := StrToNetAddr(ip);
  94.  
  95.     sock := fpSocket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
  96.     if sock = -1 then
  97.       exit(-2); // Socket error
  98.  
  99.     id := word(FpGetPid);
  100.     seq := 1;
  101.     FillChar(icmp, SizeOf(icmp), 0);
  102.     icmp.icmp_type := ICMP_ECHO;
  103.     icmp.icmp_code := 0;
  104.     icmp.icmp_id := htons(id);
  105.     icmp.icmp_seq := htons(seq);
  106.     icmp.icmp_cksum := 0;
  107.     icmp.icmp_cksum := Checksum(icmp, SizeOf(icmp));
  108.  
  109.     Move(icmp, buf, SizeOf(icmp));
  110.     sendTime := myGetTickCount;
  111.     n := fpSendTo(sock, @buf, SizeOf(icmp), 0, @sa, SizeOf(sa));
  112.     if n < SizeOf(icmp) then
  113.     begin
  114.       fpClose(sock);
  115.       exit(-3); // unknown error, reply smaller than icmp
  116.     end;
  117.  
  118.     fpFD_ZERO(fdset);
  119.     fpFD_SET(sock, fdset);
  120.     timeout.tv_sec := TIMEOUT_SEC;
  121.     timeout.tv_usec := 0;
  122.     n := fpSelect(sock + 1, @fdset, nil, nil, @timeout);
  123.     if n > 0 then
  124.     begin
  125.       n := fpRecv(sock, @buf, SizeOf(buf), 0);
  126.       recvTime := myGetTickCount;
  127.       ms := (recvTime - sendTime) / 1000;
  128.       Result := ms;
  129.     end;
  130.     fpClose(sock);
  131.   end;
  132.  
  133. var
  134.   host, ip: string;
  135.   ms: double;
  136. begin
  137.   if ParamCount <> 1 then
  138.   begin
  139.     WriteLn('Usage: minimalping <hostname-or-ip>');
  140.     Halt(1);
  141.   end;
  142.   host := ParamStr(1);
  143.   WriteLn('Pinging: ', host);
  144.   ms := PingHost(host, ip);
  145.   WriteLn('Result: ', ip, ' = ', ms: 0: 3, ' ms');
  146. end.

Quote
# ./minimalping google.com
Pinging: google.com
ip 172.217.23.206
Result: 172.217.23.206 = 9.418 ms
« Last Edit: August 22, 2025, 04:42:09 pm by rvk »

Thausand

  • Sr. Member
  • ****
  • Posts: 389
...
(That's how I understand it now, but I could be wrong)
...
After read I have same understanding.

Have raw socket can do when use setcap. When use sysctl then use IPPROTO and have other implementation not use raw socket.

@Hartmut
I have look for setcap with group but think is not common and have look other solution jurrassic pork because I look for wrong example and wrong replied.

Dzandaa

  • Hero Member
  • *****
  • Posts: 501
  • From C# to Lazarus
Hi,

@rvk:

For info:

I tried your last version on Linux Mint 22.1 Lazarus 3.8 FPC 3.2.2 and it always return -2.


B->
Regards,
Dzandaa

rvk

  • Hero Member
  • *****
  • Posts: 6885
I have look for setcap with group but think is not common and have look other solution jurrassic pork because I look for wrong example and wrong replied.
The setcap command in Linux is intended to add or remove file capabilities from a binary, and is not directly meant for setting capabilities for a group.

AFAIK there is no group-based mechanism in Linux for allowing raw socket access.

I tried your last version on Linux Mint 22.1 Lazarus 3.8 FPC 3.2.2 and it always return -2.
Does it work with root?
I'll try it later in a VM.

Hartmut

  • Hero Member
  • *****
  • Posts: 1000
net.ipv4.ping_group_range doesn't control the SOCK_RAW.
It controls the  SOCK_DGRAM and capability to use IPPROTO_ICMP on that (it's via SOCK_DGRAM, so UDP).
Ok, I understand. Then it won't help for to use the PING feature of Synapse. Thanks for clarification.

Quote
There is an option to allow RAW for users (with groups and maybe for executable via setcap) but I'm not familiar with that.
If someone else is familiar with how to allow RAW sockets by groups I would be very interested.

Quote
For a raspberry pi it's standard set as net.ipv4.ping_group_range = 0   2147483647
Is this for you 0 1 ?
What Linux are you running and what version??
My standard for net.ipv4.ping_group_range is:
Code: Text  [Select][+][-]
  1. hg6@a2100:/media/D/Tst$ sysctl net.ipv4.ping_group_range
  2. net.ipv4.ping_group_range = 1   0
  3.  
I use Ubuntu 24.04 with KDE-Desktop.

Quote
So could you test this app on a non privileged user with net.ipv4.ping_group_range set as 0 1 and as 0   2147483647 ??

Here are the results for standard net.ipv4.ping_group_range with FPC 3.2.2:
Code: Text  [Select][+][-]
  1. hg6@a2100:~$ sysctl net.ipv4.ping_group_range
  2. net.ipv4.ping_group_range = 1   0
  3.  
  4. hg6@a2100:~$ miniping google.de
  5. Pinging: google.de
  6. ip 142.250.186.131
  7. Result: 142.250.186.131 = -2.000 ms
  8.  
  9. hg6@a2100:~$ ping google.de -4 -c 4
  10. PING google.de (142.250.186.131) 56(84) bytes of data.
  11. 64 bytes from fra24s07-in-f3.1e100.net (142.250.186.131): icmp_seq=1 ttl=119 time=13.4 ms
  12. 64 bytes from fra24s07-in-f3.1e100.net (142.250.186.131): icmp_seq=2 ttl=119 time=12.9 ms
  13. 64 bytes from fra24s07-in-f3.1e100.net (142.250.186.131): icmp_seq=3 ttl=119 time=12.9 ms
  14. 64 bytes from fra24s07-in-f3.1e100.net (142.250.186.131): icmp_seq=4 ttl=119 time=12.9 ms
  15.  
  16. --- google.de ping statistics ---
  17. 4 packets transmitted, 4 received, 0% packet loss, time 3004ms
  18. rtt min/avg/max/mdev = 12.900/13.045/13.433/0.224 ms
  19. hg6@a2100:~$
You see that result 'ms' is negative... (but the ip-address is correct).

Here are the results for net.ipv4.ping_group_range of 0 2147483647:
Code: Text  [Select][+][-]
  1. hg6@a2100:~$ sudo sysctl net.ipv4.ping_group_range='0 2147483647'
  2. [sudo] Passwort für hg6:
  3. net.ipv4.ping_group_range = 0 2147483647
  4. hg6@a2100:~$ sysctl net.ipv4.ping_group_range
  5. net.ipv4.ping_group_range = 0   2147483647
  6.  
  7. hg6@a2100:~$ miniping google.de
  8. Pinging: google.de
  9. ip 142.250.74.195
  10. Result: 142.250.74.195 = 17.600 ms
  11. hg6@a2100:~$

May I ask again:
What are the advantages of using your code compared with the very simple code of Jurassic Pork in reply #11? In which cases would your code give better results (beside that your's can resolve a hostname to it's ip-address)?



I have look for setcap with group but think is not common and have look other solution jurrassic pork because I look for wrong example and wrong replied.
Ok.

Hartmut

  • Hero Member
  • *****
  • Posts: 1000
I tried your last version on Linux Mint 22.1 Lazarus 3.8 FPC 3.2.2 and it always return -2.
Does it work with root?

If I start your code with setting net.ipv4.ping_group_range = '1 0' then I always get 'ms' = -2 ms (also with sudo).
If I start your code with setting net.ipv4.ping_group_range = '0 2147483647' then I always get a 'ms' near 17 ms (with and without sudo).

rvk

  • Hero Member
  • *****
  • Posts: 6885
Here are the results for net.ipv4.ping_group_range of 0 2147483647:
Ok, then it works. That confirms that SOCK_DGRAM, IPPROTO_ICMP works with net.ipv4.ping_group_range set correctly (to include the wide range).

May I ask again:
What are the advantages of using your code compared with the very simple code of Jurassic Pork in reply #11? In which cases would your code give better results (beside that your's can resolve a hostname to it's ip-address)?
Well, code in #11 uses TCP/port combination. So you need to know which port the server has open (http, https, ftp, VoIP etc). But... not all services listen to the TCP protocol. You also have UDP protocol. A VoIP server for instance is normally listening on UDP (sometimes both UDP and TCP). The code in #11 doesn't check for UDP ports.

ICMP PING (Echo Request) is just another method of checking for presence on the network. But... not all servers or computers have to respond to ICMP PING requests. Servers on the internet normally do (because it's a usual way of checking if the server is up). But for example lots of consumer routers (for example your own router) could have ICMP reply set to off (usually this is an option to set on or off in the router). So ICMP is not guaranteed but it is very common under open servers on the internet.

So ICMP PING could just be one of the mechanisms you use to check if a server is up. For actual internet servers is the easiest because you don't have to know what service and ports you need to check. But if you want to know if a HTTPS (web-server) is up, you can directly check for TCP/443 or TCP/80.

If I start your code with setting net.ipv4.ping_group_range = '1 0' then I always get 'ms' = -2 ms (also with sudo).
If I start your code with setting net.ipv4.ping_group_range = '0 2147483647' then I always get a 'ms' near 17 ms (with and without sudo).
1 to 0 seems like nobody can use SOCK_DGRAM, IPPROTO_ICMP. Not even root. 0 to 0 or 0 to 1 would include root (0). But 1 to 0 is nothing.

I wonder if that's the default setting in that distro?
« Last Edit: August 22, 2025, 07:05:40 pm by rvk »

 

TinyPortal © 2005-2018