diff --git a/ipv4/endpoint.go b/ipv4/endpoint.go index 27cc5808..bc45bf05 100644 --- a/ipv4/endpoint.go +++ b/ipv4/endpoint.go @@ -97,11 +97,17 @@ func (c *PacketConn) Close() error { // NewPacketConn returns a new PacketConn using c as its underlying // transport. func NewPacketConn(c net.PacketConn) *PacketConn { - return &PacketConn{ + p := &PacketConn{ genericOpt: genericOpt{Conn: c.(net.Conn)}, dgramOpt: dgramOpt{PacketConn: c}, payloadHandler: payloadHandler{PacketConn: c}, } + if _, ok := c.(*net.IPConn); ok && sockOpts[ssoStripHeader].name > 0 { + if fd, err := p.payloadHandler.sysfd(); err == nil { + setInt(fd, &sockOpts[ssoStripHeader], boolint(true)) + } + } + return p } // A RawConn represents a packet network endpoint that uses the IPv4 diff --git a/ipv4/payload_cmsg.go b/ipv4/payload_cmsg.go index 20558e70..d358fc3a 100644 --- a/ipv4/payload_cmsg.go +++ b/ipv4/payload_cmsg.go @@ -27,13 +27,19 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net. return 0, nil, nil, err } case *net.IPConn: - nb := make([]byte, maxHeaderLen+len(b)) - if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil { - return 0, nil, nil, err + if sockOpts[ssoStripHeader].name > 0 { + if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil { + return 0, nil, nil, err + } + } else { + nb := make([]byte, maxHeaderLen+len(b)) + if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil { + return 0, nil, nil, err + } + hdrlen := int(nb[0]&0x0f) << 2 + copy(b, nb[hdrlen:]) + n -= hdrlen } - hdrlen := int(nb[0]&0x0f) << 2 - copy(b, nb[hdrlen:]) - n -= hdrlen default: return 0, nil, nil, errInvalidConnType } diff --git a/ipv4/sockopt.go b/ipv4/sockopt.go index 4fdb3645..1c855537 100644 --- a/ipv4/sockopt.go +++ b/ipv4/sockopt.go @@ -15,7 +15,8 @@ const ( ssoReceiveDst // header field on received packet ssoReceiveInterface // inbound interface on received packet ssoPacketInfo // incbound or outbound packet path - ssoHeaderPrepend // ipv4 header + ssoHeaderPrepend // ipv4 header prepend + ssoStripHeader // strip ipv4 header ssoJoinGroup // any-source multicast ssoLeaveGroup // any-source multicast ssoJoinSourceGroup // source-specific multicast diff --git a/ipv4/sys_darwin.go b/ipv4/sys_darwin.go index a5331ff9..58adf829 100644 --- a/ipv4/sys_darwin.go +++ b/ipv4/sys_darwin.go @@ -58,6 +58,8 @@ func init() { ctlOpts[ctlPacketInfo].parse = parsePacketInfo sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO sockOpts[ssoPacketInfo].typ = ssoTypeInt + sockOpts[ssoStripHeader].name = sysIP_STRIPHDR + sockOpts[ssoStripHeader].typ = ssoTypeInt sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq