[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ICMP socket with Gambas


Hello Lee,
...and now ?

[code]

Private Const BUFFER_SIZE As Integer = 1024


Library "libc:6"

Private Enum IPPROTO_IP, IPPROTO_ICMP, AF_INET, SOCK_DGRAM = 2, SOCK_RAW, IP_HDRINCL = 3, IPPROTO_TCP = 6

Public Struct SockAddr 
  SinFamily As Short
  SinPort As Short
  SinAddr As Pointer
End Struct

Public Struct timeval
  tv_sec As Long
  tv_usec As Long
End Struct

Private Extern socket(domain As Integer, type As Integer, protocol As Integer) As Integer
Private Extern close(sockfd As Integer) As Integer
Private Extern inet_pton(af As Integer, src As String, dst As Pointer) As Integer
Private Extern sendto(sockfd As Integer, buf As Byte[], size As Integer, flags As Integer, sockaddr As SockAddr, addrlen As Integer) As Integer

' int gettimeofday (struct timeval *__restrict __tv, void *__restrict __tz)
' Get the current time of day, putting it into *TV.
Private Extern gettimeofday(__tv As Timeval, __tz As Pointer) As Integer

' Read N bytes into BUF through socket FD.
' ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)
Private Extern recvfrom(__fd As Integer, __buf As Byte[], __ As Long, __flags As Integer, __addr As Pointer, __addr_len As Pointer) As Long


Private Sub CalcChecksum(aHeader As Byte[]) As Short
  
  Dim iSum As Long
  Dim iVal As Short
  
  For i As Integer = 0 To aHeader.Max Step 2
    iVal = (CShort(aHeader[i]) Lsl 8) + aHeader[i + 1]
    iSum += iVal
  Next
  
  While iSum > &HFFFF&
    iSum = (iSum Lsr 16) + (iSum And &HFFFF)
  Wend
  
  Return Not iSum
  
End

Public Sub Main()

  Dim sockfd, rc, buffer_len As Integer
  Dim aHeader As Byte[] = [8, 0, 0, 0, 0, 0, 0, 0]
  Dim iChecksum As Short
  Dim DestAddr As New SockAddr
  Dim buffer As New Byte[BUFFER_SIZE]
  Dim start_time, end_time As New Timeval
  
  sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)
  If sockfd < 0 Then 'error
    Print "Socket call error: " & System.Error
    Quit 
  Endif

  DestAddr.SinFamily = AF_INET
  DestAddr.SinPort = 0
  DestAddr.SinAddr = Alloc(SizeOf(gb.Pointer), 2)

  rc = inet_pton(AF_INET, "8.8.8.8", DestAddr.SinAddr)
  If rc < 1 Then 
    Print "Error converting address."
    Quit 
  Endif

  iChecksum = CalcChecksum(aHeader)
  aHeader[2] = (iChecksum Lsr 8) And &HFF
  aHeader[3] = iChecksum And &HFF

  gettimeofday(start_time, 0)

  Dim p As Pointer = Alloc(32)
  Dim st As Stream
  st = Memory p For Write 
  Write #st, DestAddr.SinFamily As Short
  Write #st, 0 As Short
  Write #st, DestAddr.SinAddr, 16
  st.Close

  rc = sendto(sockfd, aHeader, 8, 0, p, Object.SizeOf(DestAddr))
  If rc < 0 Then 
    Print "Send error:", System.Error
  Else 
    Print "Bytes sent:", rc
  Endif
  Free(p)
  Free(DestAddr.SinAddr)
  
  buffer_len = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, 0, 0)
  If buffer_len < 0 Then Error.Raise("Errore !")

  gettimeofday(end_time, 0)
  
  Dim latency As Float = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec) / 1000000.0
  Print "Latency: ", latency; " seconds"

  Finally 
    If sockfd Then 
      rc = close(sockfd)
    Endif
    If rc < 0 Then  'error
      Print "Close error: " & System.Error
    Endif
    
    Catch 
      Debug Error.Text;; "at";; Error.Where

End

[/code]




_____________________________________________

29 giu 2025, 06:30 da t.lee.davidson@xxxxxxxxx:

> On 6/28/25 10:26 AM, vuott@xxxxxxxxxxxx wrote:
>
>> Uhmmm... sorry, correct structure is:
>>
>> Public Struct SockAddr
>>    SinFamily As SHORT
>>    SinPort As SHORT
>>    SinAddr As Pointer
>> End Struct
>>
>> (with SHORT, not Integer)
>>
>
> Thank you. I tried it, and that doesn't work just a my code didn't work. No address number gets stuffed into the structure.
>
> I made a few changes in my own code, and with the following (including only the pertinent snippets):
> [code]
>
> Public Struct In_addr
>  s_addr As Integer
> End Struct
>
> Public Struct Sockaddr_in
>  sin_family As Short
>  sin_port As Short
>  sin_addr As Struct In_addr
> End Struct
>
> ' Now to Main() and,
> ' Of course create the socket already, then...
>
>  DestAddr = New Sockaddr_in
>  DestAddr.sin_family = AF_INET
>  DestAddr.sin_port = 4096
>  rc = inet_pton(AF_INET, "127.0.0.1", DestAddr.sin_addr)
>
>  For p As Integer = 0 To Object.SizeOf(DestAddr) - 1
>  Print "Offset:";; p, Byte@(Object.Data(DestAddr) + p), Hex(Byte@(Object.Data(DestAddr) + p))
>  Next
>
> [/code]
>
> This is the output:
> Offset: 0       2       2
> Offset: 1       0       0
> Offset: 2       0       0
> Offset: 3       16      10
> Offset: 4       0       0
> Offset: 5       0       0
> Offset: 6       0       0
> Offset: 7       0       0
> Offset: 8       127     7F
> Offset: 9       0       0
> Offset: 10      0       0
> Offset: 11      1       1
> Offset: 12      0       0
> Offset: 13      0       0
> Offset: 14      0       0
> Offset: 15      0       0
>
> Data at offsets 4-7 and 12-15 are extraneous bytes that seem to come from the ether. The ICMP message gets sent to "0.0.0.0" (offsets 4-7), which is nowhere, because that is where `sendto` looks for the address.
>
> If I comment out the "sin_addr" member in the Sockaddr_in structure, DestAddr is 8 bytes in size when, it seems to me, it should be only 4. Perhaps Object.SizeOf() is seeing the object as a pointer (8 bytes) instead of reporting the size of its structured data.
>
>
> -- 
> Lee
>
> --- Gambas User List Netiquette [https://gambaswiki.org/wiki/doc/netiquette] ----
> --- Gambas User List Archive [https://lists.gambas-basic.org/archive/user] ----
>
>


Follow-Ups:
Re: ICMP socket with Gambas - workingLee <t.lee.davidson@xxxxxxxxx>
Re: ICMP socket with Gambas - also workingLee <t.lee.davidson@xxxxxxxxx>
References:
Re: ICMP socket with GambasLee <t.lee.davidson@xxxxxxxxx>
Re: ICMP socket with GambasLinus <olivier.cruilles@xxxxxxxx>
Re: ICMP socket with GambasLee <t.lee.davidson@xxxxxxxxx>
Re: ICMP socket with Gambasvuott@xxxxxxxxxxxx
Re: ICMP socket with GambasLee <t.lee.davidson@xxxxxxxxx>