Extract second IP from lines - python-3.x

Is there a way to extract the second IP address from a command-line output?
Command output
Manual NAT Policies (Section 1)
60 (sdf-app-vip) to (outside) source dynamic d-d-servers interface destination static obj-15.34.4.32 obj-159.13.9.12
translate_hits = 0, untranslate_hits = 0
61 (ds-app-vip) to (outside) source dynamic d-d-servers interface destination static obj-15.1.95.176 obj-15.13.5.176
translate_hits = 0, untranslate_hits = 0
152 (sd-app-vip) to (outside) source dynamic d-d-servers interface destination static obj-19.36.11.12 obj-19.36.15.12
translate_hits = 0, untranslate_hits = 0
Auto NAT Policies (Section 2)
115 (nk-app-vip) to (customer-vrf-sd) source static nat-10.19.2.190-customer-vrf-transit 10.223.2.2
translate_hits = 0, untranslate_hits = 4652
My code is able to extract both IP, but am not able to filter the second IP.
Code:
import re
#Truncate file
ft=open('puip_only.txt','w')
ft.truncate()
ft.close()
#Filter IP's from object group IP output
cip=open('puip.txt', 'r')
cs=cip.readlines()
for line in cs:
matches= re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
newlines=( ' '.join(matches))
outF = open("puip_only.txt", "a")
outF.write(newlines)
outF.write("\n")
outF.close()
Expected output is
159.13.9.12
15.13.5.176
19.36.15.12
10.223.2.2

If you only want the second IP, don't join it with the first:
if len(matches)>=2:
outF.write(matches[1])
instead of
outF.write(newlines)

You can match the following space, word chars and - and then capture the second ip number in group 1.
The group 1 values will be returned by re.findall.
\b[0-9]+(?:\.[0-9]+){3}\s+\w+-([0-9]+(?:\.[0-9]+){3})\b
Regex demo

Related

Scapy & Docker: Get container's IP address w/o using Container ID?

What is the easiest way to compare IP addresses using Scapy (in Python3.6) and Docker? I have a piece of code that sniffs my Docker bridge network using Scapy sniff(). I want to look at each packet's source IP address, and if it matches the IP address for my container named "plc1", do additional steps. If they don't match, I just return an empty list and move on.
However I cannot figure out how to compare a packet's source IP address to a container name. It really needs to be the container's name and not the ID, since I am running a ton of containers in parallel and looking up ID's to plug into my Python3.6 script is tedious. Any thoughts? I've tried using the Docker SDK but it needs the Container ID, which is what I am trying to avoid...
Sample Python3.6 code, which does not work, included below:
#!/usr/bin/env python3
from scapy.all import *
def find_ports(pkt):
# if src IPaddr matches IP addr of container plc1...
if pkt[IP].src == 'plc1': # THIS DOES NOT WORK
# if there is a match, get some additional packet info
if TCP in pkt:
tcp_dport = pkt[TCP].dport
ip_total_len = pkt.getlayer(IP).len
ip_header_len = pkt.getlayer(IP).ihl * 32 / 8
tcp_header_len = pkt.getlayer(TCP).dataofs * 32 / 8
tcp_seg_len = ip_total_len - ip_header_len - tcp_header_len
sequence_num = pkt[1].ack
return [tcp_dport, tcp_seg_len, sequence_num]
# else if NO MATCHING ip addr's, return blank list...
else:
return []
tempList = sniff(filter="ip", prn=find_ports, iface="br-19f0ba1cf88f")
# if templist not empty...
if tempList:
# send a TCP RST packet...
ip = IP(src="plc1", dst="hmi_pass_thru")
tcp = TCP(sport=502, dport=tempList[0], flags="R", seq=int(tempList[1]), ack=int(tempList[2]) + 1)
pkt = ip / tcp
ls(pkt)
send(pkt, verbose=0)

Change address of a bincopy segment

What is the easiest method to change the start address of a bincopy segment?
For example, I have the code:
import bincopy
f = bincopy.BinFile("sample.hex")
print( f.segments )
which gives:
Segment(address=0, data=bytearray(b'\xaa\x00\x00\x00\x11\x00\x00\xaa'))
Segment(address=96, data=bytearray(b'\xdd\x00\x00\x00\x22\x00\x00\xdd'))
Segment(address=160, data=bytearray(b'\xee\x00\x00\x00\x33\x00\x00\xee'))
How to change the start address of the second segment from 96 to 60, for example?
What I have found so far:
bindata = f.as_binary(minimum_address=MY_START_ADDRESS, maximum_address=MY_END_ADDRESS)
f.add_binary(bindata, address=MY_DEST_ADDRESS, overwrite=False)
However, this solution has the disadvantage that the new datarange is handled by bincopy as a single segment without splitting it into multiple segments if there are empty spaces in between.
Therefore, another solution is to loop over the segments in the relevant range and move the one by one:
g = bincopy.BinFile()
for seg in f.segments:
g.add_binary( seg.data, address= seg.address + offset, overwrite=False)

Using python configparser to update .ini file section value but cant figure how to update the correct value as directed

