File Coverage

Interface.xs
Criterion Covered Total %
statement 31 84 36.9
branch 11 44 25.0
condition n/a
subroutine n/a
pod n/a
total 42 128 32.8


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "ppport.h"
7              
8             #include "const-c.inc"
9              
10              
11             #include
12             #include
13             #include
14             #include
15             #include
16              
17             //Copy a sockaddr into an sv. BSD type systems have length field in struct
18             //sockaddr linux does not. So we cast the pointer to the correct family and
19             //then access the length field
20             //Returns a SV with the full sockaddr_* data
21 10           SV* sv_from_sockaddr(pTHX_ struct sockaddr *sockaddr){
22              
23              
24 10           switch(sockaddr->sa_family){
25 6           case AF_INET:
26 6           return newSVpv((char *)sockaddr, sizeof(struct sockaddr_in));
27             break;
28 2           case AF_INET6:
29 2           return newSVpv((char *)sockaddr, sizeof(struct sockaddr_in6));
30             break;
31 0           case AF_UNIX:
32 0           return newSVpv((char *)sockaddr, sizeof(struct sockaddr_un));
33             break;
34 2           default:
35             //TODO: use sockaddr_storage on linux?
36 2           return newSVpv((char *)sockaddr, sizeof(struct sockaddr));
37             break;
38             }
39             return NULL;
40             }
41              
42              
43             MODULE = Socket::More::Interface PACKAGE = Socket::More::Interface
44              
45             INCLUDE: const-xs.inc
46              
47             void
48             getifaddrs()
49              
50              
51             INIT:
52             struct ifaddrs *a;
53             struct ifaddrs *next;
54             int ret;
55             HV* h;
56 1           UV count=0;
57              
58             PPCODE:
59 1           ret=getifaddrs(&a);
60              
61 1 50         if(ret<0){
62 0           switch(GIMME_V){
63 0           case G_SCALAR:
64             case G_VOID:
65 0           XSRETURN_UNDEF;
66             break;
67 0           case G_ARRAY:
68 0           XSRETURN_EMPTY;
69             break;
70 0           default:
71 0           break;
72             }
73             }
74             else{
75 1           next=a->ifa_next;
76 1           switch(GIMME_V){
77 0           case G_SCALAR:
78 0 0         while(next){
79 0           count++;
80 0           next=next->ifa_next;
81             }
82             //Free contents
83 0           freeifaddrs(a);
84 0 0         mXPUSHs(newSVuv(count));
85 0           XSRETURN(1);
86             break;
87              
88 0           case G_VOID:
89 0           XSRETURN_UNDEF;
90             break;
91              
92 1           case G_ARRAY:
93              
94             //Copy contents
95 5 100         while(next){
96             //Create hash
97 4           h=newHV();
98             //Copy Values
99 4 50         if(next->ifa_name){
100 4           hv_stores(h, "name", newSVpv(next->ifa_name,0));
101             }
102 4 50         if(next->ifa_flags){
103 4           hv_stores(h, "flags",newSVuv(next->ifa_flags));
104             }
105 4 50         if(next->ifa_addr){
106 4           hv_stores(h, "addr", sv_from_sockaddr(aTHX_ next->ifa_addr));
107             }
108 4 100         if(next->ifa_netmask){
109 3           hv_stores(h, "netmask", sv_from_sockaddr(aTHX_ next->ifa_netmask));
110             }
111 4 100         if(next->ifa_dstaddr){
112 3           hv_stores(h, "dstaddr", sv_from_sockaddr(aTHX_ next->ifa_dstaddr));
113             }
114              
115             //a->ifa_data... read into this more
116 4           next=next->ifa_next;
117 4 50         mXPUSHs(newRV((SV *)h));
118 4           count++;
119             }
120             //Free contents
121 1           freeifaddrs(a);
122 1           XSRETURN(count);
123             break;
124 0           default:
125 0           break;
126             }
127             }
128            
129              
130             SV *
131             if_nametoindex(name)
132             SV *name;
133             INIT:
134             char *p;
135             unsigned int ret;
136             int len;
137             PPCODE:
138              
139 0 0         if(SvOK(name)&&SvPOK(name)){
    0          
140 0           len=SvCUR(name);
141 0 0         p=SvGROW(name, len+1);
    0          
142 0           p[len]='\0';
143              
144 0           ret=if_nametoindex(p);
145 0 0         mXPUSHs(newSVuv(ret));
146 0           XSRETURN(1);
147             }
148             else {
149 0           XSRETURN_UNDEF;
150             }
151              
152              
153             SV *
154             if_indextoname(index)
155              
156             SV *index;
157              
158             INIT:
159              
160 0           SV *result=newSV(IF_NAMESIZE);
161 0           char *p=SvPVX(result);
162             char *ret;
163            
164             PPCODE:
165 0 0         if(SvOK(index)){
166 0           ret=if_indextoname(SvUV(index), p);
167 0 0         if(ret == p){
168            
169 0           SvPOK_on(result);
170 0           SvCUR_set(result, strlen(p));
171 0 0         mXPUSHs(result);
172 0           XSRETURN(1);
173             }
174             else {
175 0           XSRETURN_UNDEF;
176             }
177             }
178             else {
179 0           XSRETURN_UNDEF;
180             }
181              
182             void
183             if_nameindex()
184              
185             INIT:
186              
187 0           UV count=0;
188             struct if_nameindex *results, *next;
189             PPCODE:
190              
191 0           results=if_nameindex();
192            
193 0 0         if(results ==NULL){
194              
195 0           XSRETURN_UNDEF;
196             }
197             else {
198 0           next=results;
199 0 0         while((next->if_index !=0 )&&
200 0 0         (next->if_name != NULL)){
201 0 0         EXTEND(SP,2);
202 0           mPUSHs(newSVuv(next->if_index));
203 0           mPUSHs(newSVpv(next->if_name, 0));
204 0           count++;
205 0           next=results+count;
206             }
207 0           if_freenameindex(results);
208 0           XSRETURN(count);
209             }
210              
211