mapping.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package upnp
  2. import (
  3. "bytes"
  4. "net/http"
  5. "strconv"
  6. "strings"
  7. loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
  8. "github.com/pkg/errors"
  9. )
  10. //
  11. ////添加一个端口映射
  12. func (n *Upnp) AddPortMapping(localPort, remotePort int, protocol string) (err error) {
  13. defer func() {
  14. if errTemp := recover(); errTemp != nil {
  15. loger2.NewOLoger().Error("upnp模块报错了", errTemp)
  16. }
  17. }()
  18. if isSuccess := addSend(localPort, remotePort, protocol, n.GatewayHost, n.CtrlUrl, n.LocalHost); isSuccess {
  19. return nil
  20. } else {
  21. return errors.New("添加一个端口映射失败")
  22. }
  23. }
  24. func addSend(localPort, remotePort int, protocol, host, ctrUrl, localHost string) bool {
  25. request := addRequest(localPort, remotePort, protocol, host, ctrUrl, localHost)
  26. response, _ := http.DefaultClient.Do(request)
  27. defer response.Body.Close()
  28. //resultBody, _ := ioutil.ReadAll(response.Body)
  29. //fmt.Println(string(resultBody))
  30. return response.StatusCode == 200
  31. }
  32. type Node struct {
  33. Name string
  34. Content string
  35. Attr map[string]string
  36. Child []Node
  37. }
  38. func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl, localHost string) *http.Request {
  39. //请求头
  40. header := http.Header{}
  41. header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
  42. header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"`)
  43. header.Set("Content-Type", "text/xml")
  44. header.Set("Connection", "Close")
  45. header.Set("Content-Length", "")
  46. //请求体
  47. body := Node{Name: "SOAP-ENV:Envelope",
  48. Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
  49. "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
  50. childOne := Node{Name: `SOAP-ENV:Body`}
  51. childTwo := Node{Name: `m:AddPortMapping`,
  52. Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
  53. childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
  54. childList2 := Node{Name: "NewInternalPort", Content: strconv.Itoa(localPort)}
  55. childList3 := Node{Name: "NewProtocol", Content: protocol}
  56. childList4 := Node{Name: "NewEnabled", Content: "1"}
  57. childList5 := Node{Name: "NewInternalClient", Content: localHost}
  58. childList6 := Node{Name: "NewLeaseDuration", Content: "0"}
  59. childList7 := Node{Name: "NewPortMappingDescription", Content: "Oasis"}
  60. childList8 := Node{Name: "NewRemoteHost"}
  61. childTwo.AddChild(childList1)
  62. childTwo.AddChild(childList2)
  63. childTwo.AddChild(childList3)
  64. childTwo.AddChild(childList4)
  65. childTwo.AddChild(childList5)
  66. childTwo.AddChild(childList6)
  67. childTwo.AddChild(childList7)
  68. childTwo.AddChild(childList8)
  69. childOne.AddChild(childTwo)
  70. body.AddChild(childOne)
  71. bodyStr := body.BuildXML()
  72. //请求
  73. request, _ := http.NewRequest("POST", "http://"+gatewayHost+ctlUrl,
  74. strings.NewReader(bodyStr))
  75. request.Header = header
  76. request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
  77. return request
  78. }
  79. func (n *Node) AddChild(node Node) {
  80. n.Child = append(n.Child, node)
  81. }
  82. func (n *Node) BuildXML() string {
  83. buf := bytes.NewBufferString("<")
  84. buf.WriteString(n.Name)
  85. for key, value := range n.Attr {
  86. buf.WriteString(" ")
  87. buf.WriteString(key + "=" + value)
  88. }
  89. buf.WriteString(">" + n.Content)
  90. for _, node := range n.Child {
  91. buf.WriteString(node.BuildXML())
  92. }
  93. buf.WriteString("</" + n.Name + ">")
  94. return buf.String()
  95. }
  96. func (n *Upnp) DelPortMapping(remotePort int, protocol string) bool {
  97. isSuccess := delSendSend(remotePort, protocol, n.GatewayHost, n.CtrlUrl)
  98. if isSuccess {
  99. //this.MappingPort.delMapping(remotePort, protocol)
  100. //fmt.Println("删除了一个端口映射: remote:", remotePort)
  101. }
  102. return isSuccess
  103. }
  104. func delSendSend(remotePort int, protocol, host, ctlUrl string) bool {
  105. delrequest := delbuildRequest(remotePort, protocol, host, ctlUrl)
  106. response, _ := http.DefaultClient.Do(delrequest)
  107. //resultBody, _ := ioutil.ReadAll(response.Body)
  108. defer response.Body.Close()
  109. return response.StatusCode == 200
  110. }
  111. func delbuildRequest(remotePort int, protocol, host, ctlUrl string) *http.Request {
  112. //请求头
  113. header := http.Header{}
  114. header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
  115. header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"`)
  116. header.Set("Content-Type", "text/xml")
  117. header.Set("Connection", "Close")
  118. header.Set("Content-Length", "")
  119. //请求体
  120. body := Node{Name: "SOAP-ENV:Envelope",
  121. Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
  122. "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
  123. childOne := Node{Name: `SOAP-ENV:Body`}
  124. childTwo := Node{Name: `m:DeletePortMapping`,
  125. Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
  126. childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
  127. childList2 := Node{Name: "NewProtocol", Content: protocol}
  128. childList3 := Node{Name: "NewRemoteHost"}
  129. childTwo.AddChild(childList1)
  130. childTwo.AddChild(childList2)
  131. childTwo.AddChild(childList3)
  132. childOne.AddChild(childTwo)
  133. body.AddChild(childOne)
  134. bodyStr := body.BuildXML()
  135. //请求
  136. request, _ := http.NewRequest("POST", "http://"+host+ctlUrl,
  137. strings.NewReader(bodyStr))
  138. request.Header = header
  139. request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
  140. return request
  141. }