52
52
func newControlMessage(opt *rawOpt) (oob []byte) {
55
56
if opt.isset(FlagTTL) {
56
b := make([]byte, syscall.CmsgSpace(1))
57
cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
58
cmsg.Level = syscall.IPPROTO_IP
59
cmsg.Type = syscall.IP_RECVTTL
60
cmsg.SetLen(syscall.CmsgLen(1))
61
oob = append(oob, b...)
57
l += syscall.CmsgSpace(1)
63
59
if opt.isset(FlagDst) {
64
b := make([]byte, syscall.CmsgSpace(net.IPv4len))
65
cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
66
cmsg.Level = syscall.IPPROTO_IP
67
cmsg.Type = syscall.IP_RECVDSTADDR
68
cmsg.SetLen(syscall.CmsgLen(net.IPv4len))
69
oob = append(oob, b...)
60
l += syscall.CmsgSpace(net.IPv4len)
71
62
if opt.isset(FlagInterface) {
72
b := make([]byte, syscall.CmsgSpace(syscall.SizeofSockaddrDatalink))
73
cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
74
cmsg.Level = syscall.IPPROTO_IP
75
cmsg.Type = syscall.IP_RECVIF
76
cmsg.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
77
oob = append(oob, b...)
63
l += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink)
67
if opt.isset(FlagTTL) {
68
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
69
m.Level = ianaProtocolIP
70
m.Type = syscall.IP_RECVTTL
71
m.SetLen(syscall.CmsgLen(1))
72
off += syscall.CmsgSpace(1)
74
if opt.isset(FlagDst) {
75
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
76
m.Level = ianaProtocolIP
77
m.Type = syscall.IP_RECVDSTADDR
78
m.SetLen(syscall.CmsgLen(net.IPv4len))
79
off += syscall.CmsgSpace(net.IPv4len)
81
if opt.isset(FlagInterface) {
82
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
83
m.Level = ianaProtocolIP
84
m.Type = syscall.IP_RECVIF
85
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
86
off += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink)
82
92
func parseControlMessage(b []byte) (*ControlMessage, error) {
83
96
cmsgs, err := syscall.ParseSocketControlMessage(b)
85
98
return nil, os.NewSyscallError("parse socket control message", err)
90
100
cm := &ControlMessage{}
91
101
for _, m := range cmsgs {
92
if m.Header.Level != syscall.IPPROTO_IP {
102
if m.Header.Level != ianaProtocolIP {
95
105
switch m.Header.Type {
96
106
case syscall.IP_RECVTTL:
97
107
cm.TTL = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
98
108
case syscall.IP_RECVDSTADDR:
100
cm.Dst = net.IPv4(v[0], v[1], v[2], v[3])
109
cm.Dst = m.Data[:net.IPv4len]
101
110
case syscall.IP_RECVIF:
102
111
sadl := (*syscall.SockaddrDatalink)(unsafe.Pointer(&m.Data[0]))
103
112
cm.IfIndex = int(sadl.Index)