getSockOptIP implements linux getsockopt(2) when the level is SOL_IP.
(t *kernel.Task, ep commonEndpoint, name int, outPtr hostarch.Addr, outLen int, _ int)
| 1636 | |
| 1637 | // getSockOptIP implements linux getsockopt(2) when the level is SOL_IP. |
| 1638 | func (s *sock) getSockOptIP(t *kernel.Task, ep commonEndpoint, name int, outPtr hostarch.Addr, outLen int, _ int) (marshal.Marshallable, *syserr.Error) { |
| 1639 | if _, ok := ep.(tcpip.Endpoint); !ok { |
| 1640 | log.Warningf("SOL_IP options not supported on endpoints other than tcpip.Endpoint: option = %d, endpoint = %T", name, ep) |
| 1641 | return nil, syserr.ErrUnknownProtocolOption |
| 1642 | } |
| 1643 | // Rejection of SOL_IP options for AF_INET6 RAW sockets matches Linux behavior: |
| 1644 | // https://github.com/torvalds/linux/blob/cec1e6e5d1a/net/ipv6/ipv6_sockglue.c#L1453 |
| 1645 | if family, skType, _ := s.Type(); family == linux.AF_INET6 && skType == linux.SOCK_RAW { |
| 1646 | return nil, syserr.ErrUnknownProtocolOption |
| 1647 | } |
| 1648 | |
| 1649 | switch name { |
| 1650 | case linux.IP_TTL: |
| 1651 | if outLen < sizeOfInt32 { |
| 1652 | return nil, syserr.ErrInvalidArgument |
| 1653 | } |
| 1654 | |
| 1655 | v, err := ep.GetSockOptInt(tcpip.IPv4TTLOption) |
| 1656 | if err != nil { |
| 1657 | return nil, syserr.TranslateNetstackError(err) |
| 1658 | } |
| 1659 | |
| 1660 | // Fill in the default value, if needed. |
| 1661 | vP := primitive.Int32(v) |
| 1662 | if vP == 0 { |
| 1663 | vP, err = defaultTTL(t, header.IPv4ProtocolNumber) |
| 1664 | if err != nil { |
| 1665 | return nil, syserr.TranslateNetstackError(err) |
| 1666 | } |
| 1667 | } |
| 1668 | |
| 1669 | return &vP, nil |
| 1670 | |
| 1671 | case linux.IP_RECVTTL: |
| 1672 | if outLen < sizeOfInt32 { |
| 1673 | return nil, syserr.ErrInvalidArgument |
| 1674 | } |
| 1675 | |
| 1676 | v := primitive.Int32(boolToInt32(ep.SocketOptions().GetReceiveTTL())) |
| 1677 | return &v, nil |
| 1678 | |
| 1679 | case linux.IP_MULTICAST_TTL: |
| 1680 | if outLen < sizeOfInt32 { |
| 1681 | return nil, syserr.ErrInvalidArgument |
| 1682 | } |
| 1683 | |
| 1684 | v, err := ep.GetSockOptInt(tcpip.MulticastTTLOption) |
| 1685 | if err != nil { |
| 1686 | return nil, syserr.TranslateNetstackError(err) |
| 1687 | } |
| 1688 | |
| 1689 | vP := primitive.Int32(v) |
| 1690 | return &vP, nil |
| 1691 | |
| 1692 | case linux.IP_MULTICAST_IF: |
| 1693 | if outLen < len(linux.InetAddr{}) { |
| 1694 | return nil, syserr.ErrInvalidArgument |
| 1695 | } |
no test coverage detected