PDA

View Full Version : Get port from cli



pkfox
2016-01-18, 05:16
Hi all, anyone know if it's possible to retrieve the port LMS is listening on ( default being 9000 ) programmatically ?

bpa
2016-01-18, 05:26
Hi all, anyone know if it's possible to retrieve the port LMS is listening on ( default being 9000 ) programmatically ?

Players initially do a mulitcast broadcast of a UDP packet on Port 3483. All LMS servers listening reply with their IP address and the port to be used.

DJanGo
2016-01-18, 05:27
Hi all, anyone know if it's possible to retrieve the port LMS is listening on ( default being 9000 ) programmatically ?

Hi,

from "where"?
from lms itself its easy from any of the net is hard (you need a portscanner)

edit...
aeh?

Thread title says: Get port from cli
Thread itself "default 9000" thats the gui.

Since 9000 is std. and 9090 also but both can be changed i am not really sure what you want to know.

pkfox
2016-01-18, 05:36
Players initially do a mulitcast broadcast of a UDP packet on Port 3483. All LMS servers listening reply with their IP address and the port to be used.

Hi bpa, I'm trying to do this using C# so far I'm able to get the ip address correctly but don't see the correct port number - this is what I have


int UDPPort = 3483;
UdpClient listener = new UdpClient(UDPPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, UDPPort);
byte[] bytes = listener.Receive(ref groupEP);

The object groupEP contains the correct ip address but the port is 3483 - I'm obviously missing something here - thanks

pkfox
2016-01-18, 05:39
Hi,

from "where"?
from lms itself its easy from any of the net is hard (you need a portscanner)

edit...
aeh?

Thread title says: Get port from cli
Thread itself "default 9000" thats the gui.

Since 9000 is std. and 9090 also but both can be changed i am not really sure what you want to know.

Hi DJango please see my reply to bpa - thanks

bpa
2016-01-18, 05:43
Hi bpa, I'm trying to do this using C# so far I'm able to get the ip address correctly but don't see the correct port number - this is what I have


int UDPPort = 3483;
UdpClient listener = new UdpClient(UDPPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, UDPPort);
byte[] bytes = listener.Receive(ref groupEP);

The object groupEP contains the correct ip address but the port is 3483 - I'm obviously missing something here - thanks

Yes - the contents of the message telling the server what info you want

I don't know C# syntax try sending the server string 'eIPAD\0NAME\0JSON\0' where \0 is null.

bpa
2016-01-18, 05:49
Relevant dsicver server routine from squeezelite source in slimproto.c



in_addr_t discover_server(void) {
struct sockaddr_in d;
struct sockaddr_in s;
char *buf;
struct pollfd pollinfo;

int disc_sock = socket(AF_INET, SOCK_DGRAM, 0);

socklen_t enable = 1;
setsockopt(disc_sock, SOL_SOCKET, SO_BROADCAST, (const void *)&enable, sizeof(enable));

buf = "e";

memset(&d, 0, sizeof(d));
d.sin_family = AF_INET;
d.sin_port = htons(PORT);
d.sin_addr.s_addr = htonl(INADDR_BROADCAST);

pollinfo.fd = disc_sock;
pollinfo.events = POLLIN;

do {

LOG_INFO("sending discovery");
memset(&s, 0, sizeof(s));

if (sendto(disc_sock, buf, 1, 0, (struct sockaddr *)&d, sizeof(d)) < 0) {
LOG_INFO("error sending disovery");
}

if (poll(&pollinfo, 1, 5000) == 1) {
char readbuf[10];
socklen_t slen = sizeof(s);
recvfrom(disc_sock, readbuf, 10, 0, (struct sockaddr *)&s, &slen);
LOG_INFO("got response from: %s:%d", inet_ntoa(s.sin_addr), ntohs(s.sin_port));
}

} while (s.sin_addr.s_addr == 0 && running);

closesocket(disc_sock);

return s.sin_addr.s_addr;
}


edit:

The Perl file which processes the Discovery packet from player https://github.com/Logitech/slimserver/blob/public/7.9/Slim/Networking/Discovery.pm

pkfox
2016-01-18, 07:38
Yes - the contents of the message telling the server what info you want

I don't know C# syntax try sending the server string 'eIPAD\0NAME\0JSON\0' where \0 is null.

Hi I tried sending what you suggested and I receive a 1 byte array containg 'E'

bpa
2016-01-18, 08:22
Hi I tried sending what you suggested and I receive a 1 byte array containg 'E'

E is the correct response to an "'e" enquiry but usually there is more data.

What was the length of packet you sent ?
What is the length of the packet received ?

pkfox
2016-01-18, 08:42
E is the correct response to an "'e" enquiry but usually there is more data.

What was the length of packet you sent ?
What is the length of the packet received ?



bytes sent is 16, bytes received is 1

bpa
2016-01-18, 08:59
bytes sent is 16, bytes received is 1

You did broadcast the packet to 255.255.255.255 ?

