Introduction
Introduction Statistics Contact Development Disclaimer Help
dwmstatus-mitm.c - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwmstatus-mitm.c (3958B)
---
1 /* Here is a helper function that warns you if someone tries to sniff yo…
2 * network traffic (i.e. a Man-In-The-Middle attack ran against you than…
3 * to ARP cache poisoning).
4 *
5 * It must be called regularly because it monitors changes in the ARP ta…
6 * If a host got a new MAC address, it will alert during ALERT_TIMEOUT s…
7 * If the MAC address remains the same, it assumes it is just a new host.
8 * Otherwise, if it keep changing, it will keep on alerting.
9 *
10 * Returns true on success, false otherwise.
11 *
12 * Written by vladz (vladz AT devzero.fr).
13 * Updated by mephesto1337 ( dwm-status AT junk-mail.fr )
14 */
15
16 #include <arpa/inet.h>
17 #include <linux/if_ether.h>
18 #include <netinet/in.h>
19 #include <stdbool.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25
26
27 // Some useful macros
28 #define CHK(expr, cond) \
29 do { \
30 if ( (expr) cond ) { \
31 fprintf(stderr, "%s failed", #expr); \
32 goto fail; \
33 } \
34 } while ( 0 )
35
36 #define CHK_NEG(expr) CHK((long)(expr), < 0L)
37 #define CHK_FALSE(expr) CHK(!!(expr), == false)
38 #define CHK_NULL(expr) CHK(expr, == NULL)
39 #define SAFE_FREE(func, ptr) \
40 do { \
41 if ( ptr != NULL ) { \
42 func(ptr); \
43 } \
44 ptr = NULL; \
45 } while ( 0 )
46 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
47
48 #define ALERT_TIMEOUT ((time_t)40L) // In seconds
49
50 /* The hard maximum number of entries kept in the ARP cache is obtained …
51 * "sysctl net.ipv4.neigh.default.gc_thresh3" (see arp(7)). Default val…
52 * for Linux is 1024.
53 */
54 #define MAX_ARP_CACHE_ENTRIES 1024
55
56
57 struct ether_ip_s {
58 union {
59 uint8_t mac[ETH_ALEN];
60 unsigned long lmac;
61 };
62 time_t last_changed;
63 in_addr_t ip;
64 };
65
66 struct ether_ip_s table[MAX_ARP_CACHE_ENTRIES];
67 size_t table_size = 0;
68
69
70 bool lookup_and_insert(const struct ether_ip_s *new);
71
72 bool check_arp_table(char *message, size_t len) {
73 FILE *f;
74 struct ether_ip_s tmp;
75 char ip_address[32];
76 char mac_address[32];
77
78 snprintf(message, len, "ARP table OK");
79 CHK_NULL(f = fopen("/proc/net/arp", "r"));
80 time(&tmp.last_changed);
81 fscanf(f, "%*[^\n]\n");
82 while ( !feof(f) ) {
83 CHK(fscanf(f, "%s%*[ ]0x%*x%*[ ]0x%*x%*[ ]%[a-f0-9:]%*[^\n]\n", …
84 CHK_NEG(inet_pton(AF_INET, ip_address, &tmp.ip));
85
86 tmp.lmac = 0UL;
87 CHK(sscanf(
88 mac_address, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
89 &tmp.mac[0], &tmp.mac[1], &tmp.mac[2], &tmp.mac[3], &tmp.mac…
90 ), != 6);
91
92 if ( ! lookup_and_insert(&tmp) ) {
93 snprintf(message, len, "Possible MITM attack, please check %…
94 break;
95 }
96 }
97 SAFE_FREE(fclose, f);
98 return true;
99
100 fail:
101 SAFE_FREE(fclose, f);
102 snprintf(message, len, "ARP table ???");
103 return false;
104 }
105
106 bool lookup_and_insert(const struct ether_ip_s *new) {
107 for ( size_t i = 0; i < table_size; i++ ) {
108 if ( table[i].ip == new->ip ) {
109 if ( table[i].lmac != new->lmac ) {
110 if ( table[i].last_changed + ALERT_TIMEOUT > new->last_c…
111 return false;
112 } else {
113 // Update the DB, it must be a new host
114 table[i].lmac = new->lmac;
115 table[i].last_changed = new->last_changed;
116 return true;
117 }
118 } else {
119 // Update last seen
120 table[i].last_changed = new->last_changed;
121 return true;
122 }
123 }
124 }
125
126 if ( table_size < ARRAY_SIZE(table) ) {
127 memcpy(&table[table_size], new, sizeof(struct ether_ip_s));
128 table_size++;
129 } else {
130 // To big, let's restart from the begining
131 table_size = 0;
132 return false;
133 }
134
135 return true;
136 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.