-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhopper_thread.c
96 lines (77 loc) · 2.4 KB
/
hopper_thread.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
/*
ssid-logger is a simple software to log SSID you encounter in your vicinity
Copyright © 2020-2022 solsTiCe d'Hiver
*/
#include <net/if.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <linux/nl80211.h>
#include <stdbool.h>
#include <unistd.h>
#include <pthread.h>
#ifdef HAS_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#include "hopper_thread.h"
struct nl_sock *sckt = NULL;
struct nl_msg *msg = NULL;
void cleanup_socket(void *arg)
{
nlmsg_free(msg);
nl_close(sckt);
nl_socket_free(sckt);
return;
}
// thread whose sole purpose is to switch the channel of the interface card
// following the predefined pattern set in CHANNELS
void *hop_channel(void *arg)
{
// based on https://stackoverflow.com/a/53602395/283067
char *device = (char *) arg;
uint8_t indx = 0;
size_t chan_number = sizeof(CHANNELS) / sizeof(uint8_t);
#ifdef HAS_SYS_PRCTL_H
// name our thread; using prctl instead of pthread_setname_np to avoid defining _GNU_SOURCE
prctl(PR_SET_NAME, "channel_hopper");
#endif
// push clean up code when thread is cancelled
pthread_cleanup_push(cleanup_socket, NULL);
// Create the socket and connect to it
sckt = nl_socket_alloc();
genl_connect(sckt);
int ctrl = genl_ctrl_resolve(sckt, "nl80211");
// create netlink message
msg = nlmsg_alloc();
genlmsg_put(msg, 0, 0, ctrl, 0, 0, NL80211_CMD_SET_CHANNEL, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(device));
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, 0); // correctly initialized below
// find the frequency attribute in the netlink stream message
struct nlattr *attr_freq = nlmsg_find_attr(nlmsg_hdr(msg), sizeof(uint32_t), NL80211_ATTR_WIPHY_FREQ);
// and its data portion to change it later
uint32_t *freq = nla_data(attr_freq);
while (true) {
// change the freq by changing the attribute in the netlink message
*freq = 2412 + (CHANNELS[indx] - 1) * 5; // 2.4GHz band only for now
// send the modified message
int ret = nl_send_auto(sckt, msg);
if (!ret) {
goto nla_put_failure;
}
indx++;
if (indx == chan_number) {
indx = 0;
}
usleep(SLEEP_DURATION);
pthread_testcancel();
continue;
nla_put_failure:
fprintf(stderr, "Error: failed to send netlink message\n");
fflush(stderr);
}
nlmsg_free(msg);
nl_close(sckt);
nl_socket_free(sckt);
pthread_cleanup_pop(1);
return NULL;
}