I have been tasked with creating a program that will update a value in an ini file. The ini file looks like;
[link1]
name = nodeB
ip = 127.0.0.1
port = 1002
cost = 190
[link2]
name = nodeC
ip = 127.0.0.1
port = 1003
cost = 210
The command to update this ini file can only take two parameters, neighbor name and cost. I cant figure out how to update the values without saying which section the neighbor is in. The example of the parameters in use is UpdateRouteCost nodeB 4.
I am able to update a value by stating the section and the key I want updated.
elif text == "UpdateRouteCost":
parser = configparser.ConfigParser()
parser.read('try.ini')
t = open('try.ini', 'w')
parser.set('link1', 'cost', '1')
parser.write(t)
t.close()
print(parser.get('link1', 'cost'))

Export data from a file into Excel Python 2.7

I would need to create an Excel sheet out of a file. The file has this format, but has dozens of templates like this one. To match the representation of my entire file, the following format can be copy pasted twice:
Field Value
OS-DCF:diskConfig MANUAL
OS-EXT-AZ:availability_zone az1
OS-EXT-STS:power_state 1
OS-EXT-STS:task_state None
OS-EXT-STS:vm_state active
OS-SRV-USG:launched_at 2016-02-04T12:53:35.000000
OS-SRV-USG:terminated_at None
accessIPv4
accessIPv6
addresses 10.10.10.10
config_drive True
created 2018-09-04T12:52:52Z
flavor m1.small
hostId ajsdajdad-qweqweqw-qwe123123-qweqweq-sadsadasd-1121212
id 922adwq-qwejjqeq-123123-asdasa
image cirros1
key_name None
name vm1
os-extended-volumes:volumes_attached []
progress 0
project_id id
properties ctrl='10.10.10.3', token='token', tenant='tenant1'
scheduler_hints {}
security_groups [{u'name': u'sg1'}, {u'name': u'sg2'}]
status ACTIVE
updated 2016-02-04T12:53:35Z
user_id user1
The Excel file should look like this:
The problematic part seems to be here:
hostname, chains_segment = host.split('\n',1)
hostname = hostname.strip()
After the strip, I should get the VM name value, but I am getting empty values.
Here is the full code:
import xlsxwriter
import argparse
parser=argparse.ArgumentParser(description="Script")
parser.add_argument('-i','--input',help='Input log file name',required=True)
parser.add_argument('-o','--output',help='Desired name for the Excel file',required=True)
parser.add_argument('-s','--sheet',help='Desired name of the Excel sheet(Default: Sheet1)',default='Sheet1',required=False)
args=parser.parse_args()
az='| OS-EXT-AZ:availability_zone | '
state='| OS-EXT-STS:vm_state | '
launch='| OS-SRV-USG:launched_at | '
ipaddr='| addresses | '
flavor='| flavor | '
image='| image | '
def create_chain(chain_segment):
chains=[]
chain_lines = [line for line in chain_segment.split('\n') if line]
for line in chain_lines:
chain={}
if launch in line:
chain['launch'] = line.split()[3]
# chain['az'] = line.split()[3]
# chain['state'] = line.split()[3]
# chain['ipaddr'] = line.split()[3]
# chain['flavor'] = line.split()[3]
# chain['image'] = line.split()[3]
chains.append(chain)
chains=filter(None, chains)
chains=list(chains)
chained = [merge_dicts(chains[0], i) for i in chains[1:]]
return chained
def merge_dicts(x,y):
z=x.copy()
z.update(y)
return z
with open(args.input) as f:
log_content = f.read()
host_sections = [host for host in log_content.split(" Field Value") if host]
hosts = {}
for host in host_sections:
hostname, chains_segment = host.split('\n',1)
hostname = hostname.strip()
chains=[]
for segment in chains_segment.split('\n\n'):
chains.extend(create_chain(segment))
hosts[hostname] = chains
workbook=xlsxwriter.Workbook(args.output)
worksheet1=workbook.add_worksheet(args.sheet)
worksheet1.write(0,0,'VM')
worksheet1.write(0,1,'Availability Zone')
worksheet1.write(0,2,'State')
worksheet1.write(0,3,'Launched at')
worksheet1.write(0,4,'IP Address')
worksheet1.write(0,5,'Flavor')
worksheet1.write(0,6,'Image')
worksheet1.write(0,7,'Tenant')
worksheet1.write(0,8,'Security Group')
row = 1
for host, chains in hosts.items():
for chain in chains:
worksheet1.write(row, 0, host)
worksheet1.write(row, 1, chain.get('az'))
worksheet1.write(row, 2, chain.get('state'))
worksheet1.write(row, 3, chain.get('launch'))
worksheet1.write(row, 4, chain.get('ipaddr'))
worksheet1.write(row, 5, chain.get('flavor'))
worksheet1.write(row, 6, chain.get('image'))
row += 1
workbook.close()
Any idea how I can correct this?
Many thanks,
Albert
P.S. Please note that I am new to programming.

Creating ICMP fragmentation needed packet in Scapy

I want to create ICMP fragmentation needed packet using Scapy. When I give type = 3 and code =4 and display the message again, it shows me type =destination unreachable and code = fragmentation needed. But I also want to see one more field associated with this ICMP "next-hop MTU". DO I need to create custom field or is there any other way I can create it.
Here is what I'm doing.
i=ICMP()
i.display()
type = 3
code = 4
checksum = 0
unused = 0
Display it again
i.display ()
type= destination unreachable
code = fragmentation needed
checksum =0
unused = 0
from other references it seems you can use:
i.unused = mtu

Resources