File Coverage

ARP.xs
Criterion Covered Total %
statement 41 70 58.5
branch 12 32 37.5
condition n/a
subroutine n/a
pod n/a
total 53 102 51.9


line stmt bran cond sub pod time code
1             /*
2             Perl ARP Extension
3             Create and send an arp packets, lookup mac addresses
4              
5             Programmed by Bastian Ballmann
6             Last update: 11.05.2022
7              
8             This program is free software; you can redistribute
9             it and/or modify it under the terms of the
10             GNU General Public License version 2 as published
11             by the Free Software Foundation.
12              
13             This program is distributed in the hope that it will
14             be useful, but WITHOUT ANY WARRANTY; without even
15             the implied warranty of MERCHANTABILITY or FITNESS
16             FOR A PARTICULAR PURPOSE.
17             See the GNU General Public License for more details.
18             */
19              
20             #include "EXTERN.h"
21             #include "perl.h"
22             #include "XSUB.h"
23              
24             #include "ppport.h"
25             #include
26             #include
27             #include
28             #include
29             #include
30             #ifdef BSD
31             #include
32             #else
33             #include
34             #endif
35             #include
36             #include
37             #include "arp.h"
38              
39             MODULE = Net::ARP PACKAGE = Net::ARP
40              
41             int
42             send_packet(dev, sip, dip, smac, dmac, type)
43             const char *dev;
44             const char *sip;
45             const char *dip;
46             const char *smac;
47             const char *dmac;
48             const char *type;
49              
50             CODE:
51             int uid;
52 1           unsigned int packetsize = sizeof(struct my_arphdr) + sizeof(struct ether_header);
53 1           unsigned char packet[packetsize];
54 1           struct ether_header *ethhdr = (struct ether_header *)packet;
55 1           struct my_arphdr *arp = (struct my_arphdr *)(packet + sizeof(struct ether_header));
56             u_short op;
57             in_addr_t ipaddr;
58              
59 1           RETVAL = 1;
60              
61             // Are you root?
62 1           uid = getuid();
63 1 50         if(uid != 0)
64             {
65 0           printf("You must have UID 0 instead of %d.\n", uid);
66 0           exit(0);
67             }
68              
69             // Initialize packet buffer
70 1           memset(packet,0,packetsize);
71              
72             // What's the ARP operation type?
73 1 50         if(!strcmp(type, "request"))
74             {
75 0           op = ARPOP_REQUEST;
76             }
77 1 50         else if(!strcmp(type, "reply"))
78             {
79 1           op = ARPOP_REPLY;
80             }
81 0 0         else if(!strcmp(type, "revrequest"))
82             {
83 0           op = ARPOP_REVREQUEST;
84             }
85 0 0         else if(!strcmp(type, "revreply"))
86             {
87 0           op = ARPOP_REVREPLY;
88             }
89 0 0         else if(!strcmp(type, "invrequest"))
90             {
91 0           op = ARPOP_INVREQUEST;
92             }
93 0 0         else if(!strcmp(type, "invreply"))
94             {
95 0           op = ARPOP_INVREPLY;
96             }
97             else
98             {
99 0           printf("Unknown ARP operation\n");
100 0           RETVAL = 0;
101             }
102              
103 1 50         if(smac == NULL)
104             {
105 0           printf("Parameter smac is NULL! Terminating.\n");
106 0           RETVAL = 0;
107             }
108              
109 1 50         if(dmac == NULL)
110             {
111 0           printf("Parameter dmac is NULL! Terminating.\n");
112 0           RETVAL = 0;
113             }
114              
115             // Found a dollar sign?
116 1 50         if(strchr(smac, 36))
117             {
118 0           printf("Found a $ char in smac! Terminating.\n");
119 0           RETVAL = 0;
120             }
121              
122 1 50         if(strchr(dmac, 36))
123             {
124 0           printf("Found a $ char in dmac! Terminating.\n");
125 0           RETVAL = 0;
126             }
127              
128 1 50         if(ether_aton(smac) == NULL)
129             {
130 0           printf("Invalid source mac address! Terminating.\n");
131 0           RETVAL = 0;
132             }
133              
134 1 50         if(ether_aton(dmac) == NULL)
135             {
136 0           printf("Invalid destination mac address! Terminating.\n");
137 0           RETVAL = 0;
138             }
139              
140             // Check ips
141 1 50         if(inet_addr(sip) == INADDR_NONE)
142             {
143 0           printf("Invalid source ip address! Terminating.\n");
144 0           RETVAL = 0;
145             }
146              
147 1 50         if(inet_addr(dip) == INADDR_NONE)
148             {
149 0           printf("Invalid destination ip address! Terminating.\n");
150 0           RETVAL = 0;
151             }
152              
153             // Construct and send packet
154 1 50         if(RETVAL != 0)
155             {
156             // Ethernet header
157 1           memcpy(ethhdr->ether_dhost,(u_char *)ether_aton(dmac), ETHER_ADDR_LEN); // Destination MAC
158 1           memcpy(ethhdr->ether_shost,(u_char *)ether_aton(smac), ETHER_ADDR_LEN); // Source MAC
159 1           ethhdr->ether_type = htons(ETHERTYPE_ARP); // ARP protocol
160              
161             // ARP header
162 1           arp->hw_type = htons(ARPHDR_ETHER); // Hardware address type
163 1           arp->proto_type = htons(ETH_P_IP); // Protocol address type
164 1           arp->ha_len = ETH_ALEN; // Hardware address length
165 1           arp->pa_len = IP_ALEN; // Protocol address length
166 1           arp->opcode = htons(op); // ARP operation
167 1           memcpy(arp->source_add,(u_char *)ether_aton(smac), ETH_ALEN); // Source MAC
168 1           memcpy(arp->dest_add,(u_char *)ether_aton(dmac), ETH_ALEN); // Destination MAC
169 1           ipaddr = inet_addr(sip);
170 1           memcpy(arp->source_ip, (u_char *)&ipaddr, IP_ALEN); // Source IP
171              
172 1           ipaddr = inet_addr(dip);
173 1           memcpy(arp->dest_ip, (u_char *)&ipaddr, IP_ALEN); // Destination IP
174              
175              
176             if(LINUX == 1)
177             {
178 1           RETVAL = send_packet_linux(dev, packet, packetsize);
179             }
180             else
181             {
182             RETVAL = send_packet_bsd(dev, packet, packetsize);
183             }
184             }
185              
186             OUTPUT:
187             RETVAL
188              
189             char *
190             get_mac(dev)
191             const char *dev;
192             CODE:
193 1           char tmp[HEX_HW_ADDR_LEN] = "unknown";
194              
195             if(LINUX == 1)
196             {
197 1           get_mac_linux(dev, tmp);
198             }
199             else
200             {
201             get_mac_bsd(dev, tmp);
202             }
203              
204 1           RETVAL = tmp;
205              
206             OUTPUT:
207             RETVAL
208              
209              
210             char *
211             arp_lookup(dev, ip)
212             const char *dev;
213             const char *ip;
214              
215             CODE:
216 1           char tmp[HEX_HW_ADDR_LEN] = "unknown";
217              
218             if(LINUX == 1)
219             {
220 1           arp_lookup_linux(dev, ip, tmp);
221             }
222             else
223             {
224             arp_lookup_bsd(dev, ip, tmp);
225             }
226              
227 1           RETVAL = tmp;
228              
229             OUTPUT:
230             RETVAL