example_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ipv4_test
  5. import (
  6. "log"
  7. "net"
  8. "code.google.com/p/go.net/internal/iana"
  9. "code.google.com/p/go.net/ipv4"
  10. )
  11. func ExampleUnicastTCPListener() {
  12. ln, err := net.Listen("tcp4", "0.0.0.0:1024")
  13. if err != nil {
  14. log.Fatal(err)
  15. }
  16. defer ln.Close()
  17. for {
  18. c, err := ln.Accept()
  19. if err != nil {
  20. log.Fatal(err)
  21. }
  22. go func(c net.Conn) {
  23. defer c.Close()
  24. err := ipv4.NewConn(c).SetTOS(iana.DiffServAF11)
  25. if err != nil {
  26. log.Fatal(err)
  27. }
  28. _, err = c.Write([]byte("HELLO-R-U-THERE-ACK"))
  29. if err != nil {
  30. log.Fatal(err)
  31. }
  32. }(c)
  33. }
  34. }
  35. func ExampleMulticastUDPListener() {
  36. en0, err := net.InterfaceByName("en0")
  37. if err != nil {
  38. log.Fatal(err)
  39. }
  40. en1, err := net.InterfaceByIndex(911)
  41. if err != nil {
  42. log.Fatal(err)
  43. }
  44. group := net.IPv4(224, 0, 0, 250)
  45. c, err := net.ListenPacket("udp4", "0.0.0.0:1024")
  46. if err != nil {
  47. log.Fatal(err)
  48. }
  49. defer c.Close()
  50. p := ipv4.NewPacketConn(c)
  51. err = p.JoinGroup(en0, &net.UDPAddr{IP: group})
  52. if err != nil {
  53. log.Fatal(err)
  54. }
  55. err = p.JoinGroup(en1, &net.UDPAddr{IP: group})
  56. if err != nil {
  57. log.Fatal(err)
  58. }
  59. err = p.SetControlMessage(ipv4.FlagDst, true)
  60. if err != nil {
  61. log.Fatal(err)
  62. }
  63. b := make([]byte, 1500)
  64. for {
  65. n, cm, src, err := p.ReadFrom(b)
  66. if err != nil {
  67. log.Fatal(err)
  68. }
  69. if cm.Dst.IsMulticast() {
  70. if cm.Dst.Equal(group) {
  71. // joined group, do something
  72. } else {
  73. // unknown group, discard
  74. continue
  75. }
  76. }
  77. p.SetTOS(iana.DiffServCS7)
  78. p.SetTTL(16)
  79. _, err = p.WriteTo(b[:n], nil, src)
  80. if err != nil {
  81. log.Fatal(err)
  82. }
  83. dst := &net.UDPAddr{IP: group, Port: 1024}
  84. for _, ifi := range []*net.Interface{en0, en1} {
  85. err := p.SetMulticastInterface(ifi)
  86. if err != nil {
  87. log.Fatal(err)
  88. }
  89. p.SetMulticastTTL(2)
  90. _, err = p.WriteTo(b[:n], nil, dst)
  91. if err != nil {
  92. log.Fatal(err)
  93. }
  94. }
  95. }
  96. err = p.LeaveGroup(en1, &net.UDPAddr{IP: group})
  97. if err != nil {
  98. log.Fatal(err)
  99. }
  100. newgroup := net.IPv4(224, 0, 0, 249)
  101. err = p.JoinGroup(en1, &net.UDPAddr{IP: newgroup})
  102. if err != nil {
  103. log.Fatal(err)
  104. }
  105. }
  106. type OSPFHeader struct {
  107. Version byte
  108. Type byte
  109. Len uint16
  110. RouterID uint32
  111. AreaID uint32
  112. Checksum uint16
  113. }
  114. const (
  115. OSPFHeaderLen = 14
  116. OSPFHelloHeaderLen = 20
  117. OSPF_VERSION = 2
  118. OSPF_TYPE_HELLO = iota + 1
  119. OSPF_TYPE_DB_DESCRIPTION
  120. OSPF_TYPE_LS_REQUEST
  121. OSPF_TYPE_LS_UPDATE
  122. OSPF_TYPE_LS_ACK
  123. )
  124. var (
  125. AllSPFRouters = net.IPv4(224, 0, 0, 5)
  126. AllDRouters = net.IPv4(224, 0, 0, 6)
  127. )
  128. func ExampleIPOSPFListener() {
  129. var ifs []*net.Interface
  130. en0, err := net.InterfaceByName("en0")
  131. if err != nil {
  132. log.Fatal(err)
  133. }
  134. ifs = append(ifs, en0)
  135. en1, err := net.InterfaceByIndex(911)
  136. if err != nil {
  137. log.Fatal(err)
  138. }
  139. ifs = append(ifs, en1)
  140. c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSFP for IPv4
  141. if err != nil {
  142. log.Fatal(err)
  143. }
  144. defer c.Close()
  145. r, err := ipv4.NewRawConn(c)
  146. if err != nil {
  147. log.Fatal(err)
  148. }
  149. for _, ifi := range ifs {
  150. err := r.JoinGroup(ifi, &net.IPAddr{IP: AllSPFRouters})
  151. if err != nil {
  152. log.Fatal(err)
  153. }
  154. err = r.JoinGroup(ifi, &net.IPAddr{IP: AllDRouters})
  155. if err != nil {
  156. log.Fatal(err)
  157. }
  158. }
  159. err = r.SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
  160. if err != nil {
  161. log.Fatal(err)
  162. }
  163. r.SetTOS(iana.DiffServCS6)
  164. parseOSPFHeader := func(b []byte) *OSPFHeader {
  165. if len(b) < OSPFHeaderLen {
  166. return nil
  167. }
  168. return &OSPFHeader{
  169. Version: b[0],
  170. Type: b[1],
  171. Len: uint16(b[2])<<8 | uint16(b[3]),
  172. RouterID: uint32(b[4])<<24 | uint32(b[5])<<16 | uint32(b[6])<<8 | uint32(b[7]),
  173. AreaID: uint32(b[8])<<24 | uint32(b[9])<<16 | uint32(b[10])<<8 | uint32(b[11]),
  174. Checksum: uint16(b[12])<<8 | uint16(b[13]),
  175. }
  176. }
  177. b := make([]byte, 1500)
  178. for {
  179. iph, p, _, err := r.ReadFrom(b)
  180. if err != nil {
  181. log.Fatal(err)
  182. }
  183. if iph.Version != ipv4.Version {
  184. continue
  185. }
  186. if iph.Dst.IsMulticast() {
  187. if !iph.Dst.Equal(AllSPFRouters) && !iph.Dst.Equal(AllDRouters) {
  188. continue
  189. }
  190. }
  191. ospfh := parseOSPFHeader(p)
  192. if ospfh == nil {
  193. continue
  194. }
  195. if ospfh.Version != OSPF_VERSION {
  196. continue
  197. }
  198. switch ospfh.Type {
  199. case OSPF_TYPE_HELLO:
  200. case OSPF_TYPE_DB_DESCRIPTION:
  201. case OSPF_TYPE_LS_REQUEST:
  202. case OSPF_TYPE_LS_UPDATE:
  203. case OSPF_TYPE_LS_ACK:
  204. }
  205. }
  206. }
  207. func ExampleWriteIPOSPFHello() {
  208. var ifs []*net.Interface
  209. en0, err := net.InterfaceByName("en0")
  210. if err != nil {
  211. log.Fatal(err)
  212. }
  213. ifs = append(ifs, en0)
  214. en1, err := net.InterfaceByIndex(911)
  215. if err != nil {
  216. log.Fatal(err)
  217. }
  218. ifs = append(ifs, en1)
  219. c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSPF for IPv4
  220. if err != nil {
  221. log.Fatal(err)
  222. }
  223. defer c.Close()
  224. r, err := ipv4.NewRawConn(c)
  225. if err != nil {
  226. log.Fatal(err)
  227. }
  228. for _, ifi := range ifs {
  229. err := r.JoinGroup(ifi, &net.IPAddr{IP: AllSPFRouters})
  230. if err != nil {
  231. log.Fatal(err)
  232. }
  233. err = r.JoinGroup(ifi, &net.IPAddr{IP: AllDRouters})
  234. if err != nil {
  235. log.Fatal(err)
  236. }
  237. }
  238. hello := make([]byte, OSPFHelloHeaderLen)
  239. ospf := make([]byte, OSPFHeaderLen)
  240. ospf[0] = OSPF_VERSION
  241. ospf[1] = OSPF_TYPE_HELLO
  242. ospf = append(ospf, hello...)
  243. iph := &ipv4.Header{}
  244. iph.Version = ipv4.Version
  245. iph.Len = ipv4.HeaderLen
  246. iph.TOS = iana.DiffServCS6
  247. iph.TotalLen = ipv4.HeaderLen + len(ospf)
  248. iph.TTL = 1
  249. iph.Protocol = 89
  250. iph.Dst = AllSPFRouters
  251. for _, ifi := range ifs {
  252. err := r.SetMulticastInterface(ifi)
  253. if err != nil {
  254. return
  255. }
  256. err = r.WriteTo(iph, ospf, nil)
  257. if err != nil {
  258. return
  259. }
  260. }
  261. }