GLBasic forum

Feature request => Network => Topic started by: Moebius on 2010-Sep-14

Title: SOCK_RECVIP - Possible?
Post by: Moebius on 2010-Sep-14
Such a function would be really useful - i.e. the IP address of the sender of the last message you used SOCK_RECV on.
Title: Re: SOCK_RECVIP - Possible?
Post by: Kitty Hello on 2010-Sep-14
If you got the socket from SOCK_CONNECT, you know the IP beforehand - just remember it.
If you got it from SOCK_TCPACCEPT, the 2nd parameter has the IP - also, just remember it.
Title: Re: SOCK_RECVIP - Possible?
Post by: Moebius on 2010-Sep-15
These commands will work for TCP, but not UDP.  If you need your program to respond to UDP messages, then there is currently no way to get the IP address of the sender.  I've brought this up before, and I'm simply embedding a string of IPs at the start of messages, but it would be easier to have something like SOCK_RECVIP, and this would allow GLBasic programs to communicate with others that send UDP messages.  Although this isn't terribly necessary, it would be nice to have it.  I'm not sure about how hard it is to implement though, and therefore if it's worth it.
Title: Re: SOCK_RECVIP - Possible?
Post by: Kitty Hello on 2010-Sep-15
I think there is no way to tell where a udp message came from.
Title: Re: SOCK_RECVIP - Possible?
Post by: Moebius on 2010-Sep-17
Exactly - surely the IP address of the sender must be in the header somewhere?
Title: Re: SOCK_RECVIP - Possible?
Post by: Kitty Hello on 2010-Sep-17
there's no header IIRC. You can browse the web to see if you find something usefull. I can implement that.
Title: Re: SOCK_RECVIP - Possible?
Post by: Moru on 2010-Sep-17
This one has some related stuff too:

http://gafferongames.com/networking-for-game-programmers/sending-and-receiving-packets/

And yes it should be possible to see where a packet came from even with UDP.
Title: Re: SOCK_RECVIP - Possible?
Post by: Moebius on 2010-Sep-18
I've looked up stuff regarding winsock.  I'm not sure what is used internally for networking in GLBasic, but Winsock seems to output a structure after receiving a UDP message which contains info (the 'recvfrom' structure is a 'sockaddr' structure, see http://msdn.microsoft.com/en-us/library/ms740496%28v=VS.85%29.aspx (http://msdn.microsoft.com/en-us/library/ms740496%28v=VS.85%29.aspx), which contains the IP address).

The 'recvfrom' function seems to be used in UDP (it says it is used for connectionless receiving) - see http://msdn.microsoft.com/en-us/library/ms740120%28v=VS.85%29.aspx (http://msdn.microsoft.com/en-us/library/ms740120%28v=VS.85%29.aspx)
This function outputs a sockaddr structure:
Code (glbasic) Select
int recvfrom(
  __in         SOCKET s,
  __out        char *buf,
  __in         int len,
  __in         int flags,
  __out        struct sockaddr *from,
  __inout_opt  int *fromlen
);


The 'recvfrom' function, or something similar seems to be used in GLBasic.  This function takes in a previously setup socket, a pointer to a buffer, a maximum length to read - sounds like the the GL function:
Code (glbasic) Select
SOCK_RECV(sock%,msg$,length%)

Anyway, if GLBasic does use Winsock, then the IP address from a received UDP message should be put in the specified 'sockaddr' structure.  However, I'm assuming it's probably a lot more complicated than that - Winsock doesn't exactly sound like a multiplatform thing  :D
I think that the majority of this post will probably be useless if GLBasic doesn't use winsock, and possibly if I've misunderstood stuff about winsock, but here are some links which should be relevant in any case:

The structure of 'pseudoheaders' - the source IP is included.  http://en.wikipedia.org/wiki/User_Datagram_Protocol#IPv4_PSEUDO-HEADER (http://en.wikipedia.org/wiki/User_Datagram_Protocol#IPv4_PSEUDO-HEADER)

If you scroll down to the section on UDP, you can see that there is a normal header, followed by the pseudoheader described in the wikipedia page (i think at least).  http://www.protocols.com/pbook/tcpip2.htm (http://www.protocols.com/pbook/tcpip2.htm)

Another link on the normal header and then IPv4 and IPv6 pseudoheaders.  http://www.networksorcery.com/enp/protocol/udp.htm (http://www.networksorcery.com/enp/protocol/udp.htm)

EDIT:  The links posted by Ocean and Moru also have this, I didn't notice until now :whistle:
Title: Re: SOCK_RECVIP - Possible?
Post by: Moru on 2010-Sep-19
Oh oh, I have always wanted ICMP, can we have that too while we are wishing? :-)
Title: Re: SOCK_RECVIP - Possible?
Post by: Moru on 2010-Sep-19
A support application. Istead of spelling out IPCONFIG, PING and TRACERT on the phone to confused customers that has problems with internet, I tell them to doubleclick the help_me.exe and tell me the result :-)

