gateway.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package upnp
  2. import (
  3. ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
  4. "github.com/pkg/errors"
  5. "net"
  6. "strings"
  7. )
  8. func Gateway() (*Upnp, error) {
  9. result, error := send()
  10. if result == "" || error != nil {
  11. return nil, error
  12. }
  13. upnp := resolvesss(result)
  14. return upnp, nil
  15. }
  16. func send() (string, error) {
  17. var str = "M-SEARCH * HTTP/1.1\r\n" +
  18. "HOST: 239.255.255.250:1900\r\n" +
  19. "ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
  20. "MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n\r\n"
  21. var conn *net.UDPConn
  22. remotAddr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
  23. if err != nil {
  24. return "", errors.New("组播地址格式不正确")
  25. }
  26. locaAddr, err := net.ResolveUDPAddr("udp", ip_helper2.GetLoclIp()+":")
  27. if err != nil {
  28. return "", errors.New("本地ip地址格式不正确")
  29. }
  30. conn, err = net.ListenUDP("udp", locaAddr)
  31. defer conn.Close()
  32. if err != nil {
  33. return "", errors.New("监听udp出错")
  34. }
  35. _, err = conn.WriteToUDP([]byte(str), remotAddr)
  36. if err != nil {
  37. return "", errors.New("发送msg到组播地址出错")
  38. }
  39. buf := make([]byte, 1024)
  40. n, _, err := conn.ReadFromUDP(buf)
  41. if err != nil {
  42. return "", errors.New("从组播地址接搜消息出错")
  43. }
  44. result := string(buf[:n])
  45. return result, nil
  46. }
  47. func resolvesss(result string) *Upnp {
  48. var upnp = &Upnp{}
  49. lines := strings.Split(result, "\r\n")
  50. for _, line := range lines {
  51. //按照第一个冒号分为两个字符串
  52. nameValues := strings.SplitAfterN(line, ":", 2)
  53. if len(nameValues) < 2 {
  54. continue
  55. }
  56. switch strings.ToUpper(strings.Trim(strings.Split(nameValues[0], ":")[0], " ")) {
  57. case "ST":
  58. //fmt.Println(nameValues[1])
  59. case "CACHE-CONTROL":
  60. //fmt.Println(nameValues[1])
  61. case "LOCATION":
  62. urls := strings.Split(strings.Split(nameValues[1], "//")[1], "/")
  63. upnp.GatewayHost = (urls[0])
  64. upnp.DeviceDescUrl = ("/" + urls[1])
  65. case "SERVER":
  66. upnp.GatewayName = (nameValues[1])
  67. default:
  68. }
  69. }
  70. return upnp
  71. }