I successfully create a socket handle with
createNativeSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, false)
according to the documentation this creates a socket, but looking at the source this is just a handle.
I want to use the created socket, but how do I do that? Instead of just using the handle?
So, for instance if a proc needs a Socket and not a SocketHandle, what should I do if I want to use createNativeSocket?
For example:
import std/[nativesockets,net,os]
type
INNER_C_STRUCT_ping_24* {.bycopy.} = object
id*: uint16
sequence*: uint16
INNER_C_STRUCT_ping_30* {.bycopy.} = object
unused*: uint16
mtu*: uint16
INNER_C_UNION_ping_22* {.bycopy, union.} = object
echo*: INNER_C_STRUCT_ping_24 ## echo datagram
gateway*: uint32 ## gateway address
frag*: INNER_C_STRUCT_ping_30 ## path mtu discovery
icmphdr* {.bycopy.} = object
`type`*: uint8 ## message type
code*: uint8 ## type sub-code
checksum*: uint16
un*: INNER_C_UNION_ping_22
proc checksum(x: openArray[uint16]):uint16 =
var sum:int32
for a in x:
sum += (int32)a
sum = (sum shr 16) + (sum and 0xffff)
sum += (sum shr 16)
return (uint16)(not sum)
proc ping() =
var nsent{.global.}:uint16
inc nsent
var icp = cast[ptr icmphdr](alloc0(56))
icp.`type` = 8
icp.un.echo.id = 1
icp.un.echo.sequence = htons(nsent)
icp.checksum = checksum(cast[array[sizeof(icp) div 2,uint16]](icp))
let sockhand = createNativeSocket(AF_INET,SOCK_DGRAM,IPPROTO_ICMP)
var sockadd: SockAddr
var socklen: SockLen
toSockAddr(parseIPAddress("127.0.0.1"),Port(0),cast[var Sockaddr_storage](sockadd.addr),socklen)
discard sockhand.sendto(icp,56,0,sockadd.addr,socklen)
for i in 0..10:
ping()
sleep(1000)
Looks good! Do you know why the checksum fails if you change the socket to raw?
So SOCK_DGRAM -> SOCK_RAW
it's not the checksum, (although that code is buggy: it wont work for non-zero ping data or for non-power of two packet lengths)
should say i'm working on linux so maybe there are differences there.
the problem for me was that creating a raw socket requires root permissions. otherwise createNativeSocket(AF_INET,SOCK_RAW,IPPROTO_ICMP) returns -1, aka osInvalidSocket