2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
24 static struct mutexlock pcap_init_lock
= MUTEXLOCK_INITIALIZER
;
26 // Starts an ARP RX thread for *every* device in the device_list.
27 // (Except for the loopback interface)
29 // RETURN VALUE: 0 upon success,
36 for (i
=0; i
<device_list_entries
; i
++) {
37 if (mz_strcmp(device_list
[i
].dev
, "lo", 2)==0) continue; // omit loopback!
38 if (pthread_create( &(device_list
[i
].arprx_thread
),
41 &device_list
[i
])) { // give thread a pointer to that device_list entry
42 printf("xxxxxxxxxx\n");
43 return 1; // Error creating thread
46 fprintf(stderr
, " Started ARP monitor on device %s.\n",
55 // Thread function to receive ARP responses for a given device.
56 // Runs forever - until Mausezahn stops (see clean_up())
58 // Argument: pointer to device_struct!
62 void *rx_arp (void *arg
)
64 char errbuf
[PCAP_ERRBUF_SIZE
];
66 struct bpf_program filter
;
67 char filter_str
[] = "arp"; // We want to analyze both requests and responses!
68 struct device_struct
*dev
= (struct device_struct
*) arg
;
70 // FYI, possible filter string is also:
71 // "eth.dst==00:05:4e:51:01:b5 and arp and arp.opcode==2";
73 mutexlock_lock(&pcap_init_lock
);
75 p_arp
= pcap_open_live (dev
->dev
,
76 100, // max num of bytes to read
77 1, // 1 if promiscuous mode
78 PCAP_READ_TIMEOUT_MSEC
, // read timeout 'until error' (-1 = indefinitely)
82 fprintf(stderr
," rx_arp: [ERROR] %s\n",errbuf
);
86 dev
->p_arp
= p_arp
; // also assign pointer to a global which is needed for clean_up
88 if ( pcap_compile(p_arp
,
89 &filter
, // the compiled version of the filter
90 filter_str
, // text version of filter
94 fprintf(stderr
," rx_arp: [ERROR] Error calling pcap_compile\n");
98 if ( pcap_setfilter(p_arp
, &filter
) == -1) {
99 fprintf(stderr
," rx_arp: [ERROR] Error setting pcap filter\n");
100 pcap_perror(p_arp
, " rx_arp: ");
104 if (pcap_setdirection(p_arp
, PCAP_D_IN
) == -1) {
105 pcap_perror(p_arp
, " rx_arp: ");
109 mutexlock_unlock(&pcap_init_lock
);
113 1, // number of packets to wait
114 got_arp_packet
, // name of callback function
115 (u_char
*) dev
); // optional additional arguments for callback function
118 pthread_exit(NULL
); // destroy thread
122 mutexlock_unlock(&pcap_init_lock
);
127 void got_arp_packet (u_char
*args
,
128 const struct pcap_pkthdr
*header
, // statistics about the packet (see 'struct pcap_pkthdr')
129 const u_char
*packet
) // the bytestring sniffed
131 const struct struct_ethernet
*ethernet
;
132 const struct struct_arp
*arp
;
133 int size_ethernet
= sizeof(struct struct_ethernet
);
134 struct device_struct
*dev
= (struct device_struct
*) args
;
139 smac
[6], // source hw address
140 sip
[4], // source protocol address
141 tmac
[6], // target hw address
142 tip
[4]; // target protocol address
143 u_int16_t op
; // operation
147 // These are the most important lines here:
148 ethernet
= (struct struct_ethernet
*)(packet
);
149 arp
= (struct struct_arp
*)(packet
+size_ethernet
);
150 sec
= (u_int32_t
) header
->ts
.tv_sec
;
151 nsec
= (u_int32_t
) ((header
->ts
.tv_usec
) * 1000);
153 op
= arp
->arp_op
; // note that we don't have network byte order anymore!
155 // 100 instead of 00:01 (request)
156 // 200 instead of 00:02 (response)
158 memcpy((void*) da
, (void*) ethernet
->eth_da
, 6);
159 memcpy((void*) sa
, (void*) ethernet
->eth_sa
, 6);
160 memcpy((void*) smac
, (void*) arp
->arp_smac
, 6);
161 memcpy((void*) sip
, (void*) arp
->arp_sip
, 4);
162 memcpy((void*) tmac
, (void*) arp
->arp_tmac
, 6);
163 memcpy((void*) tip
, (void*) arp
->arp_tip
, 4);
165 // Only handle the packet if it is really an ARP response!
166 ////AND if it is not sent by THIS host! (not possible, we only scan inbound!)
167 x
= (u_int8_t
*) & op
;
168 if (*(x
+1) == 0x02) {
169 // ARP RESPONSE: Update ARP table
170 arptable_add(dev
, sa
, da
, smac
, sip
, sec
, nsec
);
171 } else if (*(x
+1) == 0x01) {
172 // ARP REQUEST: Detect poisoning attacks
173 arpwatch(dev
, sa
, da
, smac
, sip
, tmac
, tip
, sec
, nsec
);
179 // ARP binding consists of: sip (IP) - smac (MAC)
181 // User alert, 2 possibilities:
183 // 1. Learned new binding: does smac belong to sip?
185 // 2. Alert: Mismatch of stored versus announced sip-to-smac binding
187 // In both cases user action: [Learn] [Ignore] [Attack] [Amok Attack]
188 // Countermeasures: Mausezahn him!
190 // ALSO correct ARP tables of other hosts, especially on the default gateway
191 // that is, send arp replies with true binding
193 // Finally: Create logging message
199 // Add new entry in device-specific ARP table
200 // but first check if already existing or change.
202 // RETURN VALUE: 0 upon success
205 int arptable_add(struct device_struct
*dev
,
213 struct arp_table_struct
*prev
=NULL
, *cur
= dev
->arp_table
;
216 // If SA and SMAC are different this might be a MITM !!!
217 if (compare_mac(smac
, sa
)) alert
=1;
219 // Check if IP (sip) is already existing in arp table:
221 if (compare_ip(sip
, cur
->sip
)==0) { // IP found!
222 timestamp_hms(cur
->when
);
223 if (da
[0]==0xff) cur
->bc_resp
++;
224 else cur
->uni_resp
++;
225 if (compare_mac(smac
, cur
->smac
)==0) {
231 // entry with other MAC address found !
232 if (cur
->locked
==0) {
234 memcpy((void*) cur
->smac_prev
, (void*) cur
->smac
, 6);
235 memcpy((void*) cur
->smac
, (void*) smac
, 6);
236 cur
->sec_prev
=cur
->sec
;
237 cur
->nsec_prev
=cur
->nsec
;
240 if (alert
) cur
->flags
|=0x02;
250 // If we get here, then there was no entry for that IP yet!
251 // Create new arp_table entry:
252 cur
= (struct arp_table_struct
*) malloc(sizeof(struct arp_table_struct
));
253 if (cur
==NULL
) return 1;
256 if (dev
->arp_table
==NULL
) dev
->arp_table
= cur
;
257 else prev
->next
= cur
;
259 memcpy((void*) cur
->sa
, (void*) sa
, 6);
260 memcpy((void*) cur
->smac
, (void*) smac
, 6);
261 cur
->smac_prev
[0]=0x00;
262 cur
->smac_prev
[1]=0x00;
263 cur
->smac_prev
[2]=0x00;
264 cur
->smac_prev
[3]=0x00;
265 cur
->smac_prev
[4]=0x00;
266 cur
->smac_prev
[5]=0x00;
267 memcpy((void*) cur
->sip
, (void*) sip
, 4);
283 cur
->index
=i
+1; // I assume users prefer to count from 1.
284 timestamp_hms(cur
->when
);
285 if (alert
) cur
->flags
|=0x02;
292 // Validate ARP requests
293 int arpwatch(struct device_struct
*dev
,
303 // Unicast requests are considered as anomaly
305 if ((da
[0]&0x01)==0) { // broadcast bit NOT set?
306 fprintf(stderr
, "NOTE: Non-broadcast ARP request from %02x:%02x:%02x:%02x:%02x:%02x\n",
307 sa
[0], sa
[1], sa
[2], sa
[3], sa
[4], sa
[5]);