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 )