blob: 9b08a5ad43696665320cc8854426f2567e4deb7d [file] [log] [blame]
Prashanth Katti747ce9d2019-02-07 07:23:48 -06001#!/usr/bin/env python
2
3r"""
4Network generic functions.
5
6"""
7
Michael Walsh8ce4e032019-08-22 18:03:12 -05008import gen_print as gp
9import gen_cmd as gc
10import gen_misc as gm
11import var_funcs as vf
12import collections
Michael Walsh91960fd2019-08-19 14:21:20 -050013import re
Prashanth Katti747ce9d2019-02-07 07:23:48 -060014import ipaddress
Sushil Singh45d841e2020-07-30 11:52:11 -050015import subprocess
Sushil Singhbfaeb032020-09-01 02:02:36 -050016import socket
Prashanth Katti747ce9d2019-02-07 07:23:48 -060017from robot.libraries.BuiltIn import BuiltIn
Tony Leeea741302019-11-08 11:01:58 +080018import json
19import bmc_ssh_utils as bsu
Prashanth Katti747ce9d2019-02-07 07:23:48 -060020
Sushil Singh45d841e2020-07-30 11:52:11 -050021
Sushil Singh07297f82020-09-08 09:12:04 -050022def get_running_system_ip():
Sushil Singh45d841e2020-07-30 11:52:11 -050023 r"""
Sushil Singh07297f82020-09-08 09:12:04 -050024 Get the IP address of server from which robot code is running.
Sushil Singhbfaeb032020-09-01 02:02:36 -050025
Sushil Singh07297f82020-09-08 09:12:04 -050026 Example of getaddrinfo:
27
28 [(<AddressFamily.AF_INET: X>, <SocketKind.SOCK_STREAM: X>, X, '', ('XX.XX.XX.XX', port)),]
Sushil Singh45d841e2020-07-30 11:52:11 -050029 """
30
Sushil Singh07297f82020-09-08 09:12:04 -050031 ip_list = list()
Sushil Singhbfaeb032020-09-01 02:02:36 -050032 host_name = socket.gethostname()
Sushil Singh07297f82020-09-08 09:12:04 -050033 temp_ip_list = socket.getaddrinfo(host_name, 80)
34 for item in temp_ip_list:
35 ip_addr = item[-1][0]
36 ip_list.insert(0, ip_addr)
Sushil Singh45d841e2020-07-30 11:52:11 -050037
Sushil Singh07297f82020-09-08 09:12:04 -050038 return ip_list
Sushil Singh45d841e2020-07-30 11:52:11 -050039
Prashanth Katti747ce9d2019-02-07 07:23:48 -060040
41def netmask_prefix_length(netmask):
42 r"""
43 Return the netmask prefix length.
44
45 Description of argument(s):
46 netmask Netmask value (e.g. "255.255.0.0", "255.255.255.0",
47 "255.252.0.0", etc.).
48 """
49
50 # IP address netmask format: '0.0.0.0/255.255.252.0'
51 return ipaddress.ip_network('0.0.0.0/' + netmask).prefixlen
Michael Walsh91960fd2019-08-19 14:21:20 -050052
53
Anvesh Kumar Rayankula8e25b8f2020-04-06 01:18:37 -050054def get_netmask_address(prefix_len):
55 r"""
56 Return the netmask address.
57
58 Description of argument(s):
59 prefix_len Prefix length value (e.g. "24", "23", "22", etc.).
60 """
61
62 # IP address netmask format: '0.0.0.0/24'
63 return ipaddress.ip_network('0.0.0.0/' + prefix_len).netmask
64
65
Michael Walsh91960fd2019-08-19 14:21:20 -050066def parse_nping_output(output):
67 r"""
68 Parse the output from the nping command and return as a dictionary.
69
70 Example of output value:
71
72 Starting Nping 0.6.47 ( http://nmap.org/nping ) at 2019-08-07 22:05 IST
73 SENT (0.0181s) TCP Source IP:37577 >
74 Destination IP:80 S ttl=64 id=39113 iplen=40 seq=629782493 win=1480
75 SENT (0.2189s) TCP Source IP:37577 >
76 Destination IP:80 S ttl=64 id=39113 iplen=40 seq=629782493 win=1480
77 RCVD (0.4120s) TCP Destination IP:80 >
78 Source IP:37577 SA ttl=49 id=0 iplen=44 seq=1078301364 win=5840 <mss 1380>
79 Max rtt: 193.010ms | Min rtt: 193.010ms | Avg rtt: 193.010ms
80 Raw packets sent: 2 (80B) | Rcvd: 1 (46B) | Lost: 1 (50.00%)
81 Nping done: 1 IP address pinged in 0.43 seconds
82
83 Example of data returned by this function:
84
85 nping_result:
86 [max_rtt]: 193.010ms
87 [min_rtt]: 193.010ms
88 [avg_rtt]: 193.010ms
89 [raw_packets_sent]: 2 (80B)
90 [rcvd]: 1 (46B)
91 [lost]: 1 (50.00%)
92 [percent_lost]: 50.00
93
94 Description of argument(s):
95 output The output obtained by running an nping
96 command.
97 """
98
99 lines = output.split("\n")
100 # Obtain only the lines of interest.
101 lines = list(filter(lambda x: re.match(r"(Max rtt|Raw packets)", x),
102 lines))
103
104 key_value_list = []
105 for line in lines:
106 key_value_list += line.split("|")
107 nping_result = vf.key_value_list_to_dict(key_value_list)
108 # Extract percent_lost value from lost field.
109 nping_result['percent_lost'] = \
110 float(nping_result['lost'].split(" ")[-1].strip("()%"))
111 return nping_result
Michael Walsh8ce4e032019-08-22 18:03:12 -0500112
113
114openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
115
116
117def nping(host=openbmc_host, parse_results=1, **options):
118 r"""
119 Run the nping command and return the results either as a string or as a dictionary.
120
121 Do a 'man nping' for a complete description of the nping utility.
122
123 Note that any valid nping argument may be specified as a function argument.
124
125 Example robot code:
126
127 ${nping_result}= Nping delay=${delay} count=${count} icmp=${None} icmp-type=echo
128 Rprint Vars nping_result
129
130 Resulting output:
131
132 nping_result:
133 [max_rtt]: 0.534ms
134 [min_rtt]: 0.441ms
135 [avg_rtt]: 0.487ms
136 [raw_packets_sent]: 4 (112B)
137 [rcvd]: 2 (92B)
138 [lost]: 2 (50.00%)
139 [percent_lost]: 50.0
140
141 Description of argument(s):
142 host The host name or IP of the target of the
143 nping command.
144 parse_results 1 or True indicates that this function
145 should parse the nping results and return
146 a dictionary rather than the raw nping
147 output. See the parse_nping_output()
148 function for details on the dictionary
149 structure.
150 options Zero or more options accepted by the nping
151 command. Do a 'man nping' for details.
152 """
153
154 command_string = gc.create_command_string('nping', host, options)
155 rc, output = gc.shell_cmd(command_string, print_output=0, ignore_err=0)
156 if parse_results:
157 return parse_nping_output(output)
158
159 return output
Tony Leeea741302019-11-08 11:01:58 +0800160
161
162def get_channel_config():
163 r"""
164 Get the channel config data and return as a dictionary.
165
166 Example:
167 channel_config = get_channel_config()
168 print_vars(channel_config)
169
170 channel_config:
171 [0]:
172 [name]: IPMB
173 [is_valid]: True
174 [active_sessions]: 0
175 [channel_info]:
176 [medium_type]: ipmb
177 [protocol_type]: ipmb-1.0
178 [session_supported]: session-less
179 [is_ipmi]: True
180 [1]:
181 [name]: eth0
182 [is_valid]: True
183 [active_sessions]: 0
184 [channel_info]:
185 [medium_type]: other-lan
186 [protocol_type]: ipmb-1.0
187 [session_supported]: multi-session
188 [is_ipmi]: True
189 [2]:
190 [name]: eth1
191 [is_valid]: True
192 [active_sessions]: 0
193 [channel_info]:
194 [medium_type]: lan-802.3
195 [protocol_type]: ipmb-1.0
196 [session_supported]: multi-session
197 [is_ipmi]: True
198 (etc.)
199 """
200
201 stdout, stderr, rc = bsu.bmc_execute_command("cat /usr/share/ipmi-providers/channel_config.json")
202 return json.loads(stdout)
203
204
205def get_active_channel_config():
206 r"""
207 Channel configs which medium_type are 'other-lan' or 'lan-802.3' returned by
208 this function.
209 """
210
211 return vf.filter_struct(get_channel_config(), "[('medium_type', 'other-lan|lan-802.3')]", regex=1)
Tony Lee18c6f9a2020-02-18 17:00:20 +0800212
213
Tony Lee87c9cb92020-03-04 14:47:09 +0800214def get_channel_access_config(file_name):
Tony Lee18c6f9a2020-02-18 17:00:20 +0800215 r"""
216 Get the channel access config data and return as a dictionary.
217
Tony Lee87c9cb92020-03-04 14:47:09 +0800218 Description of argument:
219 file_name File name for channel access settings (e.g. '/run/ipmi/channel_access_volatile.json',
220 '/var/lib/ipmi/channel_access_nv.json'.).
221
Tony Lee18c6f9a2020-02-18 17:00:20 +0800222 Example:
223
224 channel_access_config = get_channel_access_config()
225 print_vars(channel_access_config)
226
227 channel_access_config:
228 [1]:
229 [priv_limit]: priv-admin
230 [per_msg_auth_disabled]: False
231 [access_mode]: always_available
232 [alerting_disabled]: False
233 [user_auth_disabled]: False
234 [2]:
235 [priv_limit]: priv-admin
236 [per_msg_auth_disabled]: False
237 [access_mode]: always_available
238 [alerting_disabled]: False
239 [user_auth_disabled]: False
240 """
Tony Lee87c9cb92020-03-04 14:47:09 +0800241 stdout, stderr, rc = bsu.bmc_execute_command("cat " + file_name)
Tony Lee18c6f9a2020-02-18 17:00:20 +0800242
243 return json.loads(stdout)