indexing output of linux command in c++ - c++

I want to get the ip address given url.
I am currently using this
std::string i;
std::string pingStr = (std::string)"nslookup " +"www.yahoo.com" ;
i = system (pingStr.c_str());
but the output is
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
www.yahoo.com canonical name = atsv2-fp-shed.wg1.b.yahoo.com.
Name: atsv2-fp-shed.wg1.b.yahoo.com
Address: 106.10.250.10
Q: Is there anyway I can only get the Ip address?

Use the getaddrinfo(3) function to look up IP addresses, IPv4 or IPv6, in usable form.

you can use the folowing command.
nslookup www.yahoo.com | grep Address: | sed -n 2p
grep Address gives you all lines having "address" word in them
sed gets the 2nd line of those 2
You can truncate the "Address" part of output in c++.

Related

How to get the specific content from the log file described bellow?

I Have a log file which is generated by nmap, which is something like this:
Nmap scan report for gateway (10.0.0.1)
Host is up (0.0060s latency).
MAC Address: 10:BE:F5:FC:9C:65 (D-Link International)
Nmap scan report for 10.0.0.2
Host is up (0.055s latency).
MAC Address: 7C:78:7E:E8:1C:2A (Samsung Electronics)
Nmap scan report for 10.0.0.3
Host is up (0.059s latency).
MAC Address: 54:60:09:83:6E:B6 (Google)
Nmap scan report for 10.0.0.200
Host is up (-0.093s latency).
MAC Address: 5C:B9:01:02:5F:D8 (Hewlett Packard)
Nmap scan report for manoj-notebook (10.0.0.4)
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 16.84 seconds
It keeps on changing as the new devices connect to the network or existing device disconnects from the network. I want to fetch the ip address example: 10.0.0.1, mac address example: 10:BE:F5:FC:9C:65 and the device name example: D-Link International in a single list something like:
result = [['10.0.0.1', '10.0.0.2', '10.0.0.3', '10.0.0.200', '10.0.0.4'], ['10:BE:F5:FC:9C:65', '7C:78:7E:E8:1C:2A', '54:60:09:83:6E:B6', '5C:B9:01:02:5F:D8'], ['D-Link International', 'Samsung Electronics', 'Google', 'Hewlett Packard']]
I tried the following regular expression to match IP address, MAC Address and Device name:
ipPattern = re.findall(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', temp)
macPattern = re.findall(r'(?:.*?s: ){2}(.*)(?= \))', temp)
devicePattern = re.findall(r'(?:.*?\(){2}(.*)(?=\))', temp)
I'm able to match the IP Address but unable to match mac address and device name. How to match the same and store it in a single list? Thank you.
Also if I could get a pattern to fetch latency from the log file example: 0.0060s it would be a cherry on top. Thank you.
You can use the following expressions:
ipPattern : \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
macPattern : (?:[0-9A-F]{2}:){2,}[0-9A-F]{2}\b
(?:[0-9A-F]{2}:)+ Non capturing group for sequence of pairs of alphanumerical values followed by :.
[0-9A-F]+\b Final pair of alphanumerical value, followed by word boundary.
devicePattern : (?<=\()[^)0-9.]*(?=\))
(?<=\() Negative lookbehind for bracket ).
[^)0-9.]* Negated character set, matches anything that is not a ) or . or digits.
(?=\)) Positive lookahead for ).
latency : -?\d+\.\d+s(?=\slatency)
-?\d+\.\d+s Match - optionally, digits, full stop, more digits and s.
(?=\slatency) Positive lookahead, assert that what follows whitespace and latency.
Python snippet:
import re
import itertools
temp = """
b'\nStarting Nmap 7.60 ( https://nmap.org ) at 2018-08-03 19:44 IST\nNmap scan report for gateway (10.0.0.1)\nHost is up (0.0070s latency).\nMAC Address: 10:BE:F5:FC:9C:65 (D-Link International)\nNmap scan report for 10.0.0.3\nHost is up (0.11s latency).\nMAC Address: 54:60:09:83:6E:B6 (Google)\nNmap scan report for 10.0.0.5\nHost is up (0.11s latency).\nMAC Address: 7C:78:7E:A4:73:8C (Samsung Electronics)\nNmap scan report for 10.0.0.200\nHost is up (0.027s latency).\nMAC Address: 5C:B9:01:02:5F:D8
"""
ipPattern = re.findall(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b', temp)
macPattern= re.findall(r'(?:[0-9A-F]{2}:){2,}[0-9A-F]{2}\b',temp)
devicePattern = re.findall(r'(?<=\()[^)0-9.]*(?=\))',temp)
latency = re.findall(r'-?\d+\.\d+s(?=\slatency)',temp)
print(ipPattern)
print(macPattern)
print(devicePattern)
print(latency)
Prints:
['10.0.0.1', '10.0.0.3', '10.0.0.5', '10.0.0.200']
['10:BE:F5:FC:9C:65', '54:60:09:83:6E:B6', '7C:78:7E:A4:73:8C', '5C:B9:01:02:5F:D8']
['D-Link International', 'Google', 'Samsung Electronics']
['0.0070s', '0.11s', '0.11s', '0.027s']
For joining in a single list use:
mylist = itertools.chain([ipPattern], [macPattern], [devicePattern], [latency])
print(list(mylist))
Prints:
[['10.0.0.1', '10.0.0.3', '10.0.0.5', '10.0.0.200'], ['10:BE:F5:FC:9C:65', '54:60:09:83:6E:B6', '7C:78:7E:A4:73:8C', '5C:B9:01:02:5F:D8'], ['D-Link International', 'Google', 'Samsung Electronics'], ['0.0070s', '0.11s', '0.11s', '0.027s']]

Ansible: Concatenate registered variable with string

I have this :
# grab the internal ip [eg 10.5.20.2]
- name: Grab the internal ip to setup the sec group rule
local_action: shell /sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1 # returns the ip
register: internal_ip # save the output of the above command in a var
- debug: var=internal_ip.stdout
I want to set this IP in the inbound rule of an AWS security group as single host IP.
Like this: 10.5.20.2/32
How do I concatenate the internal_ip registered var with the string /32 ??
I scratched and bled but found it... :]
"{{ internal_ip.stdout }}/32"

