want to get mac address of remote PC - python

I have my web page in python, I am able to get the IP address of the user, who will be accessing our web page, we want to get the mac address of the user's PC, is it possible in python, we are using Linux PC, we want to get it on Linux.

I have a small, signed Java Applet, which requires Java 6 runtime on the remote computer to do this. It uses the getHardwareAddress() method on NetworkInterface to obtain the MAC address. I use javascript to access a method in the applet that calls this and returns a JSON object containing the address. This gets stuffed into a hidden field in the form and posted with the rest of the fields.

from Active code
#!/usr/bin/env python
import ctypes
import socket
import struct
def get_macaddress(host):
""" Returns the MAC address of a network host, requires >= WIN2K. """
# Check for api availability
try:
SendARP = ctypes.windll.Iphlpapi.SendARP
except:
raise NotImplementedError('Usage only on Windows 2000 and above')
# Doesn't work with loopbacks, but let's try and help.
if host == '127.0.0.1' or host.lower() == 'localhost':
host = socket.gethostname()
# gethostbyname blocks, so use it wisely.
try:
inetaddr = ctypes.windll.wsock32.inet_addr(host)
if inetaddr in (0, -1):
raise Exception
except:
hostip = socket.gethostbyname(host)
inetaddr = ctypes.windll.wsock32.inet_addr(hostip)
buffer = ctypes.c_buffer(6)
addlen = ctypes.c_ulong(ctypes.sizeof(buffer))
if SendARP(inetaddr, 0, ctypes.byref(buffer), ctypes.byref(addlen)) != 0:
raise WindowsError('Retreival of mac address(%s) - failed' % host)
# Convert binary data into a string.
macaddr = ''
for intval in struct.unpack('BBBBBB', buffer):
if intval > 15:
replacestr = '0x'
else:
replacestr = 'x'
macaddr = ''.join([macaddr, hex(intval).replace(replacestr, '')])
return macaddr.upper()
if __name__ == '__main__':
print 'Your mac address is %s' % get_macaddress('localhost')

All you can access is what the user sends to you.
MAC address is not part of that data.

The dpkt package was already mentioned on SO. It allows for parsing TCP/IP packets. I have not yet used it for your case, though.

Related

How to access a different/remote Windows machine using Python?

I am currenlty using machine A and I am trying to access machine B via Python to copy files from machine B to machine A.
I have already tried the methods explained here How to connect to a remote Windows machine to execute commands using python? , but with no luck as I cannot manage to even get access to the remote machine.
I am open to other solutions, even better if using Python 3+.
Here is an example of the code in use.
ip = r'\\IP.IP.IP.IP'
username = r'AccountUserName'
password = r'AccountPassword'
# -------------------------------- with win32net
import win32net
import win32file
data = {
'remote': r'\\IP.IP.IP.IP\C$',
'local': 'C:',
'username': username,
'password': password
}
win32net.NetUseAdd(None, 2, data)
# -------------------------------- with wmi
import wmi
from socket import *
try:
print ("Establishing connection to %s" %ip)
connection = wmi.WMI(ip, user=username, password=password )
print ("Connection established")
except wmi.x_wmi:
print ("Your Username and Password of "+getfqdn(ip)+" are wrong.")
Using the win32net method
According to the documentation here https://learn.microsoft.com/en-us/windows/win32/api/lmuse/nf-lmuse-netuseadd
If the function is to be run from the same computer the script is running from (A), then the first parameter f NetUseAdd can be left to NONE, but with that I get the error
pywintypes.error: (87, 'NetUseAdd', 'The parameter is incorrect.')
Whilst if I change it with "127.0.0.1" I get the error
pywintypes.error: (50, 'NetUseAdd', 'The request is not supported.')
And lastly, if I change it with the same IP that I am trying to access I get the error
pywintypes.error: (1326, 'NetUseAdd', 'Logon failure: unknown user name or bad password.')
Using the wmi method
It gives the error
Your Username and Password of \\IP.IP.IP.IP are wrong.
There can be multiple ways to achieve this. One of them is given below which makes use of inbuilt windows utilities.
import os
machine_b = {"ip":"10.197.145.244","user":"administrator","pwd":"abc1234"}
src = r"C:\Temp" # folder to copy from remote machine
dest = r"C:\Python27\build\temp" # destination folder on host machine
network_drive_letter = "Z:"
source_driver_letter = os.path.splitdrive(src)[0][0]
cmd = "netuse %s \\%s\%s$ %s /u:%s"%(network_drive_letter, machine_b["ip"],source_driver_letter,machine_b["pwd"],machine_b["user"])
os.system(cmd)
cmd = "robocopy %s %s /mir"%(src.replace(source_driver_letter,network_drive_letter),dest)
os.system(cmd)
You can improve this code by handling exceptions and replacing os.system with subprocess.Popen calls.
Note: Be careful with /MIR switch as it can copy as well as delete files in the host machine. It creates mirror of destination folder.

