OctoPrint-TPLinkSmartplug icon indicating copy to clipboard operation
OctoPrint-TPLinkSmartplug copied to clipboard

Use MAC addr option

Open ikishk opened this issue 5 years ago • 18 comments

The IP changes on reboot at times, the MAC addr doesnt. These tplink devices broadcast all the time, so the system would have it in the arp table.

ikishk avatar Nov 29 '18 03:11 ikishk

Have you considered reserving the ip address in your router? That's what I do to insure it's always the same.

jneilliii avatar Nov 29 '18 03:11 jneilliii

that's a possibility for most... but if you think about it.. the kasa app only shows you the MAC, the box you got it in has the MAC, the sticker has the MAC... best way to find the ip is to grep the mac from the arp table. if there was a radio/check/etc to use MAC to populate the ip, all you have to do is arp -na|grep $mac and populate the ip automatically.

quick dirty snippet from a perl script i use via cron (only relevant stuff, i use JSON for other things):

open(ARP, "arp -n|") || die "Failed $!\n"; @arp = <ARP>; close ARP;

@devices = ( { 'alias' => '3d printer', 'deviceMac' => '50C7BF747BF5', 'deviceModel' => 'HS110(US)'}, }

foreach $device (@devices) { $encoded = $j->encode($device); $decoded = $j->decode($encoded); $mac = $decoded->{'deviceMac'}; foreach $arp (@arp) { if ($_ =~ m/incomplet/) {next;} if ($_ =~ m/Address/) {next;} @line = split(/\s+/,$arp); $ip = $line[0]; $cmac = $line[2]; $cmac =~ s/://g; $cmac = uc $cmac; if ($mac eq $cmac) { $tpip = $ip; } } }

ikishk avatar Nov 29 '18 03:11 ikishk

This issue has been automatically marked as stale because it has not had activity in 14 days. It will be closed if no further activity occurs in 7 days.

stale[bot] avatar Dec 13 '18 04:12 stale[bot]

I really need this too. I recently moved from AT&T to Spectrum internet and the new router has absolutely no user facing options for controlling DHCP addresses or anything. I could in my previous router, but not with this new one. And I can't even set a static IP address on the device because I don't have any guarantees about the IP range this router may assign out. On the upside, my internet speeds at 20 times as fast and it's about half the price, so I'm not going back.

jgrills avatar Apr 18 '20 21:04 jgrills

I haven't found a good way to do this yet in python. If anyone has any ideas I'd be glad to integrate it.

jneilliii avatar Apr 18 '20 21:04 jneilliii

scapy

https://pypi.org/project/scapy/

On Sat, Apr 18, 2020, 16:12 jneilliii [email protected] wrote:

I haven't found a good way to do this yet in python. If anyone has any ideas I'd be glad to integrate it.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/issues/76#issuecomment-615950301, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANVMCB6E2UDNUC32QCUTC3RNIJSHANCNFSM4GHDMR2Q .

ikishk avatar Apr 18 '20 21:04 ikishk

I used to be a network administrator way back in the early 90's. So from a shell on my octopi, I've managed to be able to map that MAC address to an IP address by finding the broadcast address and pinging it first, ensuring the TP device is in the ARP cache.

ip addr show <interface> where interface is eth0 for me, and you get <broadcast_address> ping -c 5 -b <broadcast_address> ip neigh show | grep -i <mac_address>

For implementing it in python, I see two choices. The first would be to use the subprocess module of python to invoke these utils like they are. You could go down to the socket layer, but I wouldn't recommend that approach.

jgrills avatar Apr 18 '20 21:04 jgrills

Thanks both for the responses. I did find a method that uses the arp command with a grep to search for specific mac using subprocess, but I'm going to look into scapy as that would probably be a more reliable cross platform solution.

jneilliii avatar Apr 18 '20 22:04 jneilliii

An arp | grep solution would be equivalent to the ip neigh show | grep line I provided, and also is the same fundamental technique as suggested all the way back in the second comment https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/issues/76#issuecomment-442698014 - the solution suggested there was the perl equivalent of using subprocess to run arp, and finding the right IP from the mac address by processing the text output, which is simple in either perl or python.

Anyway, the major difference is that I wasn't finding my HS107 device in the arp cache, so I had to add the first two steps, to get the broadcast and ping it, to populate the arp cache. Otherwise arp results did not include my HS107 device with its IP and MAC addresses.

I didn't much look into scapy, but it clearly indicated it was usable as a library too. It looks like it should be able to handle it too.

jgrills avatar Apr 18 '20 23:04 jgrills

broadcast ping, arp, grep is the easiest system command way... but most devs try and avoid system commands for efficiency/security issues... why i found scapy :)

On Sat, Apr 18, 2020, 18:24 Jeff Grills [email protected] wrote:

An arp | grep solution would be equivalent to the ip neigh show | grep line I provided, and also is the same fundamental technique as suggested all the way back in the second comment #76 (comment) https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/issues/76#issuecomment-442698014

  • the solution suggested there was the perl equivalent of using subprocess to run arp, and finding the right IP from the mac address by processing the text output, which is simple in either perl or python.

Anyway, the major difference is that I wasn't finding my HS107 device in the arp cache, so I had to add the first two steps, to get the broadcast and ping it, to populate the arp cache. Otherwise arp results did not include my HS107 device with its IP and MAC addresses.

I didn't much look into scapy, but it clearly indicated it was usable as a library too. It looks like it should be able to handle it too.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/issues/76#issuecomment-615977440, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANVMCHYESBEQGAJJTNOUSDRNIZDPANCNFSM4GHDMR2Q .

ikishk avatar Apr 18 '20 23:04 ikishk

So just some quick tests with scapy and I'm able to output the ip address from mac, but can't seem to figure out how to assign it to a variable in python to use it. This is what I was able to use to get the ip back of one of my plugs.

from scapy.all import ARP, Ether, srp
ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.0.0/24"),timeout=2)
ip = ans.summary( lfilter = lambda(s,r): r[ARP].hwsrc == "50:c7:bf:6a:6c:83",prn = lambda(s,r): r[ARP].psrc )

It prints out the IP address to the console but ip variable gets assigned as a NoneType. @ikishk have you used scapy in python and know a quick way to get the results I'm able to list with the above summary into a variable? I'm having a hard time dissecting their documentation.

Not sure if the scapy approach would resolve your arp cache issue @jgrills or not.

jneilliii avatar Apr 18 '20 23:04 jneilliii

I'm a perl guy, sorry :(  I can try and play with it later tonight.

⁣--- Sent from some ballistic thermoconductive tempered glass.  Please excuse my brevity. ​

On Apr 18, 2020, 18:40, at 18:40, jneilliii [email protected] wrote:

So just some quick tests with scapy and I'm able to output the ip address from mac, but can't seem to figure out how to assign it to a variable in python to use it. This is what I was able to use to get the ip back of one of my plugs.

from scapy.all import ARP, Ether, srp
ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.0.0/24"),timeout=2)
ip = ans.summary( lfilter = lambda(s,r): r[ARP].hwsrc ==
"50:c7:bf:6a:6c:83",prn = lambda(s,r): r[ARP].psrc )

It prints out the IP address to the console but ip variable gets assigned as a NoneType. @ikishk have you used scapy in python and know a quick way to get the results I'm able to list with the above summary into a variable? I'm having a hard time dissecting their documentation.

Not sure if the scapy approach would resolve your arp cache issue @jgrills or not.

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/issues/76#issuecomment-615980771

ikishk avatar Apr 18 '20 23:04 ikishk

I think I got it working. Will require some additional tweaking to add error checking and integrate it into the plugin, but at least I'm getting the ip address now. You have to provide it with the network (pdst=192.168.0.0/24) and mac address to search for (50:c7:bf:6a:6c:83).

from scapy.all import ARP, Ether, srp
ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.0.0/24"),timeout=2)
ip = ans.filter(lambda(s,r): r[ARP].hwsrc == "50:c7:bf:6a:6c:83")[0][1][1].psrc

Edit: Will potentially need sudo permissions in raspbian environment to function.

jneilliii avatar Apr 19 '20 01:04 jneilliii

i wouldnt assume /24 (or 192.168.x.x for that matter). maybe https://pypi.org/project/netifaces/ to pull the ip/netmask then convert that to bit for scapy?

On Sat, Apr 18, 2020 at 8:58 PM jneilliii [email protected] wrote:

I think I got it working. Will require some additional tweaking to add error checking and integrate it into the plugin, but at least I'm getting the ip address now. You have to provide it with the network (pdst= 192.168.0.0/24) and mac address to search for (50:c7:bf:6a:6c:83).

from scapy.all import ARP, Ether, srp ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.0.0/24"),timeout=2) ip = ans.filter(lambda(s,r): r[ARP].hwsrc == "50:c7:bf:6a:6c:83")[0][1][1].psrc

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/issues/76#issuecomment-616005757, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANVMCFIW7TVDUVNSTHCXATRNJLDJANCNFSM4GHDMR2Q .

ikishk avatar Apr 19 '20 04:04 ikishk

Yeah, that would be my approach, limiting the search in some way.

jneilliii avatar Apr 19 '20 05:04 jneilliii

I'd happily enter a broadcast address into the plugin if you don't want to start off detecting it. There's also the possibility that multiple interfaces are active with different networks.

Oh, and I finally found an option in my managed switch to filter DHCP messages (it was command line only and wasn't in the GUI), so I've filtered off the annoying DHCP server that kept updating my IPs and now I'm using the DHCP server in my DD-WRT wireless router instead. I'll be able to lock down all my wifi IOT devices to non-changing IPs in the DHCP server if I want.

jgrills avatar Apr 28 '20 19:04 jgrills

I would love to see this. I have an issue that my DHCP swap always once a day the ip adress. Iam not in an home Network. I use this for business... (trainees can work with the printer)

Appa1990 avatar Jul 07 '21 06:07 Appa1990

I'd like this option as well.

b-morgan avatar Jul 16 '22 22:07 b-morgan