I am attempting to parse an ifconfig file that will have the following format:
Bond10G: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST> mtu 9000
inet 10.117.62.135 netmask 255.255.254.0 broadcast 10.117.63.255
ether 00:50:56:9e:89:10 txqueuelen 1000 (Ethernet)
RX packets 14315389 bytes 39499265855 (36.7 GiB)
RX errors 0 dropped 35686 overruns 0 frame 0
TX packets 13009616 bytes 38702751346 (36.0 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Bond1G: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST> mtu 1500
inet 10.117.60.135 netmask 255.255.254.0 broadcast 10.117.61.255
inet6 fe80::250:56ff:fe9e:ed0d prefixlen 64 scopeid 0x20<link>
ether 00:50:56:9e:ed:0d txqueuelen 1000 (Ethernet)
RX packets 1573455 bytes 172628399 (164.6 MiB)
RX errors 0 dropped 10946 overruns 0 frame 0
TX packets 185449 bytes 50369231 (48.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 9000
ether 00:50:56:9e:89:10 txqueuelen 1000 (Ethernet)
RX packets 13493291 bytes 39433797198 (36.7 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 13006856 bytes 38701854528 (36.0 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 9000
ether 00:50:56:9e:89:10 txqueuelen 1000 (Ethernet)
RX packets 822097 bytes 65468597 (62.4 MiB)
RX errors 0 dropped 35673 overruns 0 frame 0
TX packets 2760 bytes 896818 (875.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth2: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 1500
ether 00:50:56:9e:ed:0d txqueuelen 1000 (Ethernet)
RX packets 961003 bytes 127916200 (121.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 182704 bytes 49477386 (47.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth3: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST> mtu 1500
ether 00:50:56:9e:ed:0d txqueuelen 1000 (Ethernet)
RX packets 612452 bytes 44712199 (42.6 MiB)
RX errors 0 dropped 10930 overruns 0 frame 0
TX packets 2745 bytes 891845 (870.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 3164912 bytes 12725232051 (11.8 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3164912 bytes 12725232051 (11.8 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
What I would like to get is a dictionary who's value is the interface, and the keys and values looking in this manner:
{'Bond10G' : {'mtu' : '9000', 'inet' : '10.117.62.135', 'netmask' : '255.255.254.0' # all remaining values that are space delimited},
'Bond1G' : {'mtu' : '9000', 'inet' : '10.117.60.135' # all remaining values that are space delimited} }
I have been able to split by new line to segregate each interface, however I am unsure as to how to continue. Sample code:
with open('ifconfig_file) as data:
for line in data:
temp_array = line.split("\n\n")
My logic would be (correct me if im wrong):
Split by colon to grab interface name to find the key (issue is the ether has colons in it).
While not empty line, take those values delimited by spaces and array[0] would be the key and array[1] would be the value.
You can leverage split() as well as regex. Here's an example where I parse mtu and inet:
import re
def parse_info(interface):
info = {}
mtuMatches = re.findall("mtu [0-9]*\s", interface) # find all matches for mtu
if (len(mtuMatches) > 0):
info['mtu'] = mtuMatches[0].replace("mtu", "").strip() # use the first match
inetMatches = re.findall("inet [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\s", interface) # find all matches for inet
if (len(inetMatches) > 0):
info['inet'] = inetMatches[0].replace("inet", "").strip() # use the first match
# add more here
return info
def parse_name(interface):
parts = interface.split(":")
return parts[0] # grab the name
def parse_interface(interface):
name = parse_name(interface)
info = parse_info(interface)
return name, info
def parse_file(data):
interfaces = data.split("\n\n")
parsed = {}
for interface in interfaces:
name, info = parse_interface(interface)
parsed[name] = info
return parsed
with open('ifconfig.txt') as file:
print(parse_file(file.read()))
This is probably not the most performant way of doing it (if you want performance then maybe split by space and iterate over the result) but this is the cleanest in my opinion
Related
I'm doing a project that will connect multiple subsystems (sensors, controller, etc) via CAN bus. I'm using SocketCAN and have settings as below:
root#ngtianxun-desktop:~# ip -details -statistic link show can0
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 10
bitrate 500000 sample-point 0.600
tq 100 prop-seg 3 phase-seg1 8 phase-seg2 8 sjw 4
RDC_CAN: tseg1 5..16 tseg2 3..8 sjw 1..4 brp 2..131072 brp-inc 2
clock 20000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 337 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
27841616 3498429 0 0 0 0
TX: bytes packets errors dropped carrier collsns
9504120 2357958 0 0 0 0
root#ngtianxun-desktop:~#
Python scripts have been written to constantly monitor the subsystems and write to the subsystems upon request from the python end.
My question here is - Why am I seeing arbit-lost incrementing by 1 every time at an interval of about ~5 mins once my python program runs? Does it indicate any serious issue? Does it mean the data frame is lost? Is there any concern if I just let it be like this? Anyone who could help to answer and explain would be appreciated!
Worth noting: The programs started for about ~3 days. Only arbit-lost is observed, there's no re-started, bus-errors, error-warn, error-pass, and bus-off. And there are no errors, dropped, overrun, mcast, carrier, and collsns errors in TX/RX fields.
Usually you can safely ignore arbitration lost errors. It just means one message lost an arbitration in favor of another. Thankfully CAN has been made robust enough so that the "arbitration loser" will be sent again.
I recommend the following reads:
Wikipedia
SocketCAN
following a tutorial I coded a wifi sniffer in python using sockets (on linux) and the "struct" package. The code is splitted in two parts: the first one decodes the Ipv4 header packets getting the Ips and other information and then sends the remaining data to the second part which decodes ICMP, UDP and TCP packets. When I decode the TCP and UDP packets I can easily get source ports and destinations ports, flags etc... but I'm now looking for the host name. In other words Im trying to see which website is visited by the packet sender/receiver.
How can I get the host name? Is it in the "data" part of the tcp/udp packet, if so how to decode it? Do I have to look at the source and destination ports?
Here is the code: 2 functions for UDP/TCP packets, the data argument is the "data" part from a Ipv4 packet.
def tcp_segment(data):
(src_port, dest_port, sequence, acknowledgement, offset_reserved_flags) = struct.unpack('! H H L L H', data[:14])
offset = (offset_reserved_flags >> 12) * 4
flag_urg = (offset_reserved_flags & 32) >> 5
flag_ack = (offset_reserved_flags & 16) >> 4
flag_psh = (offset_reserved_flags & 8) >> 3
flag_rst = (offset_reserved_flags & 4) >> 2
flag_syn = (offset_reserved_flags & 2) >> 1
flag_fin = offset_reserved_flags & 1
return src_port, dest_port, sequence, acknowledgement, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin, data[offset:]
def udp_segment(data):
src_port, dest_port, size = struct.unpack('! H H 2x H', data[:8])
return src_port, dest_port, size, data[8:]
TCP packet
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 days ago.
Improve this question
How can I read TLS information (record length, record type...) from a packet using scapy. I have used load_layer('tls') and I'm able to read some information when there is a single TLS record in a packet but when there is multiple TLS record in a packet I'm only able to read the first TLS record.
For exemple this packet contain 3 TLS record and when I want to read the records length with scapy I only get the first record length
Total TLS decoding
As you've found, scapy doesn't decode the entire packet. But this is fine, because we can manually decode the TLS sections that scapy currently considers as a "Raw load" of bytes.
>>> pkts = rdpcap("facebook.com.pcap")
>>> extra_tls_layers = TLS(pkts[5]["TLS"].load)
>>> # We can see that TLS is now decoded, with two new layers:
>>> extra_tls_layers.show()
###[ TLS ]###
type= application_data
version= TLS 1.2
len= 1017 [deciphered_len= 1017]
iv= b''
\msg\
|###[ TLS Application Data ]###
| data= '\x1f\x11\xc4\xab\x920l\xae]=\x10\xd4\x13\x81k\x14\x98e\x8b\xcd\xa0...
mac= b''
pad= b''
padlen= None
###[ TLS ]###
type= application_data
version= TLS 1.2
len= 1517 [deciphered_len= 240]
iv= b''
\msg\
|###[ TLS Application Data ]###
| data= '\xac\x0b\xda\xba\xe8z\x99\xad\x0b_\x82\x96c\xb3\xff\x9f\xcc...
mac= b''
pad= b''
padlen= None```
To access a value of each of these layers (the newly decoded layers start at 0, 2), use the deciphered_len attribute.
>>> pkts[5][TLS][0].deciphered_len
122
>>> pkts[5][TLS][5].deciphered_len
1
>>> extra_tls_layers[0].deciphered_len
1017
>>> extra_tls_layers[2].deciphered_len
240
Verifying completeness
The length of the entire TLS section is 1400 here, which we get with len(pkts[5][TLS]). Note that the TLS record header is 5 bytes (content type = 1 byte, version = 2 bytes, length = 2 bytes).
So with a budget of 1400 bytes, let's check the record lengths:
record 1: 5 + 122 => 127
record 2: 5 + 1 => 6
record 3: 5 + 1017 => 1022
record 4: 5 + 240 => 245
Checking that the 4 TLS records add up,
127 + 6 + 1022 + 245 = 1400 for the TLS section.
Raw packet #6
For future readers, if the pcap is not available, and you're in the scapy interpreter, this is the relevant packet bytes for packet 6:
>>> pkt = b'\x00\r:\x8a\x18P\x124Vx\x9a\xbc\x08\x00E\x00\x05\xa0E\xfc#\x00R\x06)E\x9d\xf0\x08#\n\x00\x04\x04\x01\xbb\xca`0l;1\xfa\x93\n\xc2P\x10\x00r<\xd3\x00\x00\x16\x03\x03\x00z\x02\x00\x00v\x03\x03\x94\x01\xb5\xcc1b\x86Jh\x85\xf0vG\xb7#\xe7\xd2\n\x1d\xd0\'\x01\x8d\xb6\xab\xa9\x8af\x92=h= \x98\x0fJKbJ\xff(sw\xcbdW\xae\x16\x17\xec\xec\xb7\xba\x139\x92/9\xed\xc2\xeb\xa3\x07\x88\xaa\x13\x01\x00\x00.\x00+\x00\x02\x03\x04\x003\x00$\x00\x1d\x00 \xed\xfd\x0f*\x87\x9a;Q\xbb\x88\n\xad*\x9d,C\x96\xdd\x14\xab\xd8\xd8}\xf9(\x8f\xcb\xb3\x10+\xa63\x14\x03\x03\x00\x01\x01\x17\x03\x03\x03\xf9\x1f\x11\xc4\xab\x920l\xae]=\x10\xd4\x13\x81k\x14\x98e\x8b\xcd\xa0\x9f\xca\xfd\xcf\xd5\xc2\xa3\xc9S\xd0\x86G\xf3\xdc\x08\x8a,\x15\xbe+\x84\xfd\x87\x8bk\x956zO\xb3;\x875\xf4\xbd\x01\xe7`\x0f=\x08\xc5\xd8\xe6\x9e\xa4\xd9\xa3\x89C^\x07y"\x85\xb9|\xfc:{\x19\x99r\x9av\x15{\xf6\xf4\x91\x97\xfd\xe6\x7f\xbf\x1c\x81\xb9\x81\xc7W\xbao\x98X>n\'\x91\x11X\x9660\x92\\ub\xb896\xce\r\x84\xe0\x82:r{\xff\xbet\xea*\x03\x97Iw\xc8\x8b\x1d\xe3m\xe2%\x054\xc7\x0e\x9e\xe2LQ")a\x11M\x92eY=\xcc\x89\x9cj\xae\xa73\xf0\x90\xf9.&\xf5\x14\xbc\\\x8f\xa5\xfc\x0e"bD\xce\x92\xb0\x9d\xc3\xddm\xc2\x94\x90\x93T\no\xc7\x10k\x1a\xdfP\xecF\xa9\xeb\xe3=\xe4\xe5\xf5\x8b\x1a]l\x82\xdb\x93\x0c\xb7Q\x15bS\x97\xd6xu\xec\x0fd5$\xb03A\xa8\x14 \x00\xd7h\x82\xb0\xb7\xb3QY\x82%s\xf8H\x1a\xf3\xa1\xac\xcd\x07\xb0=\xdcdv\x16y\x91D\xb1\xbfzq\x92\xcf\x07\xef\x84\x8c\'\xefD\x05\xcb\xe1\xd1\x01\'\xcf\xbedG\rg\x94\x073\x9c\xe7e-\xd3\xd2|\x0e\xa2\xeb$\xc2\xe3\xa4&`\x9c\xd6\xe9\xf3\xd4fP\xf5\xdb\x10\x85\xbf\xc8\xa1\x86d;\x9e\xe3\xa2\xce\xe2Tx\xba~g\t\x8e\xbd5\xce8T\x00\xa4*\xc7\x15\xf1\xa3\xae\x90\xearT\x03\xcaK\xb9\xf8\x04-\xd7\xeb\xfb\xc1<}\x95\x85\xd97\'\xfbIH\xcf\x07\x85G\xd7\xe6~\xaeb\x14*\xcf\xe2#\xbc\xa5\xc79+\x1e\xff\x90 Df[\xc3\xb9;\x9c\x8a\x0b\x02\xb4*\xb7s/\x9c\xaa{\xb7\xbd4\xfb\x00\xa7\xa6u\xdf0\x84\x060\xbf#\x17\xba\x0e\xbe\x86\x83\xc8h\xba!\x86j\x04\x98\x0c/\xfa\xe2wp\x16:z\x04\xc5\xc0yo\x06\xfd\xcd\x9fCxJ\xb0fS\x989\x1c\xe5\xfe\x18Kl\x8b\'\xcday%\xe5\xa7\xa6T_`\x07{\xdc\xe7OI\x80\x03\xc9\x92(\x9f\xa5\xee\x0e\xac\xc4\x01`g*|\x88\x13\x8d\xe3I\x8dZ;\xfdcV\xc0\xdb,*#\xd4Y\xd7\x9b\xe0\xd0J6u\xedn\xe3VR\xab\xb5x(\xe7\x9cF\xfd\xc0\xea\xf2\xb5\xc2\xce\r\xd1\xec\xb6 {\xce;<\x8f\n\x80\xa0\xf7W\xf0R"\x80N\xdc\x82\x92\x19wa\xb3/\xab\xf6\xec\x99\xfa\xca\xeb\x08\xaf\x97\xc8\x89g\xdd\xf3\xf2\xb1|Yo\xca\x0b\xd3_\n/\x8e!\xf7\x11b&\xae\xed\xa3\xcc\\\xeb\xbf\x19\xd6\xacE\x02\n[\xa4i(\xaa\x0cQ\xcf\xf0\xf6"`\x04M\xe9%\x8e\xfdRo\xae]eA6}l\x1e\xe2\x04[\xf0\x93\xa2)\x02\xf1\xd0&\x00_J\xd3y\x99\x90(\x85VrN\t\xf3z\xfel\xd7.\x80\x07\x8e\x1f=\x9c\xebrK\x06 6-O\xb1\x8f\xfa\xc6"f\x02\t%\xf8q\xb5\x14\xcbp*\xb4!({r\x00S\xf1\x19\t\xb2\xafs`\xd1\x0b\xc8\x14V]{B\x15\xc4\xc3\x06\x08\n\xa02&\xe1`b\xf0\xd8PZL\xb5\x8b\x93\xb8<a[\xcc\x07\xadtr\xa3hbNv\xa9t)\xb4hB\xe5\xf5\xe1\xbb\xde\x03\xe3\x14\xac\xe2\xb6i\xfe\x9a/"\x95\x9332 \xabu\xbb\x1a\xf2x\x85C\xad;\x8d\x87\x95;\x14O%\xa9f\xe1\x10x\xce">-\xb3.\xc9w\xf0fB\xfe;\xdd\xea\xf5\x85\xa2\'\x8b\x08\xe8\x1c\xb8\xeb\x7fb\xd4\xf0\xba\x7f\xfd\x9a{\x92]\x0bp5\x91.Q\'\x03Q\xf9#\xbc{\x93\xa9\xc9\x96W&\xb8\x15\x8d\xa9_k\xd2\x8bz\x90\xde\xc0\xa1`\xe4r8\xd2W\xfb\x1f\xd2]S?\xe4\x0cK^\xde\xfds\xd3\xf0\xc6\xb9\x04\x05\xd1\xf6\xb3\xd8\x0fz6\xdf\x86\xa8Z\x1cj\xadO\xa0\x89;\x94%\xa4K"`\x8b:\xdc\xb6\xa0=g\xc7\x04k/f\x04\xf5E\x00\xdd\r\xbd]\xe8\x869+\xd7\x85\xb3{yG\x1bH\x8fn\xad\xd5\xd7\xea\xf6u\x13\x85\xcd\xa3$\xbaF~\x1e\xc1M#>\n!\x97\xcd\x1aF\x86\x84\xb2\x9b\xf9u}\x96\xc68\x89\x97\x17\x03\x03\x05\xed\xac\x0b\xda\xba\xe8z\x99\xad\x0b_\x82\x96c\xb3\xff\x9f\xcc\t\xbd \x9cM\x0bP\xe2\xb0\xa5#\xfb)\xda:K\x9b-\xb0\x0b\xb36p\xe2<oOj\x96\x10\xe2jEq o\xc8\x99\xf2\x0es\x9fj\xc5\x0c\xc5\xc0\x83\x92>\x9d\x05\x17\xed\x85\xc8,Q\xf1W\xa9\xac\x9ez\x19\x14\x90i\x1ef\xe8E\xd6\xf1\x9f\xe0\xc1#\xed\'\x88\xb13\xf5;pg\x18\xc19,\xe2u\xefTJ\xd2\x08\xb5\x8e\xf2\xcf\xd2\xce\xf0L\xfa]\x95\x05wk\x8f\x85\xa2\x8aQ\x00\x12\r\x0f\xa6\xa9\x88:4\xb3\xa3z\xa8\xf6\xeaV\x1c\x86w\xce\xe7\x97\xf4\xc3\x19.\n\xe7>\xb2\x8dj\xcf\\\xaf5{$\xa0L\x1e\x15\xb6\xd4\xc7\xdb\xbc\x99l"D\x890K\xa8\x03\x0fz\xfd\x88\xabH\xcb\xbe\xbc0\xa3\xbetp\x90\xd3_BGe\x93[\x98\x9c\xf86\xc8\xdd\xb3]\x1c\xf0\x83\xbf\xbfs\xccj\xbd\x8fR\x8d\x9e\t\xe8\xce\xd33R/'
>>> # To reconstitute, create an Ethernet packet
>>> new_pkt = Ether(pkt)
Hey i need a little help trying to get the gateway IP from this using the 're' import in python. (I'm trying to get the 'broadcast' bit in eth0) can anyone help me with the regex expression. Many thanks.
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
inet6 fe80::a00:27ff:feb4:9403 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:b4:94:03 txqueuelen 1000 (Ethernet)
RX packets 81508 bytes 94760761 (90.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 80331 bytes 134321242 (128.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Not sure why you would use regex against shell output of ifconfig which is highly susceptible to changes between distributions of *nix, bsd, etc. etc.
here is a pure python solution:
>>> import netifaces as ni
>>> ni.ifaddresses('en0')[2][0]['broadcast']
u'192.168.0.255'
Well, here it is both ways. Take your pick.
import re
s = """
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
inet6 fe80::a00:27ff:feb4:9403 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:b4:94:03 txqueuelen 1000 (Ethernet)
RX packets 81508 bytes 94760761 (90.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 80331 bytes 134321242 (128.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
"""
# Bit values - see /usr/include/linux/if.h
IFF_UP = 1<<0
IFF_BROADCAST = 1<<1
IFF_RUNNING = 1<<6
IFF_MULTICAST = 1<<12
# Method 1 - Collect the flags integer value.
rf = re.compile(r'flags=(?P<flags>\d+)')
m = rf.search(s)
if m:
flags = int(m.group('flags'))
print('Your flags {0:d} (decimal) is {0:X}'.format(flags, flags))
# Note the bitwise and operator here:
if flags & IFF_BROADCAST:
print('BROADCAST bit is ON')
# Method 2 - Collect the flag names.
rn = re.compile(r'flags=\d+<(?P<names>.+)>')
m = rn.search(s)
if m:
names = m.group('names').split(',')
print('Your names are ', names)
if 'BROADCAST' in names:
print('BROADCAST bit is ON')
want to extract RX, TX counters separately. Any python example to print counters in the following way from the string_output?
RX_unicast_packets = 2735118
RX_multicast_packets = 703555
TX_unicast_packets = 3983205
TX_multicast_packets = 1916649
RX
2735118 unicast packets 703555 multicast packets 677 broadcast packets
3439365 input packets 3803190483 bytes
1867301 jumbo packets 0 storm suppression bytes
0 runts 0 giants 0 CRC 0 no buffer
0 input error 0 short frame 0 overrun 0 underrun 0 ignored
0 watchdog 0 bad etype drop 0 bad proto drop 0 if down drop
0 input with dribble 291 input discard
15 Rx pause
TX
3983205 unicast packets 1916649 multicast packets 340 broadcast packets
5900194 output packets 3546311266 bytes
1702539 jumbo packets
0 output errors 0 collision 0 deferred 0 late collision
0 lost carrier 0 no carrier 0 babble 0 output discard
0 Tx pause
"
I believe the regex expression could be valuable here, I'm not sure they way you receive the above output but I will assume that it's a string type:
to parse the TX values:
string = 'RX 2735118 unicast packets 703555 multicast packets 677 broadcast packets 3439365 input packets 3803190483 bytes 1867301 jumbo packets 0 storm suppression bytes 0 runts 0 giants 0 CRC 0 no buffer 0 input error 0 short frame 0 overrun 0 underrun 0 ignored 0 watchdog 0 bad etype drop 0 bad proto drop 0 if down drop 0 input with dribble 291 input discard 15 Rx pause TX 3983205 unicast packets 1916649 multicast packets 340 broadcast packets 5900194 output packets 3546311266 bytes 1702539 jumbo packets 0 output errors 0 collision 0 deferred 0 late collision 0 lost carrier 0 no carrier 0 babble 0 output discard 0 Tx pause'
re.findall(r'RX \d+\ ', string) #to get the matching RX values
re.findall(r'TX \d+\ ', string)#to get the matching TX values
if you want to match specific values, you can make use of the re.search groups
RX_unicast_packets = re.search(r'RX (\d+)\ \w+\ \w+\ (\d+)\ ', string).group(1)
RX_multicast_packets = re.search(r'RX (\d+)\ \w+\ \w+\ (\d+)\ ', string).group(2)
let me know if you need any further help, and i would be happy to help here