Windows alternative of this python script for linux to get IP from URL

I am very new to Python. So in newboston's latest python tutorial Im making a web crawler. This Python script however only works on Linux. What would be the windows alternative to the following code?
import os
def get_ip_address(url):
command = "host " + url
process = os.popen(command)
results = str(process.read())
marker = results.find('has address') + 12
return results[marker:].splitlines()[0]
print(get_ip_address('google.com'))
I want it in the same format as I want to code multiple modules(i.e. get ip, who is etc.) and put them together as one Python program.
I am trying to obtain ONLY the ip address and nothing else in the results.
Alternatively, This is what I have for Windows so far:
import socket
def get_ips_for_host(url):
try:
ips = socket.gethostbyname_ex(url)
except socket.gaierror:
ips = []
return ips
ips = get_ips_for_host('www.facebook.com')
print(repr(ips))
How can i modify it to make it get only the IP address?
Similarly how can I get the nmap scan and the 'who is'?
the_ip = get_ips_for_host('www.facebook.com')[-1][0]

Checking user's network environment - Python application

My Python application connects to a MSSQL database to verify some matter numbers, but this step is only necessary to assist with data integrity and does not bring the user any additional functionality.
The database is only accessible when on my office's local network. How do I check a user's environment during startup to see if this connection can be made?
I'm using pyodbc, but I also need this program to work on OS X, so I'm not importing that module until this check returns a positive result. Any ideas?
You could try something like this:
#!/usr/bin/python
import socket
mssql_server = 'foobar.example.not' # set this to your own value
s = socket.socket()
s.settimeout(3)
try:
server = [x for x in socket.getaddrinfo(mssql_server,1433) if x[0]==2 ][0][-1]
except socket.gaierror:
server = None
if server:
try:
s.connect(server)
except (socket.timeout, socket.error):
server = None
s.close()
... this should attempt to find an IPv4 address for your server (using the first one returned by getaddrinfo()) and then attempt to connect to the MS SQL TCP port (1433 by default) on that system. (Yes, change 1433 if your server is on a different port). If there's a timeout or any other socket error reported on the attempt, then server is set to None. Otherwise you probably have an MS SQL server that you could access.
Verify the host is available using ping before import:
import subprocess
host = "<hostname>"
# add sample text for ping resolution errors here
errors = ("could not find", "unreachable")
ping = "ping {0}".format(host)
(stdout, stderr) = subprocess.Popen(ping, stdout=subprocess.PIPE).communicate()
# stdout is a byte string and must be decoded before compare
if not any(error in stdout.decode("utf-8") for error in errors):
import pyodbc
.....

How to find if the user have entered hostname or IP address?

