Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(841)

Unified Diff: ipv4/control_bsd.go

Issue 6482044: code review 6482044: go.net/ipv4: new package (Closed)
Patch Set: diff -r 2513e9008213 https://code.google.com/p/go.net Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ipv4/control.go ('k') | ipv4/control_linux.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ipv4/control_bsd.go
===================================================================
new file mode 100644
--- /dev/null
+++ b/ipv4/control_bsd.go
@@ -0,0 +1,112 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd netbsd openbsd
+
+package ipv4
+
+import (
+ "net"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
+ opt.lock()
+ defer opt.unlock()
+ if cf&FlagTTL != 0 {
+ if err := setIPv4ReceiveTTL(fd, on); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagTTL)
+ } else {
+ opt.clear(FlagTTL)
+ }
+ }
+ if cf&FlagDst != 0 {
+ if err := setIPv4ReceiveDestinationAddress(fd, on); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagDst)
+ } else {
+ opt.clear(FlagDst)
+ }
+ }
+ if cf&FlagInterface != 0 {
+ if err := setIPv4ReceiveInterface(fd, on); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagInterface)
+ } else {
+ opt.clear(FlagInterface)
+ }
+ }
+ return nil
+}
+
+func newControlMessage(opt *rawOpt) (oob []byte) {
+ opt.lock()
+ defer opt.unlock()
+ if opt.isset(FlagTTL) {
+ b := make([]byte, syscall.CmsgSpace(1))
+ cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
+ cmsg.Level = syscall.IPPROTO_IP
+ cmsg.Type = syscall.IP_RECVTTL
+ cmsg.SetLen(syscall.CmsgLen(1))
+ oob = append(oob, b...)
+ }
+ if opt.isset(FlagDst) {
+ b := make([]byte, syscall.CmsgSpace(net.IPv4len))
+ cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
+ cmsg.Level = syscall.IPPROTO_IP
+ cmsg.Type = syscall.IP_RECVDSTADDR
+ cmsg.SetLen(syscall.CmsgLen(net.IPv4len))
+ oob = append(oob, b...)
+ }
+ if opt.isset(FlagInterface) {
+ b := make([]byte, syscall.CmsgSpace(syscall.SizeofSockaddrDatalink))
+ cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
+ cmsg.Level = syscall.IPPROTO_IP
+ cmsg.Type = syscall.IP_RECVIF
+ cmsg.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
+ oob = append(oob, b...)
+ }
+ return
+}
+
+func parseControlMessage(b []byte) (*ControlMessage, error) {
+ cmsgs, err := syscall.ParseSocketControlMessage(b)
+ if err != nil {
+ return nil, os.NewSyscallError("parse socket control message", err)
+ }
+ if len(b) == 0 {
+ return nil, nil
+ }
+ cm := &ControlMessage{}
+ for _, m := range cmsgs {
+ if m.Header.Level != syscall.IPPROTO_IP {
+ continue
+ }
+ switch m.Header.Type {
+ case syscall.IP_RECVTTL:
+ cm.TTL = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
+ case syscall.IP_RECVDSTADDR:
+ v := m.Data[:4]
+ cm.Dst = net.IPv4(v[0], v[1], v[2], v[3])
+ case syscall.IP_RECVIF:
+ sadl := (*syscall.SockaddrDatalink)(unsafe.Pointer(&m.Data[0]))
+ cm.IfIndex = int(sadl.Index)
+ }
+ }
+ return cm, nil
+}
+
+func marshalControlMessage(cm *ControlMessage) []byte {
+ // TODO(mikio): Implement IP_PKTINFO stuff when OS X 10.8 comes
+ return nil
+}
« no previous file with comments | « ipv4/control.go ('k') | ipv4/control_linux.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b