|
NAMEip —
Internet Protocol
SYNOPSIS#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int
DESCRIPTIONIP is the transport layer protocol used by the Internet protocol family. Options may be set at the IP level when using higher-level protocols that are based on IP (such as TCP and UDP). It may also be accessed through a “raw socket” when developing new protocols, or special-purpose applications.There are several IP-level
setsockopt(2)
and
getsockopt(2)
options. setsockopt(s, IPPROTO_IP, IP_OPTIONS, NULL, 0);
int tos = IPTOS_LOWDELAY; /* see <netinet/ip.h> */ setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); int ttl = 60; /* max = 255 */ setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
const char *policy = "in ipsec ah/transport//require"; char *buf = ipsec_set_policy(policy, strlen(policy)); setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, buf, ipsec_get_policylen(buf));
If the cmsg_len = CMSG_LEN(sizeof(struct sockaddr_in)) cmsg_level = IPPROTO_IP cmsg_type = IP_ORIGDSTADDR If the cmsg_len = CMSG_LEN(sizeof(struct in_addr)) cmsg_level = IPPROTO_IP cmsg_type = IP_RECVDSTADDR The source address to be used for outgoing UDP datagrams on a
socket can be specified as ancillary data with a type code of
cmsg_len = CMSG_LEN(sizeof(struct in_addr)) cmsg_level = IPPROTO_IP cmsg_type = IP_SENDSRCADDR The socket should be either bound to
For convenience, If the This option allows applications to choose which interface is used to transmit an undirected broadcast datagram. For example, the following code would force an undirected broadcast to be transmitted via the interface configured with the broadcast address 192.168.2.255: char msg[512]; struct sockaddr_in sin; int onesbcast = 1; /* 0 = disable (default), 1 = enable */ setsockopt(s, IPPROTO_IP, IP_ONESBCAST, &onesbcast, sizeof(onesbcast)); sin.sin_addr.s_addr = inet_addr("192.168.2.255"); sin.sin_port = htons(1234); sendto(s, msg, sizeof(msg), 0, &sin, sizeof(sin)); It is the application's responsibility to set the
If the If the cmsg_len = CMSG_LEN(sizeof(u_char)) cmsg_level = IPPROTO_IP cmsg_type = IP_RECVTTL If the cmsg_len = CMSG_LEN(sizeof(u_char)) cmsg_level = IPPROTO_IP cmsg_type = IP_RECVTOS If the cmsg_len = CMSG_LEN(sizeof(struct sockaddr_dl)) cmsg_level = IPPROTO_IP cmsg_type = IP_RECVIF
The range of privileged ports which only may be opened by
root-owned processes may be modified by the
net.inet.ip.portrange.reservedlow and
net.inet.ip.portrange.reservedhigh sysctl settings.
The values default to the traditional range, 0 through
Ports are allocated at random within the specified port range in order to increase the difficulty of random spoofing attacks. In scenarios such as benchmarking, this behavior may be undesirable. In these cases, net.inet.ip.portrange.randomized can be used to toggle randomization off. If more than net.inet.ip.portrange.randomcps ports have been allocated in the last second, then return to sequential port allocation. Return to random allocation only once the current port allocation rate drops below net.inet.ip.portrange.randomcps for at least net.inet.ip.portrange.randomtime seconds. The default values for net.inet.ip.portrange.randomcps and net.inet.ip.portrange.randomtime are 10 port allocations per second and 45 seconds correspondingly. Multicast OptionsIP multicasting is supported only onAF_INET sockets of
type SOCK_DGRAM and SOCK_RAW ,
and only on networks where the interface driver supports multicasting.
The u_char ttl; /* range: 0 to 255, default = 1 */ setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); Datagrams with a TTL of 1 are not forwarded beyond the local network. Multicast datagrams with a TTL of 0 will not be transmitted on any network, but may be delivered locally if the sending host belongs to the destination group and if multicast loopback has not been disabled on the sending socket (see below). Multicast datagrams with TTL greater than 1 may be forwarded to other networks if a multicast router is attached to the local network. For hosts with multiple interfaces, where an interface has not
been specified for a multicast group membership, each multicast transmission
is sent from the primary network interface. The
struct in_addr addr; setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)); where "addr" is the local IP address of the desired
interface or To specify an interface by index, an instance of ip_mreqn may be passed instead. The imr_ifindex member should be set to the index of the desired interface, or 0 to specify the default interface. The kernel differentiates between these two structures by their size. The use of IP_MULTICAST_IF is not recommended, as multicast memberships are scoped to each individual interface. It is supported for legacy use only by applications, such as routing daemons, which expect to be able to transmit link-local IPv4 multicast datagrams (224.0.0.0/24) on multiple interfaces, without requesting an individual membership for each interface. An interface's local IP address and multicast capability can be
obtained via the If a multicast datagram is sent to a group to which the sending
host itself belongs (on the outgoing interface), a copy of the datagram is,
by default, looped back by the IP layer for local delivery. The
u_char loop; /* 0 = disable, 1 = enable (default) */ setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); This option improves performance for applications that may have no more than one instance on a single host (such as a routing daemon), by eliminating the overhead of receiving their own transmissions. It should generally not be used by applications for which there may be more than one instance on a single host (such as a conferencing program) or for which the sender does not belong to the destination group (such as a time querying program). The sysctl setting net.inet.ip.mcast.loop
controls the default setting of the
A multicast datagram sent with an initial TTL greater than 1 may be delivered to the sending host on a different interface from that on which it was sent, if the host belongs to the destination group on that other interface. The loopback control option has no effect on such delivery. A host must become a member of a multicast group before it can
receive datagrams sent to the group. To join a multicast group, use the
struct ip_mreqn mreqn; setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, sizeof(mreqn)); where mreqn is the following structure: struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_interface; /* local IP address of interface */ int imr_ifindex; /* interface index */ } imr_ifindex should be set to the index of a particular multicast-capable interface if the host is multihomed. If imr_ifindex is non-zero, value of imr_interface is ignored. Otherwise, if imr_ifindex is 0, kernel will use IP address from imr_interface to lookup the interface. Value of imr_interface may be set to INADDR_ANY to choose the default interface, although this is not recommended; this is considered to be the first interface corresponding to the default route. Otherwise, the first multicast-capable interface configured in the system will be used. Legacy struct ip_mreq, that lacks
imr_ifindex field is also supported by
Prior to FreeBSD 7.0, if the
imr_interface member is within the network range
Up to To drop a membership, use: struct ip_mreq mreq; setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); where mreq contains the same values as used to add the membership. Memberships are dropped when the socket is closed or the process exits. The IGMP protocol uses the primary IP address of the interface as its identifier for group membership. This is the first IP address configured on the interface. If this address is removed or changed, the results are undefined, as the IGMP membership state will then be inconsistent. If multiple IP aliases are configured on the same interface, they will be ignored. This shortcoming was addressed in IPv6; MLDv2 requires that the unique link-local address for an interface is used to identify an MLDv2 listener. Source-Specific Multicast OptionsSince FreeBSD 8.0, the use of Source-Specific Multicast (SSM) is supported. These extensions require an IGMPv3 multicast router in order to make best use of them. If a legacy multicast router is present on the link, FreeBSD will simply downgrade to the version of IGMP spoken by the router, and the benefits of source filtering on the upstream link will not be present, although the kernel will continue to squelch transmissions from blocked sources.Each group membership on a socket now has a filter mode:
Groups joined using the legacy
To block a multicast source on an existing group membership: struct ip_mreq_source mreqs; setsockopt(s, IPPROTO_IP, IP_BLOCK_SOURCE, &mreqs, sizeof(mreqs)); where mreqs is the following structure: struct ip_mreq_source { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_sourceaddr; /* IP address of source */ struct in_addr imr_interface; /* local IP address of interface */ } To unblock a multicast source on an existing group: struct ip_mreq_source mreqs; setsockopt(s, IPPROTO_IP, IP_UNBLOCK_SOURCE, &mreqs, sizeof(mreqs)); The To join a multicast group in struct ip_mreq_source mreqs; setsockopt(s, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, &mreqs, sizeof(mreqs)); To leave a single source from an existing group in inclusive mode: struct ip_mreq_source mreqs; setsockopt(s, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, &mreqs, sizeof(mreqs)); The The sysctl settings net.inet.ip.mcast.maxsocksrc and net.inet.ip.mcast.maxgrpsrc are used to specify an upper limit on the number of per-socket and per-group source filter entries which the kernel may allocate. Raw IP SocketsRaw IP sockets are connectionless, and are normally used with the sendto(2) and recvfrom(2) calls, though the connect(2) call may also be used to fix the destination for future packets (in which case the read(2) or recv(2) and write(2) or send(2) system calls may be used).If proto is 0, the default protocol
Outgoing packets automatically have an IP header prepended to them
(based on the destination address and the protocol number the socket is
created with), unless the
#include <netinet/in_systm.h> #include <netinet/ip.h> int hincl = 1; /* 1 = on, 0 = off */ setsockopt(s, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl)); Unlike previous BSD releases, the program must set all the fields of the IP header, including the following: ip->ip_v = IPVERSION; ip->ip_hl = hlen >> 2; ip->ip_id = 0; /* 0 means kernel set appropriate value */ ip->ip_off = htons(offset); ip->ip_len = htons(len); The packet should be provided as is to be sent over wire. This
implies all fields, including ip_len and
ip_off to be in network byte order. See
byteorder(3)
for more information on network byte order. If the
ip_id field is set to 0 then the kernel will choose an
appropriate value. If the header source address is set to
ERRORSA socket operation may fail with one of the following errors returned:
The following errors specific to IP may occur when setting or getting IP options:
The following errors may occur when attempting to send IP
datagrams via a “raw socket” with the
SEE ALSOgetsockopt(2), recv(2), send(2), byteorder(3), CMSG_DATA(3), sourcefilter(3), icmp(4), igmp(4), inet(4), intro(4), multicast(4)D. Thaler, B. Fenner, and B. Quinn, Socket Interface Extensions for Multicast Source Filters, RFC 3678, Jan 2004. HISTORYTheip protocol appeared in
4.2BSD. The ip_mreqn structure
appeared in Linux 2.4.
BUGSBefore FreeBSD 10.0 packets received on raw IP sockets had the ip_hl subtracted from the ip_len field.Before FreeBSD 11.0 packets received on raw IP sockets had the ip_len and ip_off fields converted to host byte order. Packets written to raw IP sockets were expected to have ip_len and ip_off in host byte order.
Visit the GSP FreeBSD Man Page Interface. |