The string is encoded as ASCII not UTF ?

pkfox
2016-01-18, 09:40
You did broadcast the packet to 255.255.255.255 ?

The string is encoded as ASCII not UTF ?

You have to send it as an array , I've done it in Java using a byte array like this



byte[] request = {
'e', // 'existence' ?
'I', 'P', 'A', 'D', 0, // Include IP address
'N', 'A', 'M', 'E', 0, // Include server name
'J', 'S', 'O', 'N', 0, // Include server port
};


But you can't do that in C# so I've tried



Char[] request = {
'e', // 'existence' ?
'I', 'P', 'A', 'D', '0', // Include IP address
'N', 'A', 'M', 'E','0', // Include server name
'J', 'S', 'O', 'N', '0', // Include server port
};


Which it seems to accept but maybe that's part of the problem

pkfox
2016-01-18, 09:54
You did broadcast the packet to 255.255.255.255 ?

The string is encoded as ASCII not UTF ?

You have to send it as an array , I've done it in Java using a byte array like this



byte[] request = {
'e', // 'existence' ?
'I', 'P', 'A', 'D', 0, // Include IP address
'N', 'A', 'M', 'E', 0, // Include server name
'J', 'S', 'O', 'N', 0, // Include server port
};


But yoU can't do that in C# so I've tried



Char[] request = {
'e', // 'existence' ?
'I', 'P', 'A', 'D', '0', // Include IP address
'N', 'A', 'M', 'E','0', // Include server name
'J', 'S', 'O', 'N', '0', // Include server port
};


Which it seems to accept but maybe that's part of the problem

pippin
2016-01-18, 10:03
bytes sent is 16, bytes received is 1

Are you sure that's the actual size and not just the size of the first string being returned?

bpa
2016-01-18, 10:12
Which it seems to accept but maybe that's part of the problem

I've tried this string in Perl, Javascript and Python (and squeezelite uses C) so either you're not reading all the chars received or the string sent is not correct.

Many langauge which support UTF may enacode them as 16 bit. Each char is 16 bit and also says length is number of 16 bit chars not 8 bit bytes.

An independent check would be to use wireshark.

Why don't you encode as ASCII to be sure ? this example seems to so ASCII encoding https://social.msdn.microsoft.com/Forums/en-US/baa3a5bb-2154-445f-965d-8a139dbe932a/c-udp-broadcast-send-and-receive?forum=netfxnetcom

bpa
2016-01-18, 13:30
If you're running a Linux or OSX server - you could edit the LMS Discovery.pm file and modify it to dump the message your application sends.

pkfox
2016-01-18, 23:30
I've tried this string in Perl, Javascript and Python (and squeezelite uses C) so either you're not reading all the chars received or the string sent is not correct.

Many langauge which support UTF may enacode them as 16 bit. Each char is 16 bit and also says length is number of 16 bit chars not 8 bit bytes.

An independent check would be to use wireshark.

Why don't you encode as ASCII to be sure ? this example seems to so ASCII encoding https://social.msdn.microsoft.com/Forums/en-US/baa3a5bb-2154-445f-965d-8a139dbe932a/c-udp-broadcast-send-and-receive?forum=netfxnetcom

Hi and thanks for your patience, im pretty sure it's the way im sending the string is the problem - I've got a few things to try now and will report back

pkfox
2016-01-19, 02:52
I've tried this string in Perl, Javascript and Python (and squeezelite uses C) so either you're not reading all the chars received or the string sent is not correct.

Many langauge which support UTF may enacode them as 16 bit. Each char is 16 bit and also says length is number of 16 bit chars not 8 bit bytes.

An independent check would be to use wireshark.

Why don't you encode as ASCII to be sure ? this example seems to so ASCII encoding https://social.msdn.microsoft.com/Forums/en-US/baa3a5bb-2154-445f-965d-8a139dbe932a/c-udp-broadcast-send-and-receive?forum=netfxnetcom


Success !!! here's what I did



int UDPPort = 3483;
UdpClient listener = new UdpClient(UDPPort);
IPEndPoint ReceiveIP = new IPEndPoint(IPAddress.Any, UDPPort);

// Notice I escape the 0 terminator.

Char[] request = {
'e',
'I', 'P', 'A', 'D', '\0',
'N', 'A', 'M', 'E', '\0',
'J', 'S', 'O', 'N', '\0',
};

Byte[] RequestData = Encoding.ASCII.GetBytes(request);

listener.Receive(ref ReceiveIP); // This populates ReceiveIP with the ip address of the server that responded.

int BytesSent = listener.Send(RequestData, RequestData.Length, ReceiveIP); // Now send our request.

byte[] BytesReceived = listener.Receive(ref ReceiveIP); // Get the response data ( "ENAME\bmax2playJSON9000" is returned in a byte array )
String RetVal = Encoding.ASCII.GetBytes(BytesReceived);

// The port number is all the digits following JSON which is easily parsed


thanks for your help.