1
// Copyright 2014 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.
5
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
15
"golang.org/x/net/internal/iana"
16
"golang.org/x/net/ipv4"
17
"golang.org/x/net/ipv6"
20
const sysIP_STRIPHDR = 0x17 // for now only darwin supports this option
22
// ListenPacket listens for incoming ICMP packets addressed to
23
// address. See net.Dial for the syntax of address.
25
// For non-privileged datagram-oriented ICMP endpoints, network must
26
// be "udp4" or "udp6". The endpoint allows to read, write a few
27
// limited ICMP messages such as echo request and echo reply.
28
// Currently only Darwin and Linux support this.
31
// ListenPacket("udp4", "192.168.0.1")
32
// ListenPacket("udp4", "0.0.0.0")
33
// ListenPacket("udp6", "fe80::1%en0")
34
// ListenPacket("udp6", "::")
36
// For privileged raw ICMP endpoints, network must be "ip4" or "ip6"
37
// followed by a colon and an ICMP protocol number or name.
40
// ListenPacket("ip4:icmp", "192.168.0.1")
41
// ListenPacket("ip4:1", "0.0.0.0")
42
// ListenPacket("ip6:ipv6-icmp", "fe80::1%en0")
43
// ListenPacket("ip6:58", "::")
44
func ListenPacket(network, address string) (*PacketConn, error) {
48
family, proto = syscall.AF_INET, iana.ProtocolICMP
50
family, proto = syscall.AF_INET6, iana.ProtocolIPv6ICMP
52
i := last(network, ':')
55
proto = iana.ProtocolICMP
57
proto = iana.ProtocolIPv6ICMP
63
case syscall.AF_INET, syscall.AF_INET6:
64
s, err := syscall.Socket(family, syscall.SOCK_DGRAM, proto)
66
return nil, os.NewSyscallError("socket", err)
68
defer syscall.Close(s)
69
if runtime.GOOS == "darwin" && family == syscall.AF_INET {
70
if err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil {
71
return nil, os.NewSyscallError("setsockopt", err)
74
sa, err := sockaddr(family, address)
78
if err := syscall.Bind(s, sa); err != nil {
79
return nil, os.NewSyscallError("bind", err)
81
f := os.NewFile(uintptr(s), "datagram-oriented icmp")
83
c, cerr = net.FilePacketConn(f)
85
c, cerr = net.ListenPacket(network, address)
91
case iana.ProtocolICMP:
92
return &PacketConn{c: c, ipc: ipv4.NewPacketConn(c)}, nil
93
case iana.ProtocolIPv6ICMP:
94
return &PacketConn{c: c, ipc: ipv6.NewPacketConn(c)}, nil
96
return &PacketConn{c: c}, nil