/** Get the IPv6 address from a HTTP URL. This function will return the IPv6 address according to the Url and previous parse result. @param[in] Url The pointer to a HTTP URL string. @param[in] UrlParser URL Parse result returned by NetHttpParseUrl(). @param[out] Ip6Address Pointer to a buffer to store the IP address. @retval EFI_SUCCESS Successfully get the required component. @retval EFI_INVALID_PARAMETER Uri is NULL or Ip6Address is NULL or UrlParser is invalid. @retval EFI_NOT_FOUND No IPv6 address component in the URL. @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. **/ EFI_STATUS EFIAPI HttpUrlGetIp6 ( IN CHAR8 *Url, IN VOID *UrlParser, OUT EFI_IPv6_ADDRESS *Ip6Address ) { CHAR8 *Ip6String; CHAR8 *Ptr; UINT32 Length; EFI_STATUS Status; UINT32 ResultLength; HTTP_URL_PARSER *Parser; if (Url == NULL || UrlParser == NULL || Ip6Address == NULL) { return EFI_INVALID_PARAMETER; } Parser = (HTTP_URL_PARSER*) UrlParser; if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) { return EFI_INVALID_PARAMETER; } // // IP-literal = "[" ( IPv6address / IPvFuture ) "]" // Length = Parser->FieldData[HTTP_URI_FIELD_HOST].Length; if (Length < 2) { return EFI_INVALID_PARAMETER; } Ptr = Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset; if ((Ptr[0] != '[') || (Ptr[Length - 1] != ']')) { return EFI_INVALID_PARAMETER; } Ip6String = AllocatePool (Length); if (Ip6String == NULL) { return EFI_OUT_OF_RESOURCES; } Status = UriPercentDecode ( Ptr + 1, Length - 2, Ip6String, &ResultLength ); if (EFI_ERROR (Status)) { return Status; } Ip6String[ResultLength] = '\0'; Status = NetLibAsciiStrToIp6 (Ip6String, Ip6Address); FreePool (Ip6String); return Status; }
/** Parse the NULL terminated ASCII string of multicast option. @param[in] Str The pointer to the Ascii string of multicast option. @param[in] ExtInfo The pointer to the option information to be filled. @retval EFI_SUCCESS Parse the multicast option successfully. @retval EFI_INVALID_PARAMETER The string is malformatted. @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resources. **/ EFI_STATUS Mtftp6ParseMcastOption ( IN UINT8 *Str, IN MTFTP6_EXT_OPTION_INFO *ExtInfo ) { EFI_STATUS Status; UINT32 Num; CHAR8 *Ip6Str; CHAR8 *TempStr; // // The multicast option is formated like "addr,port,mc" // The server can also omit the ip and port, use ",,1" // if (*Str == ',') { ZeroMem (&ExtInfo->McastIp, sizeof (EFI_IPv6_ADDRESS)); } else { Ip6Str = (CHAR8 *) AllocateCopyPool (AsciiStrSize ((CHAR8 *) Str), Str); if (Ip6Str == NULL) { return EFI_OUT_OF_RESOURCES; } // // The IPv6 address locates before comma in the input Str. // TempStr = Ip6Str; while ((*TempStr != '\0') && (*TempStr != ',')) { TempStr++; } *TempStr = '\0'; Status = NetLibAsciiStrToIp6 (Ip6Str, &ExtInfo->McastIp); FreePool (Ip6Str); if (EFI_ERROR (Status)) { return Status; } while ((*Str != '\0') && (*Str != ',')) { Str++; } } if (*Str != ',') { return EFI_INVALID_PARAMETER; } Str++; // // Convert the port setting. the server can send us a port number or // empty string. such as the port in ",,1" // if (*Str == ',') { ExtInfo->McastPort = 0; } else { Num = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Str); if (Num > 65535) { return EFI_INVALID_PARAMETER; } ExtInfo->McastPort = (UINT16) Num; while (NET_IS_DIGIT (*Str)) { Str++; } } if (*Str != ',') { return EFI_INVALID_PARAMETER; } Str++; // // Check the master/slave setting, 1 for master, 0 for slave. // Num = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Str); if (Num != 0 && Num != 1) { return EFI_INVALID_PARAMETER; } ExtInfo->IsMaster = (BOOLEAN) (Num == 1); while (NET_IS_DIGIT (*Str)) { Str++; } if (*Str != '\0') { return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; }