code: def map_port(protocol, public_port, private_port, lifetime=3600,
               gateway_ip=None, retry=9, use_exception=True):
      
      if protocol not in [NATPMP_PROTOCOL_UDP, NATPMP_PROTOCOL_TCP]:
          raise ValueError("Must be either NATPMP_PROTOCOL_UDP or "
                           "NATPMP_PROTOCOL_TCP")
      if gateway_ip is None:
          gateway_ip = get_gateway_addr()
      response = None
      port_mapping_request = PortMapRequest(protocol, private_port,
                                            public_port, lifetime)
      port_mapping_response = \
          send_request_with_retry(gateway_ip, port_mapping_request,
                                  response_data_class=PortMapResponse,
                                  retry=retry)
      if port_mapping_response.result != 0 and use_exception:
          raise NATPMPResultError(port_mapping_response.result,
                                  error_str(port_mapping_response.result),
                                  port_mapping_response)
      return port_mapping_response
docs: A function to map public_port to private_port of protocol.
         Returns the complete response on success.
         
              protocol - NATPMP_PROTOCOL_UDP or NATPMP_PROTOCOL_TCP
              public_port - the public port of the mapping requested
              private_port - the private port of the mapping requested
              lifetime - the duration of the mapping in seconds.
                         Defaults to 3600, per specification.
              gateway_ip - the IP to the NAT-PMP compatible gateway.
                           Defaults to using auto-detection function
                           get_gateway_addr()
              retry - the number of times to retry the request if unsuccessful.
                      Defaults to 9 as per specification.
              use_exception - throw an exception if an error result
                              is received from the gateway.  Defaults to True.