Socket-Packet

 view release on metacpan or  search on metacpan

lib/Socket/Packet.xs  view on Meta::CPAN

             int    ifindex
    unsigned short  hatype
    unsigned char   pkttype
    SV             *addr

  PREINIT:
    struct sockaddr_ll sll;
    char *addrbytes;
    STRLEN addrlen;

  PPCODE:
    if (DO_UTF8(addr) && !sv_utf8_downgrade(addr, 1))
      croak("Wide character in Socket::Packet::pack_sockaddr_ll");

    addrbytes = SvPVbyte(addr, addrlen);

    if(addrlen > sll_maxaddr)
      croak("addr too long; should be no more than %d bytes, found %d", sll_maxaddr, addrlen);

    sll.sll_family   = AF_PACKET;
    sll.sll_protocol = htons(protocol);

lib/Socket/Packet.xs  view on Meta::CPAN


void
unpack_sockaddr_ll(sa)
    SV * sa

  PREINIT:
    STRLEN sa_len;
    char *sa_bytes;
    struct sockaddr_ll sll;

  PPCODE:
    /* variable size of structure, because of variable length of addr bytes */
    sa_bytes = SvPVbyte(sa, sa_len);
    if(sa_len < sll_min)
      croak("Socket address too small; found %d bytes, expected at least %d", sa_len, sll_min);
    if(sa_len > sll_max)
      croak("Socket address too big; found %d bytes, expected at most %d", sa_len, sll_max);

    Copy(sa_bytes, &sll, sizeof sll, char);

    if(sa_len < sll_min + sll.sll_halen)

lib/Socket/Packet.xs  view on Meta::CPAN

pack_packet_mreq(ifindex, type, addr)
    int            ifindex
    unsigned short type
    SV *           addr

  PREINIT:
    struct packet_mreq mreq;
    char  *addr_bytes;
    STRLEN addr_len;

  PPCODE:
    if (DO_UTF8(addr) && !sv_utf8_downgrade(addr, 1))
      croak("Wide character in Socket::Packet::pack_sockaddr_ll");

    addr_bytes = SvPVbyte(addr, addr_len);

    if(addr_len > sizeof(mreq.mr_address))
      croak("addr too long; should be no more than %d bytes, found %d", sizeof(mreq.mr_address), addr_len);

    mreq.mr_ifindex = ifindex;
    mreq.mr_type    = type;

lib/Socket/Packet.xs  view on Meta::CPAN


void
unpack_packet_mreq(data)
    SV * data

  PREINIT:
    STRLEN data_len;
    char *data_bytes;
    struct packet_mreq mreq;

  PPCODE:
    data_bytes = SvPVbyte(data, data_len);
    if(data_len != sizeof(mreq))
      croak("packet_mreq buffer incorrect size; found %d bytes, expected %d", data_len, sizeof(mreq));

    Copy(data_bytes, &mreq, data_len, char);

    if(mreq.mr_alen > sizeof(mreq.mr_address))
      croak("packet_mreq claims to have a larger address than it has space for");

    EXTEND(SP, 3);

lib/Socket/Packet.xs  view on Meta::CPAN


void
unpack_tpacket_stats(stats)
    SV * stats

  PREINIT:
    STRLEN stats_len;
    char *stats_bytes;
    struct tpacket_stats statsbuf;

  PPCODE:
    stats_bytes = SvPVbyte(stats, stats_len);
    if(stats_len != sizeof(statsbuf))
      croak("tpacket_stats buffer incorrect size; found %d bytes, expected %d", stats_len, sizeof(statsbuf));

    Copy(stats_bytes, &statsbuf, stats_len, char);

    EXTEND(SP, 5);
    mPUSHi(statsbuf.tp_packets);
    mPUSHi(statsbuf.tp_drops);

