📄 rfc2133.txt
字号:
This API uses an interface index (a small positive integer) to
identify the local interface on which a multicast group is joined
(Section 5.3). Additionally, the advanced API [5] uses these same
interface indexes to identify the interface on which a datagram is
received, or to specify the interface on which a datagram is to be
sent.
Interfaces are normally known by names such as "le0", "sl1", "ppp2",
and the like. On Berkeley-derived implementations, when an interface
is made known to the system, the kernel assigns a unique positive
integer value (called the interface index) to that interface. These
are small positive integers that start at 1. (Note that 0 is never
used for an interface index.) There may be gaps so that there is no
current interface for a particular positive interface index.
Gilligan, et. al. Informational [Page 12]
RFC 2133 IPv6 Socket Interface Extensions April 1997
This API defines two functions that map between an interface name and
index, a third function that returns all the interface names and
indexes, and a fourth function to return the dynamic memory allocated
by the previous function. How these functions are implemented is
left up to the implementation. 4.4BSD implementations can implement
these functions using the existing sysctl() function with the
NET_RT_LIST command. Other implementations may wish to use ioctl()
for this purpose.
4.1. Name-to-Index
The first function maps an interface name into its corresponding
index.
#include <net/if.h>
unsigned int if_nametoindex(const char *ifname);
If the specified interface does not exist, the return value is 0.
4.2. Index-to-Name
The second function maps an interface index into its corresponding
name.
#include <net/if.h>
char *if_indextoname(unsigned int ifindex, char *ifname);
The ifname argument must point to a buffer of at least IFNAMSIZ bytes
into which the interface name corresponding to the specified index is
returned. (IFNAMSIZ is also defined in <net/if.h> and its value
includes a terminating null byte at the end of the interface name.)
This pointer is also the return value of the function. If there is
no interface corresponding to the specified index, NULL is returned.
Gilligan, et. al. Informational [Page 13]
RFC 2133 IPv6 Socket Interface Extensions April 1997
4.3. Return All Interface Names and Indexes
The final function returns an array of if_nameindex structures, one
structure per interface.
#include <net/if.h>
struct if_nameindex {
unsigned int if_index; /* 1, 2, ... */
char *if_name; /* null terminated name: "le0", ... */
};
struct if_nameindex *if_nameindex(void);
The end of the array of structures is indicated by a structure with
an if_index of 0 and an if_name of NULL. The function returns a NULL
pointer upon an error.
The memory used for this array of structures along with the interface
names pointed to by the if_name members is obtained dynamically.
This memory is freed by the next function.
4.4. Free Memory
The following function frees the dynamic memory that was allocated by
if_nameindex().
#include <net/if.h>
void if_freenameindex(struct if_nameindex *ptr);
The argument to this function must be a pointer that was returned by
if_nameindex().
5. Socket Options
A number of new socket options are defined for IPv6. All of these
new options are at the IPPROTO_IPV6 level. That is, the "level"
parameter in the getsockopt() and setsockopt() calls is IPPROTO_IPV6
when using these options. The constant name prefix IPV6_ is used in
all of the new socket options. This serves to clearly identify these
options as applying to IPv6.
The declaration for IPPROTO_IPV6, the new IPv6 socket options, and
related constants defined in this section are obtained by including
the header <netinet/in.h>.
Gilligan, et. al. Informational [Page 14]
RFC 2133 IPv6 Socket Interface Extensions April 1997
5.1. Changing Socket Type
Unix allows open sockets to be passed between processes via the
exec() call and other means. It is a relatively common application
practice to pass open sockets across exec() calls. Thus it is
possible for an application using the original API to pass an open
PF_INET socket to an application that is expecting to receive a
PF_INET6 socket. Similarly, it is possible for an application using
the extended API to pass an open PF_INET6 socket to an application
using the original API, which would be equipped only to deal with
PF_INET sockets. Either of these cases could cause problems, because
the application that is passed the open socket might not know how to
decode the address structures returned in subsequent socket
functions.
To remedy this problem, a new setsockopt() option is defined that
allows an application to "convert" a PF_INET6 socket into a PF_INET
socket and vice versa.
An IPv6 application that is passed an open socket from an unknown
process may use the IPV6_ADDRFORM setsockopt() option to "convert"
the socket to PF_INET6. Once that has been done, the system will
return sockaddr_in6 address structures in subsequent socket
functions.
An IPv6 application that is about to pass an open PF_INET6 socket to
a program that is not be IPv6 capable can "downgrade" the socket to
PF_INET before calling exec(). After that, the system will return
sockaddr_in address structures to the application that was exec()'ed.
Be aware that you cannot downgrade an IPv6 socket to an IPv4 socket
unless all nonwildcard addresses already associated with the IPv6
socket are IPv4-mapped IPv6 addresses.
The IPV6_ADDRFORM option is valid at both the IPPROTO_IP and
IPPROTO_IPV6 levels. The only valid option values are PF_INET6 and
PF_INET. For example, to convert a PF_INET6 socket to PF_INET, a
program would call:
int addrform = PF_INET;
if (setsockopt(s, IPPROTO_IPV6, IPV6_ADDRFORM,
(char *) &addrform, sizeof(addrform)) == -1)
perror("setsockopt IPV6_ADDRFORM");
Gilligan, et. al. Informational [Page 15]
RFC 2133 IPv6 Socket Interface Extensions April 1997
An application may use IPV6_ADDRFORM with getsockopt() to learn
whether an open socket is a PF_INET of PF_INET6 socket. For example:
int addrform;
size_t len = sizeof(addrform);
if (getsockopt(s, IPPROTO_IPV6, IPV6_ADDRFORM,
(char *) &addrform, &len) == -1)
perror("getsockopt IPV6_ADDRFORM");
else if (addrform == PF_INET)
printf("This is an IPv4 socket.\n");
else if (addrform == PF_INET6)
printf("This is an IPv6 socket.\n");
else
printf("This system is broken.\n");
5.2. Unicast Hop Limit
A new setsockopt() option controls the hop limit used in outgoing
unicast IPv6 packets. The name of this option is IPV6_UNICAST_HOPS,
and it is used at the IPPROTO_IPV6 layer. The following example
illustrates how it is used:
int hoplimit = 10;
if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
(char *) &hoplimit, sizeof(hoplimit)) == -1)
perror("setsockopt IPV6_UNICAST_HOPS");
When the IPV6_UNICAST_HOPS option is set with setsockopt(), the
option value given is used as the hop limit for all subsequent
unicast packets sent via that socket. If the option is not set, the
system selects a default value. The integer hop limit value (called
x) is interpreted as follows:
x < -1: return an error of EINVAL
x == -1: use kernel default
0 <= x <= 255: use x
x >= 256: return an error of EINVAL
Gilligan, et. al. Informational [Page 16]
RFC 2133 IPv6 Socket Interface Extensions April 1997
The IPV6_UNICAST_HOPS option may be used with getsockopt() to
determine the hop limit value that the system will use for subsequent
unicast packets sent via that socket. For example:
int hoplimit;
size_t len = sizeof(hoplimit);
if (getsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
(char *) &hoplimit, &len) == -1)
perror("getsockopt IPV6_UNICAST_HOPS");
else
printf("Using %d for hop limit.\n", hoplimit);
5.3. Sending and Receiving Multicast Packets
IPv6 applications may send UDP multicast packets by simply specifying
an IPv6 multicast address in the address argument of the sendto()
function.
Three socket options at the IPPROTO_IPV6 layer control some of the
parameters for sending multicast packets. Setting these options is
not required: applications may send multicast packets without using
these options. The setsockopt() options for controlling the sending
of multicast packets are summarized below:
IPV6_MULTICAST_IF
Set the interface to use for outgoing multicast packets. The
argument is the index of the interface to use.
Argument type: unsigned int
IPV6_MULTICAST_HOPS
Set the hop limit to use for outgoing multicast packets.
(Note a separate option - IPV6_UNICAST_HOPS - is provided to
set the hop limit to use for outgoing unicast packets.) The
interpretation of the argument is the same as for the
IPV6_UNICAST_HOPS option:
x < -1: return an error of EINVAL
x == -1: use kernel default
0 <= x <= 255: use x
x >= 256: return an error of EINVAL
Argument type: int
Gilligan, et. al. Informational [Page 17]
RFC 2133 IPv6 Socket Interface Extensions April 1997
IPV6_MULTICAST_LOOP
Controls whether outgoing multicast packets sent should be
delivered back to the local application. A toggle. If the
option is set to 1, multicast packets are looped back. If it
is set to 0, they are not.
Argument type: unsigned int
The reception of multicast packets is controlled by the two
setsockopt() options summarized below:
IPV6_ADD_MEMBERSHIP
Join a multicast group on a specified local interface. If
the interface index is specified as 0, the kernel chooses the
local interface. For example, some kernels look up the
multicast group in the normal IPv6 routing table and using
the resulting interface.
Argument type: struct ipv6_mreq
IPV6_DROP_MEMBERSHIP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -