packet_go1_9.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright 2017 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. // +build go1.9
  5. package ipv4
  6. import (
  7. "net"
  8. "golang.org/x/net/internal/socket"
  9. )
  10. func (c *packetHandler) readFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {
  11. c.rawOpt.RLock()
  12. m := socket.Message{
  13. Buffers: [][]byte{b},
  14. OOB: NewControlMessage(c.rawOpt.cflags),
  15. }
  16. c.rawOpt.RUnlock()
  17. if err := c.RecvMsg(&m, 0); err != nil {
  18. return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  19. }
  20. var hs []byte
  21. if hs, p, err = slicePacket(b[:m.N]); err != nil {
  22. return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  23. }
  24. if h, err = ParseHeader(hs); err != nil {
  25. return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  26. }
  27. if m.NN > 0 {
  28. cm = new(ControlMessage)
  29. if err := cm.Parse(m.OOB[:m.NN]); err != nil {
  30. return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  31. }
  32. }
  33. if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil {
  34. cm.Src = src.IP
  35. }
  36. return
  37. }
  38. func (c *packetHandler) writeTo(h *Header, p []byte, cm *ControlMessage) error {
  39. m := socket.Message{
  40. OOB: cm.Marshal(),
  41. }
  42. wh, err := h.Marshal()
  43. if err != nil {
  44. return err
  45. }
  46. m.Buffers = [][]byte{wh, p}
  47. dst := new(net.IPAddr)
  48. if cm != nil {
  49. if ip := cm.Dst.To4(); ip != nil {
  50. dst.IP = ip
  51. }
  52. }
  53. if dst.IP == nil {
  54. dst.IP = h.Dst
  55. }
  56. m.Addr = dst
  57. if err := c.SendMsg(&m, 0); err != nil {
  58. return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err}
  59. }
  60. return nil
  61. }