1 #include <EXTERN.h>
2 #include <perl.h>
3 #include "perl.h"
4 #include "config.h"
5 
6 EXTERN_C void xs_init();
7 
8 static PerlInterpreter *my_perl = NULL;
9 
my_eval_sv(SV * sv,I32 coe)10 static SV *my_eval_sv(SV *sv, I32 coe) {
11     SV *retval;
12     STRLEN n_a;
13     dSP;
14 
15     ENTER;
16     SAVETMPS;
17     PUSHMARK(SP);
18     PUTBACK;
19     eval_sv(sv, G_SCALAR);
20 
21     SPAGAIN;
22     retval = POPs;
23     if(coe && SvTRUE(ERRSV)) {
24         croak(SvPVx(ERRSV, n_a));
25     }
26     SvREFCNT_inc(retval);
27     PUTBACK;
28     FREETMPS;
29     LEAVE;
30     return retval;
31 }
32 
perl_startup()33 void perl_startup() {
34     char *embedding[] = { "", "-e", "0" };
35 
36     my_perl = perl_alloc();
37     perl_construct( my_perl );
38 
39     perl_parse(my_perl, xs_init, 3, embedding, NULL);
40 }
41 
perl_shutdown()42 void perl_shutdown() {
43     if(my_perl) {
44         perl_destruct(my_perl);
45         perl_free(my_perl);
46         my_perl = NULL;
47     }
48 }
49 
perl_inc(char * path)50 int perl_inc(char *path) {
51     SV *retval;
52     SV *command = NEWSV(1024+20, 0);
53 
54     sv_setpvf(command, "use lib '%s';", path);
55     retval = my_eval_sv(command, TRUE);
56     SvREFCNT_dec(command);
57 
58     return SvIV(retval);
59 }
60 
perl_use(char * module)61 int perl_use(char *module) {
62     int val;
63     SV *retval;
64     SV *command = NEWSV(1024+20, 0);
65 
66     sv_setpvf(command, "use %s;", module);
67     retval = my_eval_sv(command, TRUE);
68     SvREFCNT_dec(command);
69     val = SvIV(retval);
70     SvREFCNT_dec(retval);
71     return val;
72 }
73 
perl_handler(char * func,struct interface * p,struct interface * e,struct interface * r)74 int perl_handler(char *func, struct interface *p,
75                  struct interface *e,
76                  struct interface *r) {
77     int retval;
78     int i;
79     HV *phv, *rhv;
80     AV *eav;
81 
82     dSP;                                  /* initialize stack pointer      */
83     ENTER;                                /* everything created after here */
84     SAVETMPS;                             /* ...is a temporary variable.   */
85     PUSHMARK(SP);                         /* remember the stack pointer    */
86     phv = newHV();
87     hv_store(phv, "ifname", sizeof("ifname")-1, sv_2mortal(newSVpv(p->ifname,0)),0);
88     hv_store(phv, "ip", sizeof("ip")-1, sv_2mortal(newSVpv(inet_ntoa(p->ipaddr),0)),0);
89     hv_store(phv, "broadcast", sizeof("broadcast")-1, sv_2mortal(newSVpv(inet_ntoa(p->bcast),0)),0);
90     hv_store(phv, "netmask", sizeof("netmask")-1, sv_2mortal(newSVpv(inet_ntoa(p->netmask),0)),0);
91 
92     eav = newAV();
93     for(i = 0; i < MAX_DEP_IF && e[i].ipaddr.s_addr != 0; i++) {
94         HV* tmphv;
95         tmphv = newHV();
96         hv_store(tmphv, "ifname", sizeof("ifname")-1, sv_2mortal(newSVpv(e[i].ifname,0)),0);
97         hv_store(tmphv, "ip", sizeof("ip")-1, sv_2mortal(newSVpv(inet_ntoa(e[i].ipaddr),0)),0);
98         hv_store(tmphv, "broadcast", sizeof("broadcast")-1, sv_2mortal(newSVpv(inet_ntoa(e[i].bcast),0)),0);
99         hv_store(tmphv, "netmask", sizeof("netmask")-1, sv_2mortal(newSVpv(inet_ntoa(e[i].netmask),0)),0);
100         av_push(eav, (SV*)sv_2mortal(newRV_inc((SV *)tmphv)));
101     }
102     rhv = newHV();
103     hv_store(rhv, "ifname", sizeof("ifname")-1, sv_2mortal(newSVpv(r->ifname,0)),0);
104     hv_store(rhv, "ip", sizeof("ip")-1, sv_2mortal(newSVpv(inet_ntoa(r->ipaddr),0)),0);
105     hv_store(rhv, "broadcast", sizeof("broadcast")-1, sv_2mortal(newSVpv(inet_ntoa(r->bcast),0)),0);
106     hv_store(rhv, "netmask", sizeof("netmask")-1, sv_2mortal(newSVpv(inet_ntoa(r->netmask),0)),0);
107 
108     XPUSHs((SV*)sv_2mortal(newRV_inc((SV *)phv)));/* push the psuedo interface onto the stack  */
109     XPUSHs((SV*)sv_2mortal(newRV_inc((SV *)eav)));/* push the extra interface array ref onto the stack  */
110     XPUSHs((SV*)sv_2mortal(newRV_inc((SV *)rhv)));/* push the real interface onto the stack  */
111     PUTBACK;                              /* make local stack pointer global */
112     call_pv(func, G_SCALAR);              /* call the function             */
113     SPAGAIN;                              /* refresh stack pointer         */
114                                           /* pop the return value from stack */
115     retval = POPi;
116     PUTBACK;
117     FREETMPS;                             /* free that return value        */
118     LEAVE;                                /* ...and the XPUSHed "mortal" args.*/
119     return retval;
120 }
121 
122