Printing part of a string in Python

Trying to obtain and print and further use just the local ip address on a pi:
import os
getipaddr = "ip addr show eth0 | grep inet"
ip = "%s" % (os.system(getipaddr))
print ip
returns:
inet 192.168.1.200/24 brd 192.168.1.255 scope global eth0
0
which correctly includes the local address, but:
import os
getipaddr = "ip addr show eth0 | grep inet"
ip = "%s" % (os.system(getipaddr))
print ip[9:22]
returns:
inet 192.168.1.200/24 brd 192.168.1.255 scope global eth0
not my expected subset of characters from character 10 to 21. Maybe ip is not really a string variable. Any help on how to fix greatly appreciated. Thanks!
[note: there are actually 4 spaces in front of inet in the print returns, just don't know how to show it in this forum]
If you look at this question, you will see that the return value of os.system is the return value of the call, not it's output. The output you are seeing on the screen is not coming from python but from the ip call. If you want to capture output use the subprocess module:
from subprocess import check_output
getipaddr = "ip addr show eth0 | grep inet"
ip = check_output(getipaddr, shell=True)
Now, the output will be in ip and you should get your desired results.
As a side note, '%s' % something is an anti-pattern. The clearer way to convert a string is to do str(something).

Bash Script: sed/awk/regex to match an IP address and replace

I have a string in a bash script that contains a line of a log entry such as this:
Oct 24 12:37:45 10.224.0.2/10.224.0.2 14671: Oct 24 2012 12:37:44.583 BST: %SEC_LOGIN-4-LOGIN_FAILED: Login failed [user: root] [Source: 10.224.0.58] [localport: 22] [Reason: Login Authentication Failed] at 12:37:44 BST Wed Oct 24 2012
To clarify; the first IP listed there "10.224.0.2" was the machine the submitted this log entry, of a failed login attempt. Someone tried to log in, and failed, from the machine at the 2nd IP address in the log entry, "10.224.0.58".
I wish to replace the first occurrence of the IP address "10.224.0.2" with the host name of that machine, as you can see presently is is "IPADDRESS/IPADDRESS" which is useless having the same info twice. So here, I would like to grep (or similar) out the first IP and then pass it to something like the host command to get the reverse host and replace it in the log output.
I would like to repeat this for the 2nd IP "10.224.0.58". I would like to find this IP and also replace it with the host name.
It's not just those two specific IP address though, any IP address. So I want to search for 4 integers between 1 and 3, separated by 3 full stops '.'
Is regex the way forward here, or is that over complicating the issue?
Many thanks.
Replace a fixed IP address with a host name:
$ cat log | sed -r 's/10\.224\.0\.2/example.com/g'
Replace all IP addresses with a host name:
$ cat log | sed -r 's/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/example.com/g'
If you want to call an external program, it's easy to do that using Perl (just replace host with your lookup tool):
$ cat log | perl -pe 's/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/`host \1`/ge'
Hopefully this is enough to get you started.
There's variou ways to find th IP addresses, here's one. Just replace "printf '<<<%s>>>' " with "host" or whatever your command name is in this GNU awk script:
$ cat tst.awk
{
subIp = gensub(/\/.*$/,"","",$4)
srcIp = gensub(/.*\[Source: ([^]]+)\].*/,"\\1","")
"printf '<<<%s>>>' " subIp | getline subName
"printf '<<<%s>>>' " srcIp | getline srcName
gsub(subIp,subName)
gsub(srcIp,srcName)
print
}
$
$ gawk -f tst.awk file
Oct 24 12:37:45 <<<10.224.0.2>>>/<<<10.224.0.2>>> 14671: Oct 24 2012 12:37:44.583 BST: %SEC_LOGIN-4-LOGIN_FAILED: Login failed [user: root] [Source: <<<10.224.0.58>>>] [localport: 22] [Reason: Login Authentication Failed] at 12:37:44 BST Wed Oct 24 2012
googled this one line command together. but was unable to pass the founded ip address to the ssh command:
sed -n 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/\nip&\n/gp' test | grep ip | sed 's/ip//' | sort | uniq
the "test" is the file the sed command is searching for for the pattern