It's getting increasingly hard to explain to customers how to get to cmd.exe and I'm a bit tired of spending 30 minutes on this with people that just wants me to "fix internet" :-)

Would also be nice to write my own pingplotter :-)

Sadly it's not possible to harvest MAC adresses past the router but would like that too, if anyone knows how? :-)
Title: Re: SOCK_RECVIP - Possible?
Post by: Moru on 2010-Sep-19
Yes that's what I meant. But I have access to the right router for this need so that's not a problem, just need some time and access to the right computer. But still ICMP would be nice :-)
Title: Re: SOCK_RECVIP - Possible?
Post by: Kitty Hello on 2010-Sep-20
OK, I'll try to implement that for UDP then.
Title: Re: SOCK_RECVIP - Possible?
Post by: Moebius on 2010-Sep-22
Thanks so much  :nw:
Title: Re: SOCK_RECVIP - Possible?
Post by: Moru on 2011-Mar-30
Is it possible to see the originating IP-number and port of a UDP-packet yet? :-)

It is of course possible to send the IP with the packet but if the local computer does not know the external IP? I don't want to use external services to find out the IP since these don't have to be working all the time...
Title: Re: SOCK_RECVIP - Possible?
Post by: Kitty Hello on 2011-Mar-31
I have the code here. (commented :P)

Can you provide a quick UDP test example for me to test? Maybe one that receives from more PCs?
Title: Re: SOCK_RECVIP - Possible?
Post by: Moru on 2011-Apr-02
The date and version is old but I just tested it and it works :-)

Set it up on all computers you want to test, aim at the same IP. This IP will recieve all packets and sent to one of the other clients (the IP you set on that client).

Code (glbasic) Select
// --------------------------------- //
// Project: NetUDPThruRouter
// Start: Tuesday, September 15, 2009
// IDE Version: 7.104

// Works if you send a message from inside the firewall to the outside IP of the other client
// And then send a message from that client on the outside of the firewall to the inside.
// Both clients can be behind a firewall.


GLOBAL sock%               // The socket connection
GLOBAL port% = 15000       // Port number to use

LOCAL ok%, ip%, rv%, msg$
LOCAL myip$
LOCAL destip$
LOCAL timeout

myip$ = NETGETIP$()        // Get our local IP just for the show
log("Our IP: "+ myip$)

STDOUT "\nDestination IP: "
destip$ = STDIN$()
// Just for less typing when testing
IF destip$ = "" THEN destip$ = "0.0.0.0" // <---- Fill in default IP here

ok = SOCK_INIT()    // Init network
IF ok
    sock = SOCK_UDPOPEN(port)    // Get the socket so we can send/recieve on the port
    IF sock <> -1
        ip = SOCK_GETIP(destip$) // Convert the string to an integer IP
        // Send 32 packets, waiting one second for an answer between each send
        FOR n = 0 TO 31
            log("Sending message: "+"Hello from "+myip$+" To: "+destip$)
            ok = SOCK_UDPSEND(sock, "Hello from "+myip$, ip, port)
            IF ok <> -1
                log("message sent with "+ok+" bytes")
                timeout = GETTIMERALL() + 1000      // Start timer for one second
                WHILE rv <> -1 AND GETTIMERALL() < timeout
                    rv = SOCK_RECV(sock, msg$, 999)
                    IF rv>0 THEN log("message recieved: ["+msg$+"]")
                    IF rv=-1
                        log(NETGETLASTERROR$())     // Didn't work, tell user why
                        SOCK_CLOSE(sock)
                    ENDIF
                WEND
            ELSE
                log(NETGETLASTERROR$())
            ENDIF
        NEXT
    ELSE
        log(NETGETLASTERROR$())
    ENDIF
ELSE
    log(NETGETLASTERROR$())
ENDIF
KEYWAIT



FUNCTION log: str$
    STDOUT "\n"+str$
ENDFUNCTION