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