Method: Socket::AncillaryData#ip_pktinfo
- Defined in:
- ancdata.c
#ip_pktinfo ⇒ Array
Extracts addr, ifindex and spec_dst from IP_PKTINFO ancillary data.
IP_PKTINFO is not standard.
Supported platform: GNU/Linux
addr = Addrinfo.ip("127.0.0.1")
ifindex = 0
spec_dest = Addrinfo.ip("127.0.0.1")
ancdata = Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dest)
p ancdata.ip_pktinfo
#=> [#<Addrinfo: 127.0.0.1>, 0, #<Addrinfo: 127.0.0.1>]
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
# File 'ancdata.c', line 485
static VALUE
ancillary_ip_pktinfo(VALUE self)
{
int level, type;
VALUE data;
struct in_pktinfo pktinfo;
struct sockaddr_in sa;
VALUE v_spec_dst, v_addr;
level = ancillary_level(self);
type = ancillary_type(self);
data = ancillary_data(self);
if (level != IPPROTO_IP || type != IP_PKTINFO ||
RSTRING_LEN(data) != sizeof(struct in_pktinfo)) {
rb_raise(rb_eTypeError, "IP_PKTINFO ancillary data expected");
}
memcpy(&pktinfo, RSTRING_PTR(data), sizeof(struct in_pktinfo));
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
memcpy(&sa.sin_addr, &pktinfo.ipi_addr, sizeof(sa.sin_addr));
v_addr = rsock_addrinfo_new((struct sockaddr *)&sa, sizeof(sa), PF_INET, 0, 0, Qnil, Qnil);
sa.sin_family = AF_INET;
memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst, sizeof(sa.sin_addr));
v_spec_dst = rsock_addrinfo_new((struct sockaddr *)&sa, sizeof(sa), PF_INET, 0, 0, Qnil, Qnil);
return rb_ary_new3(3, v_addr, UINT2NUM(pktinfo.ipi_ifindex), v_spec_dst);
}
|