void
siocgstamp(sock)
  InputStream sock
  PROTOTYPE: $

  PREINIT:
    int fd;
    int result;
    struct timeval tv;

  PPCODE:
    fd = PerlIO_fileno(sock);
    if(ioctl(fd, SIOCGSTAMP, &tv) == -1) {
      if(GIMME_V == G_ARRAY)
        return;
      else
        XSRETURN_UNDEF;
    }

    if(GIMME_V == G_ARRAY) {
      EXTEND(SP, 2);

lib/Socket/Packet.xs  view on Meta::CPAN

void
siocgstampns(sock)
  InputStream sock
  PROTOTYPE: $

  PREINIT:
    int fd;
    int result;
    struct timespec ts;

  PPCODE:
#ifdef SIOCGSTAMPNS
    fd = PerlIO_fileno(sock);
    if(ioctl(fd, SIOCGSTAMPNS, &ts) == -1) {
      if(GIMME_V == G_ARRAY)
        return;
      else
        XSRETURN_UNDEF;
    }

    if(GIMME_V == G_ARRAY) {

lib/Socket/Packet.xs  view on Meta::CPAN

void
siocgifindex(sock, ifname)
  InputStream sock
  char *ifname
  PROTOTYPE: $$

  PREINIT:
    int fd;
    struct ifreq req;

  PPCODE:
#ifdef SIOCGIFINDEX
    fd = PerlIO_fileno(sock);
    strncpy(req.ifr_name, ifname, IFNAMSIZ);
    if(ioctl(fd, SIOCGIFINDEX, &req) == -1)
      XSRETURN_UNDEF;
    mPUSHi(req.ifr_ifindex);
#else
    croak("SIOCGIFINDEX not implemented");
#endif

void
siocgifname(sock, ifindex)
  InputStream sock
  int ifindex
  PROTOTYPE: $$

  PREINIT:
    int fd;
    struct ifreq req;

  PPCODE:
#ifdef SIOCGIFNAME
    fd = PerlIO_fileno(sock);
    req.ifr_ifindex = ifindex;
    if(ioctl(fd, SIOCGIFNAME, &req) == -1)
      XSRETURN_UNDEF;
    PUSHs(sv_2mortal(newSVpv(req.ifr_name, 0)));
#else
    croak("SIOCGIFNAME not implemented");
#endif

lib/Socket/Packet.xs  view on Meta::CPAN

    int maxlen
    int flags

  PREINIT:
    int fd;
    char *bufferp;
    struct sockaddr_storage addr;
    socklen_t addrlen;
    int len;

  PPCODE:
    fd = PerlIO_fileno(sock);

    if(!SvOK(buffer))
      sv_setpvn(buffer, "", 0);

    bufferp = SvGROW(buffer, (STRLEN)(maxlen+1));

    addrlen = sizeof(addr);

    len = recvfrom(fd, bufferp, maxlen, flags, (struct sockaddr *)&addr, &addrlen);

lib/Socket/Packet.xs  view on Meta::CPAN

    unsigned int frame_nr
    unsigned int block_size

  PREINIT:
    int fd;
    int version;
    struct tpacket_req req;
    size_t size;
    char *addr;

  PPCODE:
#ifdef HAVE_RX_RING
    fd = PerlIO_fileno(sock);
#ifdef HAVE_TPACKET2
    version = TPACKET_V2;
    if(setsockopt(fd, SOL_PACKET, PACKET_VERSION, &version, sizeof version) != 0)
      XSRETURN_UNDEF;
#endif

    {
      struct tpacket_req req;

lib/Socket/Packet.xs  view on Meta::CPAN


    ST(0) = sv_2mortal(newSViv(size));
    XSRETURN(1);
#else
    croak("setup_rx_ring() not supported on this platform");
#endif

void
get_ring_frame_status(sock)
    InputStream sock
  PPCODE:
#ifdef HAVE_RX_RING
    {
      struct packet_rxring_state *state = get_rxring_state((SV*)sv_2io(ST(0)));
      char *addr = frame_ptr(state);
#if defined(HAVE_TPACKET2)
      struct tpacket2_hdr *hdr = (struct tpacket2_hdr *)addr;
#elif defined(HAVE_TPACKET)
      struct tpacket_hdr *hdr = (struct tpacket_hdr *)addr;
#endif
      ST(0) = sv_2mortal(newSViv(hdr->tp_status));

lib/Socket/Packet.xs  view on Meta::CPAN

#endif

void
get_ring_frame(sock, buffer, info)
    InputStream sock
    SV *buffer
    HV *info

  PREINIT:

  PPCODE:
#ifdef HAVE_RX_RING
    {
      struct packet_rxring_state *state = get_rxring_state((SV*)sv_2io(ST(0)));
      char *addr = frame_ptr(state);
      unsigned int len;
      unsigned int snaplen;
      int mac;
      struct sockaddr_ll  *sll;
#if defined(HAVE_TPACKET2)
      struct tpacket2_hdr *hdr = (struct tpacket2_hdr *)addr;

lib/Socket/Packet.xs  view on Meta::CPAN

      sv_setiv(ST(0), len);
      XSRETURN(1);
    }
#else
    croak("get_ring_frame() not supported on this platform");
#endif

void
done_ring_frame(sock)
    InputStream sock
  PPCODE:
#ifdef HAVE_RX_RING
    {
      struct packet_rxring_state *state = get_rxring_state((SV*)sv_2io(ST(0)));
      char *addr = frame_ptr(state);
#if defined(HAVE_TPACKET2)
      struct tpacket2_hdr *hdr = (struct tpacket2_hdr *)addr;
#elif defined(HAVE_TPACKET)
      struct tpacket_hdr *hdr = (struct tpacket_hdr *)addr;
#endif
      hdr->tp_status = TP_STATUS_KERNEL;



( run in 1.327 second using v1.01-cache-2.11-cpan-5511b514fd6 )