1 /* $Id$ */
2 
3 /*
4  * Copyright (c) 2008-2012 Patrice <GomoR> Auffret
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 SV *
intf_c2sv(IntfEntry * entry)32 intf_c2sv(IntfEntry *entry)
33 {
34    HV *out     = newHV();
35    SV *out_ref = newRV_noinc((SV *)out);
36    char *sAddr, *sDstAddr, *sLnkAddr;
37 
38    hv_store(out, "intf_len",    8, newSViv(entry->intf_len), 0);
39    hv_store(out, "intf_name",   9, newSVpv(entry->intf_name, 0), 0);
40    hv_store(out, "intf_type",   9, newSViv(entry->intf_type), 0);
41    hv_store(out, "intf_flags", 10, newSViv(entry->intf_flags), 0);
42    hv_store(out, "intf_mtu",    8, newSViv(entry->intf_mtu), 0);
43 
44    sAddr = addr_ntoa(&(entry->intf_addr));
45    if (sAddr == NULL) {
46       hv_store(out, "intf_addr", 9, &PL_sv_undef, 0);
47    }
48    else {
49       hv_store(out, "intf_addr", 9, newSVpv(sAddr, 0), 0);
50    }
51    sDstAddr = addr_ntoa(&(entry->intf_dst_addr));
52    if (sDstAddr == NULL) {
53       hv_store(out, "intf_dst_addr", 13, &PL_sv_undef, 0);
54    }
55    else {
56       hv_store(out, "intf_dst_addr", 13, newSVpv(sDstAddr, 0), 0);
57    }
58    sLnkAddr = addr_ntoa(&(entry->intf_link_addr));
59    if (sLnkAddr == NULL) {
60       hv_store(out, "intf_link_addr", 14, &PL_sv_undef, 0);
61    }
62    else {
63       hv_store(out, "intf_link_addr", 14, newSVpv(sLnkAddr, 0), 0);
64    }
65 
66    hv_store(out, "intf_alias_num", 14, newSViv(entry->intf_alias_num), 0);
67    if (entry->intf_alias_num > 0) {
68       int i;
69       AV *aliases     = newAV();
70       SV *aliases_ref = newRV_noinc((SV *)aliases);
71       for (i=0; i<entry->intf_alias_num; i++) {
72          char *alias = addr_ntoa(&(entry->intf_alias_addrs[i]));
73          if (alias != NULL) {
74             av_push(aliases, newSVpv(alias, 0));
75          }
76       }
77       hv_store(out, "intf_alias_addrs", 16, aliases_ref, 0);
78    }
79    else {
80       hv_store(out, "intf_alias_addrs", 16, newRV_noinc((SV *)newAV()), 0);
81    }
82 
83    return out_ref;
84 }
85 
86 static IntfEntry *
intf_sv2c(SV * h,IntfEntry * ref)87 intf_sv2c(SV *h, IntfEntry *ref)
88 {
89    if (ref && h && SvROK(h)) {
90       HV *hv = (HV *)SvRV(h);
91       memset(ref, 0, sizeof(IntfEntry));
92       if (hv_exists(hv, "intf_len", 8)) {
93          SV **len      = hv_fetch((HV *)SvRV(h), "intf_len", 8, 0);
94          ref->intf_len = (SvOK(*len) ? SvIV(*len) : 0);
95       }
96       if (hv_exists(hv, "intf_name", 9)) {
97          SV **name = hv_fetch((HV *)SvRV(h), "intf_name", 9, 0);
98          if (SvOK(*name)) {
99             memcpy(&(ref->intf_name), SvPV(*name, PL_na),
100                sizeof(ref->intf_name));
101          }
102       }
103       if (hv_exists(hv, "intf_type", 9)) {
104          SV **type      = hv_fetch((HV *)SvRV(h), "intf_type", 9, 0);
105          ref->intf_type = (SvOK(*type) ? SvIV(*type) : 0);
106       }
107       if (hv_exists(hv, "intf_flags", 10)) {
108          SV **flags      = hv_fetch((HV *)SvRV(h), "intf_flags", 10, 0);
109          ref->intf_flags = (SvOK(*flags) ? SvIV(*flags) : 0);
110       }
111       if (hv_exists(hv, "intf_mtu", 8)) {
112          SV **mtu      = hv_fetch((HV *)SvRV(h), "intf_mtu", 8, 0);
113          ref->intf_mtu = (SvOK(*mtu) ? SvIV(*mtu) : 0);
114       }
115       if (hv_exists(hv, "intf_addr", 9)) {
116          SV **addr = hv_fetch((HV *)SvRV(h), "intf_addr", 9, 0);
117          if (SvOK(*addr)) {
118             struct addr a;
119             if (addr_aton(SvPV(*addr, PL_na), &a) == 0) {
120                memcpy(&(ref->intf_addr), &a, sizeof(struct addr));
121             }
122          }
123       }
124       if (hv_exists(hv, "intf_dst_addr", 13)) {
125          SV **dstAddr = hv_fetch((HV *)SvRV(h), "intf_dst_addr", 13, 0);
126          if (SvOK(*dstAddr)) {
127             struct addr a;
128             if (addr_aton(SvPV(*dstAddr, PL_na), &a) == 0) {
129                memcpy(&(ref->intf_dst_addr), &a, sizeof(struct addr));
130             }
131          }
132       }
133       if (hv_exists(hv, "intf_link_addr", 14)) {
134          SV **lnkAddr = hv_fetch((HV *)SvRV(h), "intf_link_addr", 14, 0);
135          if (SvOK(*lnkAddr)) {
136             struct addr a;
137             if (addr_aton(SvPV(*lnkAddr, PL_na), &a) == 0) {
138                memcpy(&(ref->intf_link_addr), &a, sizeof(struct addr));
139             }
140          }
141       }
142    }
143    else {
144       ref = NULL;
145    }
146 
147    // XXX: put aliases also
148 
149    return ref;
150 }
151