Check and format a string result to be lowercase colon-separated MAC.
(mac)
| 178 | |
| 179 | |
| 180 | def _clean_mac(mac): |
| 181 | # type: (Optional[str]) -> Optional[str] |
| 182 | """Check and format a string result to be lowercase colon-separated MAC.""" |
| 183 | if mac is None: |
| 184 | return None |
| 185 | |
| 186 | # Handle cases where it's bytes (which are the same as str in PY2) |
| 187 | mac = str(mac) |
| 188 | if not PY2: # Strip bytestring conversion artifacts |
| 189 | # TODO(python3): check for bytes and decode instead of this weird hack |
| 190 | for garbage_string in ["b'", "'", "\\n", "\\r"]: |
| 191 | mac = mac.replace(garbage_string, "") |
| 192 | |
| 193 | # Remove trailing whitespace, make lowercase, remove spaces, |
| 194 | # and replace dashes '-' with colons ':'. |
| 195 | mac = mac.strip().lower().replace(" ", "").replace("-", ":") |
| 196 | |
| 197 | # Fix cases where there are no colons |
| 198 | if ":" not in mac and len(mac) == 12: |
| 199 | log.debug("Adding colons to MAC %s", mac) |
| 200 | mac = ":".join(mac[i : i + 2] for i in range(0, len(mac), 2)) |
| 201 | |
| 202 | # Pad single-character octets with a leading zero (e.g. Darwin's ARP output) |
| 203 | elif len(mac) < 17: |
| 204 | log.debug( |
| 205 | "Length of MAC %s is %d, padding single-character octets with zeros", |
| 206 | mac, |
| 207 | len(mac), |
| 208 | ) |
| 209 | parts = mac.split(":") |
| 210 | new_mac = [] |
| 211 | for part in parts: |
| 212 | if len(part) == 1: |
| 213 | new_mac.append("0" + part) |
| 214 | else: |
| 215 | new_mac.append(part) |
| 216 | mac = ":".join(new_mac) |
| 217 | |
| 218 | # MAC address should ALWAYS be 17 characters before being returned |
| 219 | if len(mac) != 17: |
| 220 | log.warning("MAC address %s is not 17 characters long!", mac) |
| 221 | mac = None |
| 222 | elif mac.count(":") != 5: |
| 223 | log.warning("MAC address %s is missing colon (':') characters", mac) |
| 224 | mac = None |
| 225 | return mac |
| 226 | |
| 227 | |
| 228 | def _read_file(filepath): |