The user will input either hostname or the IP address. If the user enters the IP address, I want to leave as it is but if the user enters the hostname I want to convert it into IP address using the following method:
def convert(hostname):
command = subprocess.Popen(['host', hostname],
stdout=subprocess.PIPE).communicate()[0]
progress1 = re.findall(r'\d+.', command)
progress1 = ''.join(progress1)
return progress1
How do I do it?
To get ip whether input is ip or hostname:
ip4 = socket.gethostbyname(ip4_or_hostname)
you can use a regex to match your input and test if it is a ip address or not
test = re.compile('\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b')
result = test.match(hostname)
if not result:
# no match -> must be an hostname #
convert(hostname)
that regex allows invalid ip addresses (like 999.999.999.999) so you may want to tweak it a bit, it's just a quick example
There are a number of questions on stackoverflow already about validating an IP address.
IP Address validation in python
Validating IP Addresses in python
I would like to ask why you are communicating with a subprocess when you can do this within the standard python library.
I would recommend resolving a host name into a IP address by using some of pythons built in functionality.
You can do this by importing and using the python sockets library
For example using the code found in link 1:
import socket
import re
regex = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
result = regex.match(address)
if not result:
address = socket.gethostbyname(address)
In my case, host name can only contain - as a separator. So you can uncomment and use it according to your requirement.
import re
regex = "^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"
# string_check= re.compile('[#_!#$%^&*()<>?/\|}{~:.]')
string_check= re.compile('[-]')
ip_host_detail = {}
def is_valid_hostname_ip(IpHost):
# pass regular expression and ip string into search() method
if (re.search(regex, IpHost)):
print("Valid Ip address")
ip_host_detail['is_ip'] = 'True'
ip_host_detail['is_hostname'] = 'False'
return True
elif(string_check.search(IpHost)):
print("Contain hostname")
ip_host_detail['is_hostname'] = 'True'
ip_host_detail['is_ip'] = 'False'
return True
else:
print("Invalid Ip address or hostname:- " + str(IpHost))
ip_host_detail['is_hostname'] = 'False'
ip_host_detail['is_ip'] = 'False'
return False
IpHost = sys.argv[1]
# IpHost = 'RACDC1-VM123'
is_valid_hostname_ip(IpHost)
print(ip_host_detail)

Determine IP address of CONNECTED interface (linux) in python

On my linux machine, 1 of 3 network interfaces may be actually connected to the internet. I need to get the IP address of the currently connected interface, keeping in mind that my other 2 interfaces may be assigned IP addresses, just not be connected.
I can just ping a website through each of my interfaces to determine which one has connectivity, but I'd like to get this faster than waiting for a ping time out. And I'd like to not have to rely on an external website being up.
Update:
All my interfaces may have ip addresses and gateways. This is for an embedded device. So we allow the user to choose between say eth0 and eth1. But if there's no connection on the interface that the user tells us to use, we fall back to say eth2 which (in theory) will always work.
So what I need to do is first check if the user's selection is connected and if so return that IP. Otherwise I need to get the ip of eth2. I can get the IPs of the interfaces just fine, it's just determining which one is actually connected.
If the default gateway for the system is reliable, then grab that from the output from route -n the line that contains " UG " (note the spaces) will also contain the IP of the gateway and interface name of the active interface.
the solution is here : http://code.activestate.com/recipes/439093-get-names-of-all-up-network-interfaces-linux-only/
import fcntl
import array
import struct
import socket
import platform
"""
global constants. If you don't like 'em here,
move 'em inside the function definition.
"""
SIOCGIFCONF = 0x8912
MAXBYTES = 8096
def localifs():
"""
Used to get a list of the up interfaces and associated IP addresses
on this machine (linux only).
Returns:
List of interface tuples. Each tuple consists of
(interface name, interface IP)
"""
global SIOCGIFCONF
global MAXBYTES
arch = platform.architecture()[0]
# I really don't know what to call these right now
var1 = -1
var2 = -1
if arch == '32bit':
var1 = 32
var2 = 32
elif arch == '64bit':
var1 = 16
var2 = 40
else:
raise OSError("Unknown architecture: %s" % arch)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * MAXBYTES)
outbytes = struct.unpack('iL', fcntl.ioctl(
sock.fileno(),
SIOCGIFCONF,
struct.pack('iL', MAXBYTES, names.buffer_info()[0])
))[0]
namestr = names.tostring()
return [(namestr[i:i+var1].split('\0', 1)[0], socket.inet_ntoa(namestr[i+20:i+24])) \
for i in xrange(0, outbytes, var2)]
print localifs()

Categories

Resources