Getting a value from expect shell and use it outside

I am using the following code within a procedure in order to get an IP address of eth1 and use it as a gateway. Another thing I want is to use this variable (the IP address) outside, in the user scope.
global my_gw_ip_address
expect "# "
send "ifconfig eth1 | grep 'inet addr:' | cut -d: -f2 | awk '{print \$1}' > prod_ip_base.txt\r"
expect "# "
send " my_internal_gw=`cat prod_ip_base.txt`\r"
expect "# "
send " echo \$my_internal_gw\r"
expect "root#cnode-pp81:~ "
set checking_buffer_out $expect_out(buffer)
regexp {(?:\d+\.){3}\d+} $checking_buffer_out my_gw_ip_address
puts "internal gw: $my_gw_ip_address\n"
the output of the function is:
1. the line send " echo \$my_internal_gw\r" returns the correct IP address 192.168.138.50
2. the line puts "internal gw: $my_gw_ip_address\n" returns internal gw: 0.
can anyone please tell me what I do wrong? Why the variable $my_gw_ip_address is 0?
I solve the problem.
I should have added sleep 1 between the following commands.
change
set checking_buffer_out $expect_out(buffer)
regexp {(?:\d+\.){3}\d+} $checking_buffer_out my_gw_ip_address
to be:
set checking_buffer_out $expect_out(buffer)
sleep 1
regexp {(?:\d+\.){3}\d+} $checking_buffer_out my_gw_ip_address
Amigal