code: func ForwardedPorts(manifest *schema.PodManifest) ([]ForwardedPort, error) {
  	var fps []ForwardedPort
  	var err error
  
  	// For every ExposedPort, find its corresponding PodPort
  	for _, ep := range manifest.Ports {
  		podPort := ep.PodPort
  
  		// If there is no direct mapping, search for the port by name
  		if podPort == nil {
  			podPort, err = findAppPort(manifest, ep.Name)
  			if err != nil {
  				return nil, err
  			}
  			if podPort == nil {
  				return nil, fmt.Errorf("port name %q could not be found in any apps", ep.Name)
  			}
  		}
  		fp := ForwardedPort{
  			HostPort: ep,
  			PodPort:  *podPort,
  		}
  		fp.HostPort.PodPort = &fp.PodPort
  		if fp.HostPort.HostIP == nil {
  			fp.HostPort.HostIP = net.IPv4(0, 0, 0, 0)
  		}
  
  		// Check all already-existing ports for conflicts
  		for idx := range fps {
  			if fp.conflicts(&fps[idx]) {
  				return nil, fmt.Errorf("port %s-%s:%d already mapped to pod port %d",
  					fp.PodPort.Protocol, fp.HostPort.HostIP.String(), fp.HostPort.HostPort, fps[idx].PodPort.Port)
  			}
  		}
  
  		fps = append(fps, fp)
  	}
  	return fps, nil
  }
docs: // ForwardedPorts matches up ExposedPorts (host ports) with Ports on the app side.
  // By default, it tries to match up by name - apps expose ports, and the podspec
  // maps them. The podspec can also map from host to pod, without a corresponding app
  // (which is needed for CRI)
  // This will error if:
  // - a name is ambiguous
  // - the same port:proto combination is forwarded