Build a map of services based on the IANA assignment list:
    http://www.iana.org/assignments/port-numbers

    It will load the /etc/services file and will build the mapping on the fly,
    similar to the Capirca's SERVICES file:
    https://github.com/google/capirca/blob/master/def/SERVICES.svc

    As this module is be available on Unix systems only,
    we'll read the services from /etc/services.
    In the worst case, the user will not be able to specify the
    services shortcut and they will need to specify the protocol / port combination
    using the source_port / destination_port & protocol fields.

def _get_services_mapping():
    '''
    Build a map of services based on the IANA assignment list:
    http://www.iana.org/assignments/port-numbers

    It will load the /etc/services file and will build the mapping on the fly,
    similar to the Capirca's SERVICES file:
    https://github.com/google/capirca/blob/master/def/SERVICES.svc

    As this module is be available on Unix systems only,
    we'll read the services from /etc/services.
    In the worst case, the user will not be able to specify the
    services shortcut and they will need to specify the protocol / port combination
    using the source_port / destination_port & protocol fields.
    '''
    if _SERVICES:
        return _SERVICES
    services_txt = ''
    try:
        with salt.utils.files.fopen('/etc/services', 'r') as srv_f:
            services_txt = salt.utils.stringutils.to_unicode(srv_f.read())
    except IOError as ioe:
        log.error('Unable to read from /etc/services:')
        log.error(ioe)
        return _SERVICES  # no mapping possible, sorry
        # will return the default mapping
    service_rgx = re.compile(r'^([a-zA-Z0-9-]+)\s+(\d+)\/(tcp|udp)(.*)$')
    for line in services_txt.splitlines():
        service_rgx_s = service_rgx.search(line)
        if service_rgx_s and len(service_rgx_s.groups()) == 4:
            srv_name, port, protocol, _ = service_rgx_s.groups()
            if srv_name not in _SERVICES:
                _SERVICES[srv_name] = {
                    'port': [],
                    'protocol': []
                }
            try:
                _SERVICES[srv_name]['port'].append(int(port))
            except ValueError as verr:
                log.error(verr)
                log.error('Did not read that properly:')
                log.error(line)
                log.error('Please report the above error: %s does not seem a valid port value!', port)
            _SERVICES[srv_name]['protocol'].append(protocol)
    return _SERVICES