forked from royhills/arp-scan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
link-packet-socket.c
132 lines (119 loc) · 3.19 KB
/
link-packet-socket.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* The ARP Scanner (arp-scan) is Copyright (C) 2005-2019 Roy Hills
*
* This file is part of arp-scan.
*
* arp-scan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* arp-scan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with arp-scan. If not, see <http://www.gnu.org/licenses/>.
*
* link-packet-socket.c -- Packet socket link layer functions for arp-scan
*
* Author: Roy Hills
* Date: 1 July 2006
*
* Description:
*
* This contains the link layer functions using the packet socket
* implementation. Packet socket is typically used on Linux with kernel
* version 2.2 and above. See packet(7) on a Linux system for details.
*
*/
#include "arp-scan.h"
#ifdef HAVE_NETPACKET_PACKET_H
#include <netpacket/packet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
/*
* Link layer handle structure for packet socket.
* This is typedef'ed as link_t.
*/
typedef struct link_handle {
int fd; /* Socket file descriptor */
struct ifreq ifr;
struct sockaddr_ll sll;
} link_t;
/*
* link_open -- Open the specified link-level device
*
* Inputs:
*
* device The name of the device to open
*
* Returns:
*
* A pointer to a link handle structure.
*/
static link_t *
link_open(const char *device) {
link_t *handle;
handle = Malloc(sizeof(*handle));
memset(handle, '\0', sizeof(*handle));
if ((handle->fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0) {
warn_msg("ERROR: Cannot open raw packet socket");
err_sys("socket");
}
strlcpy(handle->ifr.ifr_name, device, sizeof(handle->ifr.ifr_name));
if ((ioctl(handle->fd, SIOCGIFINDEX, &(handle->ifr))) != 0)
err_sys("ioctl");
handle->sll.sll_family = PF_PACKET;
handle->sll.sll_ifindex = handle->ifr.ifr_ifindex;
handle->sll.sll_halen = ETH_ALEN;
return handle;
}
/*
* link_close -- Close the link
*
* Inputs:
*
* handle The handle for the link interface
*
* Returns:
*
* None
*/
static void
link_close(link_t *handle) {
if (handle != NULL) {
if (handle->fd != 0)
close(handle->fd);
free(handle);
}
}
/*
* get_hardware_address -- Get the Ethernet MAC address associated
* with the given device.
* Inputs:
*
* if_name The name of the network interface
* hw_address (output) the Ethernet MAC address
*
* Returns:
*
* None
*/
void
get_hardware_address(const char *if_name, unsigned char hw_address[]) {
link_t *handle;
handle = link_open(if_name);
if(!handle) {
err_sys("link_open");
return;
}
/* Obtain hardware address for specified interface */
if ((ioctl(handle->fd, SIOCGIFHWADDR, &(handle->ifr))) != 0)
err_sys("ioctl");
memcpy(hw_address, handle->ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
link_close(handle);
}