Bug 10184 - Add Server's MAC address to server discovery packets or add query for it
: Add Server's MAC address to server discovery packets or add query for it
Status: NEW
Product: Logitech Media Server
Classification: Unclassified
Component: Misc
: 7.4.0
: PC Other
: -- enhancement (vote)
: Future
Assigned To: Felix Mueller
: ipeng
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-12-01 06:19 UTC by Joerg Schwieder
Modified: 2010-01-20 11:06 UTC (History)
1 user (show)

See Also:
Category: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joerg Schwieder 2008-12-01 06:19:34 UTC
I am trying to implement WOL on iPeng, but I seem to be unable to figure out a way to determine a server's MAC-Address on iPhone, all the routing APIs have been removed from the kernel there.

Right now, I will let the user enter the address, but that's a fudge.

Would it be possible for the server to return it's MAC?
preferably the MAC of the NIC through which the communication happens (that's probably also the easiest solution), alternatively a list of all MACs.
Comment 1 Blackketter Dean 2008-12-01 07:21:19 UTC
Felix: have any advice for Joerg on implementing WOL as SB does?
Comment 2 Felix Mueller 2008-12-02 11:16:18 UTC
SBC and SB currently check the ARP cache.
Comment 3 Joerg Schwieder 2008-12-02 11:27:17 UTC
Yes, that's what I tried, too. The problem is, all APR related IOCTL code got removed from the kernel on iPhone. We also tried packet sniffing for APR tables and evelyating the routing table. Same result.

I will continue to try to find ways to get hold of packets but I'm running out of ideas right now, don't have too much experience with this low level stuff.

Hence this enhancement request.
Comment 4 Gordon Harris 2010-01-20 11:06:30 UTC
Here is perl code so that the server can return the mac address.  On windows, it calls ipconfig /all.  On linux & osx, it calls ifconfig -a.  On SqueezeOS, it uses IOCTL calls.

# Adapted from python code at from: http://code.activestate.com/recipes/439094/
sub IOCTLGetMacAddress {
	my $interface = shift || "eth0";

	socket(my $socket, AF_INET, SOCK_DGRAM, 0);
	my $buf  = pack("a256", $interface);
	# SIOCGIFHWADDR == 0x8927
	ioctl($socket, 0x8927, $buf);
	close($socket);
	my $macstr = sprintf("%s%s:%s%s:%s%s:%s%s:%s%s:%s%s",split('',uc unpack("H12",substr($buf, 18, 6))));
	return $macstr;
}

my $max_addrs = 30;

# Adapted from http://www.perlmonks.org/?node_id=53660
sub IOCTLGetInterfaces {
	my %interfaces;
	socket(my $socket, AF_INET, SOCK_DGRAM, 0); # or die "socket: $!";
	{
		my $ifreqpack = 'a16a16';
		my $buf = pack($ifreqpack, '', '') x $max_addrs;
		my $ifconf = pack('iP', length($buf), $buf);

		#SIOCGIFCONF == 0x8912
		ioctl($socket, 0x8912, $ifconf);

		my $len = unpack('iP', $ifconf);
		substr($buf, $len) = '';

		%interfaces = unpack("($ifreqpack)*", $buf);

		unless (keys(%interfaces) < $max_addrs) {
			# Buffer was too small
			$max_addrs += 10;
			redo;
		}
	}

	for my $addr (values %interfaces) {
		$addr = inet_ntoa((sockaddr_in($addr))[1]);
	}

	my @nics;
	my $interfaceMAC;

	while( my ($interfaceName, $interfaceIP) = each %interfaces ) {
		#truncate the interface name..
		substr($interfaceName, index($interfaceName, chr(0))) = '';
		$interfaceMAC = IOCTLGetMacAddress ($interfaceName);
		push ( @nics, {
			interfaceName => $interfaceName,
			interfaceMAC  => $interfaceMAC,
			interfaceIP   => $interfaceIP,
		});
	}

	return @nics;
}


sub GetServerMacAddress {

	#If TinySC, don't make a system call..
	if ( defined( &Slim::Utils::OSDetect::isSqueezeOS ) && Slim::Utils::OSDetect::isSqueezeOS() ) {
		my $my_ip = Slim::Utils::Network::serverAddr();
		my @interfaces = IOCTLGetInterfaces();

		foreach my $interface (@interfaces) {
			if ( $my_ip eq  $interface->{interfaceIP} ) {
				return $interface->{interfaceMAC};
			}
		}
		return 'UNKNOWN';
	}

	my $serverMAC;

	if ($^O =~ /^m?s?win/i) {		## Windows?
		$serverMAC = `ipconfig /all`;
	} else {						## Everything else..
		$serverMAC = `ifconfig -a`;
		#$serverMAC = IOCTLGetMacAddress();
	}

	if ( $serverMAC =~ /((?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2})/i ) {
		$serverMAC = $1;
		$serverMAC =~ s/\-/\:/g ;	## Windows ipconfig formats MAC as aa-bb-cc-dd-ee-ff
		return $serverMAC;
	}

	return 'UNKNOWN';
}