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