Net-Interface
view release on metacpan or search on metacpan
Interface.xs view on Meta::CPAN
nl++;
}
/* should never do the else! */
else {
iferror2:
free(nlbase);
hv_undef(ifaces);
iferror1:
return -1;
}
}
free(nlbase);
hv_undef(ifaces);
return i;
}
/* return NULL or pointer to first available address */
static SV *
get_first_address(SV * ref, char * key, int sixonly)
{
HV * hv, * family;
AV * av;
SV * sv;
char afk[16], * args = "args";
hv = (HV *)SvRV(ref); /* wrapper */
if (! hv_exists(hv,args,niKEYsz))
return NULL;
sv = *hv_fetch(hv,args,niKEYsz,0); /* hface */
if (!SvROK(sv))
return NULL;
hv = (HV *)SvRV(sv);
if (! sixonly && hv_exists(hv,afk,afk_len(AF_INET,afk)))
family = (HV*)SvRV(*hv_fetch(hv,afk,afk_len(AF_INET,afk),0));
#ifdef LOCAL_SIZEOF_SOCKADDR_IN6
else if (hv_exists(hv,afk,afk_len(AF_INET6,afk)))
family = (HV*)SvRV(*hv_fetch(hv,afk,afk_len(AF_INET6,afk),0));
#endif
else
return NULL;
av = (AV*)SvRV(*hv_fetch(family,key,niKEYsz,0));
return *av_fetch(av,0,0); /* first addy */
}
MODULE = Net::Interface PACKAGE = Net::Interface PREFIX = NIP_
INCLUDE: miniSocketXS.c
void
interfaces(ref,...)
SV * ref
PROTOTYPE: $;$
ALIAS:
new = 1
PREINIT:
HV * stash = SvROK (ref)
? SvSTASH (SvRV (ref)) : gv_stashsv (ref, 0);
int rv;
PPCODE:
if ((rv = getheifs(sp,ax,items,ref,stash,(int)ix,NULL)) < 0) {
if (GIMME == G_ARRAY)
XSRETURN_EMPTY;
else
XSRETURN_UNDEF;
}
XSRETURN(rv);
void
dtest(ref)
SV * ref
PREINIT:
char * myname = "my name", * one = "one", * two = "two", * array = "array";
SV * rv, *arv, *mn;
GV * gv;
AV * av;
HV * stash, * tstash;
PPCODE:
stash = SvROK (ref) ? SvSTASH (SvRV (ref)) : gv_stashsv (ref, 0);
NI_newGV_ref(rv,gv,stash,tstash);
# mn = newSVpv(myname,0);
# GvSV(gv) = mn;
# hv_store(GvHV(gv),one,strlen(one),newSViv(1),0);
# hv_store(GvHV(gv),two,strlen(two),newSViv(2),0);
# av = newAV();
# arv = newRV_noinc((SV *)av);
# av = (AV*)SvRV(*hv_store(GvHV(gv),array,strlen(array),arv,0));
# av_push(av,newSViv(55));
XPUSHs(sv_2mortal(rv));
XSRETURN(1);
void
dtest2(ref)
SV * ref
PREINIT:
SV * sv, * pv;
HV * hv;
char * name = "Sv Name";
char * n2 = "LOGO";
char * myname = "my name", * one = "one", * two = "two", * array = "array";
PPCODE:
hv = newHV();
hv_store(hv,one,strlen(one),newSViv(1),0);
hv_store(hv,two,strlen(two),newSViv(2),0);
sv = (SV*)newRV_noinc((SV*)hv);
XPUSHs(sv_2mortal(sv));
XSRETURN(1);
void
__developer(ref)
SV *ref
ALIAS:
d_ni_ifreq = NI_IFREQ
d_ni_lifreq = NI_LIFREQ
d_ni_in6_ifreq = NI_IN6_IFREQ
d_ni_linuxproc = NI_LINUXPROC
PREINIT:
char * process;
int er = ni_developer(ix);
CODE:
if (er == 0)
XSRETURN_EMPTY;
switch (ix) {
case NI_IFREQ :
process = "NI_FREQ";
break;
case NI_LIFREQ :
process = "NI_LIFREQ";
break;
case NI_IN6_IFREQ :
process = "NI_IN6_IFREQ";
break;
case NI_LINUXPROC :
process = "NI_LINUXPROC";
break;
default :
process = "UNDEFINED";
}
printf("%s: %s\n",process,strerror(er));
void
gifaddrs_base(ref)
SV * ref
ALIAS:
# base = 0
gifa_ifreq = NI_IFREQ
gifa_lifreq = NI_LIFREQ
gifa_in6_ifreq = NI_IN6_IFREQ
gifa_linuxproc = NI_LINUXPROC
PREINIT:
struct ifaddrs * ifap;
int rv;
CODE:
if ((rv = ni_getifaddrs(&ifap,ix)) == -1) {
printf("failed PUNT!\n");
XSRETURN_EMPTY;
}
ni_getifaddrs_dump(rv,ifap);
ni_free_gifa(ifap,rv);
void
cidr2mask(prefix, size)
int prefix
int size
PREINIT:
unsigned char mask[16];
PPCODE:
if (!(size == 4 || size == 16))
croak("Bad arg for %s, requested mask size is %d, should be 4 or 16",
GvNAME (CvGV (cv)),size);
if (prefix < 0 || prefix > (size * 8))
croak ("Bad arg for %s, mask length is %d, should be 0 to <= %d",
GvNAME (CvGV (cv)),size * 8);
ni_plen2mask(mask,prefix,size);
XPUSHs(sv_2mortal(newSVpvn((char *)mask,size)));
XSRETURN(1);
int
mask2cidr(ref,...)
SV * ref;
PROTOTYPE: $;$
PREINIT:
unsigned char * mp;
STRLEN len;
char * netmask = "netm";
SV * sv;
CODE:
# called as method with argument
if (items == 2)
mp = (unsigned char *)SvPV(ST(1),len);
# called as a function
else if (! SvROK(ref))
mp = (unsigned char *)SvPV(ST(0),len);
# called as method
else {
if ((sv = get_first_address(ref,netmask,0)) == NULL)
len = 0;
else
mp = (unsigned char *)SvPV(sv,len);
}
if (!(len == 4 || len == 16))
croak("Bad arg length for %s, mask length is %d, should be 4 or 16",
GvNAME (CvGV (cv)),len);
RETVAL = ni_prefix(mp,len);
OUTPUT:
RETVAL
void
NIP_type(ref,...)
SV * ref
PROTOTYPE: $;$
ALIAS:
scope = 1
PREINIT:
unsigned char * s6bytes;
char * addr = "addr";
UV type;
STRLEN len;
HV * hv;
SV * sv;
PPCODE:
# called as method with argument
if (items == 2)
s6bytes = (unsigned char *)SvPV(ST(1),len);
# called as a function
else if (! SvROK(ref))
s6bytes = (unsigned char *)SvPV(ST(0),len);
# called as method
else {
if ((sv = get_first_address(ref,addr,1)) == NULL)
len = 0;
else
s6bytes = (unsigned char *)SvPV(sv,len);
}
if (! len == 16)
croak("Bad arg length for %s, address length is %d, should be 16",
GvNAME (CvGV (cv)),len);
type = ni_in6_classify(s6bytes);
if (ix == 0)
XPUSHs(sv_2mortal(newSVuv(type)));
else
XPUSHs(sv_2mortal(newSViv(ni_lx_type2scope((int)type))));
XSRETURN(1);
void
mac_bin2hex(ref,...)
SV * ref
PROTOTYPE: $;$
PREINIT:
unsigned char * macbin;
char macbuf[18], * format, * args = "args", * mac = "maci";
STRLEN len;
HV * hv;
SV * sv;
PPCODE:
# called as method with argument
if (items == 2)
macbin = (unsigned char *)SvPV(ST(1),len);
# called as a function
else if (! SvROK(ref))
macbin = (unsigned char *)SvPV(ST(0),len);
# called as method
else {
hv = (HV *)SvRV(ref);
if (! hv_exists(hv,args,niKEYsz))
XSRETURN_UNDEF;
sv = *hv_fetch(hv,args,niKEYsz,0);
if (!SvROK(sv))
XSRETURN_UNDEF;
hv = (HV *)SvRV(sv);
if (! hv_exists(hv,mac,niKEYsz))
XSRETURN_UNDEF;
sv = *hv_fetch(hv,mac,niKEYsz,0);
if (! SvPOK(sv))
XSRETURN_UNDEF;
macbin = (unsigned char *)SvPV(sv,len);
}
if (len != 6)
croak("Bad arg length for %s, MAC length is %d, should be 6",
GvNAME (CvGV (cv)),len);
format = SvPV(get_sv("Net::Interface::mac_format", FALSE),len);
sprintf(macbuf,format,
macbin[0],macbin[1],macbin[2],macbin[3],macbin[4],macbin[5]);
XPUSHs(sv_2mortal(newSVpv(macbuf,0)));
XSRETURN(1);
void
full_inet_ntop(neta)
SV * neta
PREINIT:
unsigned char * naddr;
char mask[40], * format;
STRLEN len;
PPCODE:
naddr = (unsigned char *)SvPV(neta,len);
if (len != 16)
croak("Bad arg length for %s, ipV6 length is %d, should be 16 bytes",
GvNAME (CvGV (cv)),len);
format = SvPV(get_sv("Net::Interface::full_format", FALSE),len);
sprintf(mask,format,
naddr[0],naddr[1],naddr[2],naddr[3],
naddr[4],naddr[5],naddr[6],naddr[7],
naddr[8],naddr[9],naddr[10],naddr[11],
naddr[12],naddr[13],naddr[14],naddr[15]);
XPUSHs(sv_2mortal(newSVpvn((char *)mask,39)));
XSRETURN(1);
void
_lx_types()
ALIAS:
IPV6_ADDR_ANY = IPV6_ADDR_ANY
IPV6_ADDR_UNICAST = IPV6_ADDR_UNICAST
IPV6_ADDR_MULTICAST = IPV6_ADDR_MULTICAST
IPV6_ADDR_ANYCAST = IPV6_ADDR_ANYCAST
IPV6_ADDR_LOOPBACK = IPV6_ADDR_LOOPBACK
IPV6_ADDR_LINKLOCAL = IPV6_ADDR_LINKLOCAL
IPV6_ADDR_SITELOCAL = IPV6_ADDR_SITELOCAL
IPV6_ADDR_COMPATv4 = IPV6_ADDR_COMPATv4
IPV6_ADDR_SCOPE_MASK = IPV6_ADDR_SCOPE_MASK
IPV6_ADDR_MAPPED = IPV6_ADDR_MAPPED
IPV6_ADDR_RESERVED = IPV6_ADDR_RESERVED
IPV6_ADDR_ULUA = IPV6_ADDR_ULUA
IPV6_ADDR_6TO4 = IPV6_ADDR_6TO4
IPV6_ADDR_6BONE = IPV6_ADDR_6BONE
IPV6_ADDR_AGU = IPV6_ADDR_AGU
IPV6_ADDR_UNSPECIFIED = IPV6_ADDR_UNSPECIFIED
IPV6_ADDR_SOLICITED_NODE = IPV6_ADDR_SOLICITED_NODE
IPV6_ADDR_ISATAP = IPV6_ADDR_ISATAP
IPV6_ADDR_PRODUCTIVE = IPV6_ADDR_PRODUCTIVE
IPV6_ADDR_6TO4_MICROSOFT = IPV6_ADDR_6TO4_MICROSOFT
IPV6_ADDR_TEREDO = IPV6_ADDR_TEREDO
IPV6_ADDR_ORCHID = IPV6_ADDR_ORCHID
IPV6_ADDR_NON_ROUTE_DOC = IPV6_ADDR_NON_ROUTE_DOC
PREINIT:
SV * rv;
int n, i;
PPCODE:
rv = sv_2mortal(newSViv(ix));
n = ni_sizeof_type2txt();
for (i=0; i<n; i++) {
if (ni_lx_type2txt[i].iff_val == ix) {
sv_setpv(rv,ni_lx_type2txt[i].iff_nam);
break;
}
}
SvIOK_on(rv);
XPUSHs(rv);
XSRETURN(1);
void
_lx_scope()
ALIAS:
RFC2373_GLOBAL = RFC2373_GLOBAL
RFC2373_ORGLOCAL = RFC2373_ORGLOCAL
RFC2373_SITELOCAL = RFC2373_SITELOCAL
RFC2373_LINKLOCAL = RFC2373_LINKLOCAL
RFC2373_NODELOCAL = RFC2373_NODELOCAL
LINUX_COMPATv4 = LINUX_COMPATv4
PREINIT:
SV * rv;
int n, i;
PPCODE:
rv = sv_2mortal(newSViv(ix));
n = sizeof(ni_lx_scope_txt) / sizeof(ni_iff_t);
for (i=0; i<n; i++) {
if (ni_lx_scope_txt[i].iff_val == ix) {
sv_setpv(rv,ni_lx_scope_txt[i].iff_nam);
break;
}
}
SvIOK_on(rv);
XPUSHs(rv);
XSRETURN(1);
size_t
NIP_strlcpy(...)
PROTOTYPE: $$$
PREINIT:
char * d = NULL;
char * s = SvPV_nolen(ST(1));
size_t size = (size_t)SvIV(ST(2));
CODE:
if ((int)size > 0) {
d = New(1234,d,2 * size,char);
memset(d,'X',2 * size);
*(d + (2*size) -1) = 0;
RETVAL = strlcpy(d,s,size);
sv_setpv(ST(0),d);
Safefree(d);
} else
RETVAL = 0;
OUTPUT:
RETVAL
int
_sets(ref,...)
SV * ref
ALIAS:
mtu = 0
metric = 1
flags = 2
index = 3
PREINIT:
int cmd, fd, rv, flavor;
struct nifreq ifr, * ofifr;
struct ni_ifconf_flavor * nifp;
HV * hv;
SV * sv;
char * key, * args = "args", * name = "name", * flav = "flav";
STRLEN len;
CODE:
if (!SvROK (ref) || !SvOBJECT(SvRV(ref)))
croak ("Can't call method \"%s\" without a valid object reference", GvNAME (CvGV (cv)));
if (items > 2) {
not_found:
croak ("Invalid or corrupted arguments passed to \"%s\"", GvNAME (CvGV (cv)));
}
hv = (HV *)SvRV(ref);
if (! hv_exists(hv,name,niKEYsz))
( run in 0.920 second using v1.01-cache-2.11-cpan-5511b514fd6 )