Compare commits
15 Commits
8335048075
...
88adc8a6e1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88adc8a6e1 | ||
|
|
615a4e510d | ||
|
|
8fd3d42e80 | ||
|
|
f1b9ecdeb7 | ||
|
|
861fb3ccf3 | ||
|
|
e84848de34 | ||
|
|
3216580054 | ||
|
|
86f57da1dd | ||
|
|
ae9b34285b | ||
| 21514ba17e | |||
| c15d8bb79f | |||
| 3b6a2d8905 | |||
| e215eb061c | |||
| 2f50ebad61 | |||
| 74c5c70ea3 |
11
README.md
11
README.md
@ -1,3 +1,7 @@
|
||||
# PLEASE NOTE
|
||||
It looks like Nintendo has quietly shut down the servers that manage the StreetPass data on March 28th, 2018. ESPerPass and other similar HomePass implementations have always relied on these servers. Without them it's impossible to exchange tags. This is very unfortunate and very likely spells the end of HomePass. I will keep [this project on GitHub](https://github.com/michaelshmitty/esperpass) for historical purposes and future reference but unless StreetPass comes back (through Nintendo, which is very unlikely or through a homebrew solution) this project is no longer maintained. Thanks for using ESPerPass!
|
||||
|
||||
|
||||
# ESPerPass
|
||||
A 3DS HomePass implementation for the ESP8266 programmable WiFi chip.
|
||||
Inspired by [this reddit post](https://www.reddit.com/r/3DS/comments/80k0qb/homepass_for_cheap_using_an_esp8266/)
|
||||
@ -10,8 +14,8 @@ A similar project using a Raspberry Pi 3 is [RaspiPass](https://github.com/Pinch
|
||||
|
||||
## Security considerations
|
||||
Martin Ger's original ESP WiFi Repeater software has been heavily modified to strip it of any unnecessary functionality for the purpose of this project. Convenience has given way to security by removing the web configuration interface. This makes it slightly more cumbersome to configure ESPerPass for your WiFi network, but at the same time prevents your home WiFi network configuration from potentially leaking through a web configuration page.
|
||||
~~Currently there are no firewall rules in place yet because I don't know if there is a list of official Streetpass IP addresses. A soon as this is resolved, the software should be locked down to only allow connections to those addresses, making the usage of the open network otherwise useless.~~
|
||||
Firewall rules are now in place to only allow clients connected to the "attwifi" network to access the IP addresses for the Streetpass servers. This should make the implementation more secure.
|
||||
After trying to implement firewall rules to limit the outbound connections we noticed a significant drop in Streetpass tags. Not only does the list we got from the Raspipass project seem out of date, it also appeared that the list of Streetpass addresses may be dynamic.
|
||||
So firewall functionality is not present but instead the "attwifi" network is configured to only stay up for 90 seconds every 15 minutes. After 15 minutes have passed the system will restart with a new random Streetpass mac address and the cycle will start over.
|
||||
|
||||
## Instructions
|
||||
Ok so getting this to work can be a bit of a pain. But I assure you, once it's set up you don't need to worry about it anymore. I did the development on MacOS but I'm going to assume most will be using Windows to flash the firmware and those who don't have Windows have a way to get it, either through a virtual machine or another computer.
|
||||
@ -39,5 +43,4 @@ The ESP module will remember the settings so you can now safely unplug it from y
|
||||
**NOTE**: If something about these instructions is unclear or you can't seem to make it work, just open an issue and I'll try to help out as much as I can. This initial setup is a pain, but once it's done you never need to touch it again. And for just a few $$ and some effort you have a reliable, secure Streetpass relay at home!
|
||||
|
||||
## TODO
|
||||
* ~~Implement firewall rules to restrict connections to official servers.~~ **Done!**
|
||||
* Implement mac address list management through console.
|
||||
* Review / update list of Streetpass mac addresses.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
310
user/acl.c
310
user/acl.c
@ -1,310 +0,0 @@
|
||||
#include "c_types.h"
|
||||
#include "mem.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
#include "user_interface.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES];
|
||||
uint8_t acl_freep[MAX_NO_ACLS];
|
||||
uint32_t acl_allow_count;
|
||||
uint32_t acl_deny_count;
|
||||
static packet_deny_cb my_deny_cb;
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_init()
|
||||
{
|
||||
int i;
|
||||
acl_allow_count = acl_deny_count = 0;
|
||||
my_deny_cb = NULL;
|
||||
for(i=0; i< MAX_NO_ACLS; i++)
|
||||
{
|
||||
acl_freep[i] = 0;
|
||||
acl_clear_stats(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
acl_is_empty(uint8_t acl_no)
|
||||
{
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return acl_freep[acl_no] == 0;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_clear(uint8_t acl_no)
|
||||
{
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
acl_freep[acl_no] = 0;
|
||||
acl_clear_stats(acl_no);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_clear_stats(uint8_t acl_no)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
my_deny_cb = NULL;
|
||||
for(i=0; i< MAX_ACL_ENTRIES; i++)
|
||||
acl[acl_no][i].hit_count = 0;
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
acl_add(uint8_t acl_no,
|
||||
uint32_t src,
|
||||
uint32_t s_mask,
|
||||
uint32_t dest,
|
||||
uint32_t d_mask,
|
||||
uint8_t proto,
|
||||
uint16_t s_port,
|
||||
uint16_t d_port,
|
||||
uint8_t allow)
|
||||
{
|
||||
acl_entry *my_entry;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS || acl_freep[acl_no] >= MAX_ACL_ENTRIES)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
my_entry = &acl[acl_no][acl_freep[acl_no]];
|
||||
my_entry->src = src & s_mask;
|
||||
my_entry->s_mask = s_mask;
|
||||
my_entry->dest = dest & d_mask;
|
||||
my_entry->d_mask = d_mask;
|
||||
my_entry->proto = proto;
|
||||
my_entry->s_port = s_port;
|
||||
my_entry->d_port = d_port;
|
||||
my_entry->allow = allow;
|
||||
my_entry->hit_count = 0;
|
||||
|
||||
acl_freep[acl_no]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t ICACHE_FLASH_ATTR
|
||||
acl_check_packet(uint8_t acl_no, struct pbuf *p)
|
||||
{
|
||||
struct eth_hdr *mac_h;
|
||||
struct ip_hdr *ip_h;
|
||||
uint8_t proto;
|
||||
struct udp_hdr *udp_h;
|
||||
struct tcp_hdr *tcp_h;
|
||||
uint16_t src_port, dest_port;
|
||||
uint8_t *packet;
|
||||
int i;
|
||||
acl_entry *my_entry;
|
||||
uint8_t allow;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
if (p->len < sizeof(struct eth_hdr))
|
||||
{
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
mac_h = (struct eth_hdr *)p->payload;
|
||||
|
||||
// Allow ARP
|
||||
if (ntohs(mac_h->type) == ETHTYPE_ARP)
|
||||
{
|
||||
acl_allow_count++;
|
||||
return ACL_ALLOW;
|
||||
}
|
||||
|
||||
// Drop anything else if not IPv4
|
||||
if (ntohs(mac_h->type) != ETHTYPE_IP)
|
||||
{
|
||||
acl_deny_count++;
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr))
|
||||
{
|
||||
acl_deny_count++;
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
allow = ACL_DENY;
|
||||
packet = (uint8_t*)p->payload;
|
||||
ip_h = (struct ip_hdr *)&packet[sizeof(struct eth_hdr)];
|
||||
proto = IPH_PROTO(ip_h);
|
||||
|
||||
switch (proto) {
|
||||
case IP_PROTO_UDP:
|
||||
{
|
||||
if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct udp_hdr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
udp_h = (struct udp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)];
|
||||
src_port = ntohs(udp_h->src);
|
||||
dest_port = ntohs(udp_h->dest);
|
||||
} break;
|
||||
|
||||
case IP_PROTO_TCP:
|
||||
{
|
||||
if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct tcp_hdr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
tcp_h = (struct tcp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)];
|
||||
src_port = ntohs(tcp_h->src);
|
||||
dest_port = ntohs(tcp_h->dest);
|
||||
} break;
|
||||
|
||||
case IP_PROTO_ICMP:
|
||||
{
|
||||
src_port = dest_port = 0;
|
||||
} break;
|
||||
|
||||
// Drop anything that is not UDP, TCP, or ICMP
|
||||
default:
|
||||
{
|
||||
acl_deny_count++;
|
||||
return ACL_DENY;
|
||||
} break;
|
||||
}
|
||||
|
||||
// os_printf("Src: %d.%d.%d.%d Dst: %d.%d.%d.%d Proto: %s SP:%d DP:%d\n",
|
||||
// IP2STR(&ip_h->src), IP2STR(&ip_h->dest),
|
||||
// proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4", src_port, dest_port);
|
||||
|
||||
for(i=0; i<acl_freep[acl_no]; i++)
|
||||
{
|
||||
my_entry = &acl[acl_no][i];
|
||||
if ((my_entry->proto == 0 || proto == my_entry->proto) &&
|
||||
(my_entry->src == 0 || my_entry->src == (ip_h->src.addr&my_entry->s_mask)) &&
|
||||
(my_entry->dest == 0 || my_entry->dest == (ip_h->dest.addr&my_entry->d_mask)) &&
|
||||
(my_entry->s_port == 0 || my_entry->s_port == src_port) &&
|
||||
(my_entry->d_port == 0 || my_entry->d_port == dest_port))
|
||||
{
|
||||
allow = my_entry->allow;
|
||||
my_entry->hit_count++;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (!(allow & ACL_ALLOW) && my_deny_cb != NULL)
|
||||
{
|
||||
allow = my_deny_cb(proto, ip_h->src.addr, src_port,
|
||||
ip_h->dest.addr, dest_port, allow);
|
||||
}
|
||||
if (allow & ACL_ALLOW)
|
||||
{
|
||||
acl_allow_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
acl_deny_count++;
|
||||
}
|
||||
|
||||
// os_printf(" allow: %d\r\n", allow);
|
||||
return allow;
|
||||
}
|
||||
|
||||
void
|
||||
acl_set_deny_cb(packet_deny_cb cb)
|
||||
{
|
||||
my_deny_cb = cb;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
addr2str(uint8_t *buf, uint32_t addr, uint32_t mask)
|
||||
{
|
||||
uint8_t clidr;
|
||||
|
||||
if (addr == 0)
|
||||
{
|
||||
os_sprintf(buf, "any");
|
||||
return;
|
||||
}
|
||||
|
||||
mask = ntohl(mask);
|
||||
for (clidr = 0; mask; mask <<= 1,clidr++);
|
||||
if (clidr < 32)
|
||||
{
|
||||
os_sprintf(buf, "%d.%d.%d.%d/%d", IP2STR((ip_addr_t*)&addr), clidr);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(buf, "%d.%d.%d.%d", IP2STR((ip_addr_t*)&addr));
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
port2str(uint8_t *buf, uint16_t port)
|
||||
{
|
||||
if (port == 0)
|
||||
{
|
||||
os_sprintf(buf, "any");
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(buf, "%d", port);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_show(uint8_t acl_no, uint8_t *buf)
|
||||
{
|
||||
int i;
|
||||
acl_entry *my_entry;
|
||||
uint8_t line[80], addr1[21], addr2[21], port1[6], port2[6];
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < acl_freep[acl_no]; i++)
|
||||
{
|
||||
my_entry = &acl[acl_no][i];
|
||||
addr2str(addr1, my_entry->src, my_entry->s_mask);
|
||||
port2str(port1, my_entry->s_port);
|
||||
addr2str(addr2, my_entry->dest, my_entry->d_mask);
|
||||
port2str(port2, my_entry->d_port);
|
||||
if (my_entry->proto != 0)
|
||||
{
|
||||
os_sprintf(line, "%s %s:%s %s:%s %s%s (%d hits)\r\n",
|
||||
my_entry->proto==IP_PROTO_TCP?"TCP":"UDP",
|
||||
addr1, port1, addr2, port2,
|
||||
(my_entry->allow & ACL_ALLOW)?"allow":"deny",
|
||||
(my_entry->allow & ACL_MONITOR)?"_monitor":"",
|
||||
my_entry->hit_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(line, "IP %s %s %s%s (%d hits)\r\n",
|
||||
addr1, addr2,
|
||||
(my_entry->allow & ACL_ALLOW)?"allow":"deny",
|
||||
(my_entry->allow & ACL_MONITOR)?"_monitor":"",
|
||||
my_entry->hit_count);
|
||||
}
|
||||
os_memcpy(&buf[os_strlen(buf)], line, os_strlen(line)+1);
|
||||
}
|
||||
}
|
||||
51
user/acl.h
51
user/acl.h
@ -1,51 +0,0 @@
|
||||
#ifndef _ACL_H_
|
||||
#define _ACL_H_
|
||||
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
#define MAX_NO_ACLS 4
|
||||
#define MAX_ACL_ENTRIES 30
|
||||
|
||||
#define ACL_DENY 0x0
|
||||
#define ACL_ALLOW 0x1
|
||||
#define ACL_MONITOR 0x2
|
||||
|
||||
typedef struct _acl_entry
|
||||
{
|
||||
uint32_t src;
|
||||
uint32_t s_mask;
|
||||
uint32_t dest;
|
||||
uint32_t d_mask;
|
||||
uint16_t s_port;
|
||||
uint16_t d_port;
|
||||
uint8_t proto;
|
||||
uint8_t allow;
|
||||
uint32_t hit_count;
|
||||
} acl_entry;
|
||||
|
||||
extern acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES];
|
||||
extern uint8_t acl_freep[MAX_NO_ACLS];
|
||||
extern uint32_t acl_allow_count;
|
||||
extern uint32_t acl_deny_count;
|
||||
|
||||
typedef uint8_t (*packet_deny_cb)(uint8_t proto, uint32_t saddr, uint16_t s_port, uint32_t daddr, uint16_t d_port, uint8_t allow);
|
||||
|
||||
void acl_init();
|
||||
bool acl_is_empty(uint8_t acl_no);
|
||||
void acl_clear(uint8_t acl_no);
|
||||
void acl_clear_stats(uint8_t acl_no);
|
||||
bool acl_add(uint8_t acl_no,
|
||||
uint32_t src,
|
||||
uint32_t s_mask,
|
||||
uint32_t dest,
|
||||
uint32_t d_mask,
|
||||
uint8_t proto,
|
||||
uint16_t s_port,
|
||||
uint16_t d_port,
|
||||
uint8_t allow);
|
||||
uint8_t acl_check_packet(uint8_t acl_no, struct pbuf *p);
|
||||
void acl_set_deny_cb(packet_deny_cb cb);
|
||||
void acl_show(uint8_t acl_no, uint8_t *buf);
|
||||
|
||||
#endif /* _ACL_H_ */
|
||||
@ -45,15 +45,15 @@ config_load_default(sysconfig_p config)
|
||||
wifi_get_macaddr(STATION_IF, config->STA_MAC_address);
|
||||
|
||||
config->dhcps_entries = 0;
|
||||
#ifdef ACLS
|
||||
acl_init(); // initializes the ACLs, written in config during save
|
||||
#endif
|
||||
|
||||
config->current_mac_address = 0;
|
||||
// Interval to change mac address in seconds
|
||||
// Default: 3600 (1 hour)
|
||||
// This should rotate every mac address in the list roughly every 16 hours.
|
||||
config->mac_change_interval = 3600;
|
||||
// NOTE(m): Interval at which to restart the system to select a new
|
||||
// random StreetPass MAC from the list.
|
||||
// In seconds. Default: 900 (15 minutes)
|
||||
config->system_restart_interval = 900;
|
||||
|
||||
// NOTE(m): How long to keep the "attwifi" AP up during one MAC cycle
|
||||
// In seconds. Default: 90 seconds.
|
||||
config->ap_enable_duration = 90;
|
||||
|
||||
// list of mac addresses
|
||||
// from https://docs.google.com/spreadsheets/d/1su5u-vPrQwkTixR6YnOTWSi_Ls9lV-_XNJHaWIJspv4/edit#gid=0
|
||||
@ -73,94 +73,6 @@ config_load_default(sysconfig_p config)
|
||||
ets_str2macaddr(config->mac_list[13], "4E:53:50:4F:4F:4D");
|
||||
ets_str2macaddr(config->mac_list[14], "4E:53:50:4F:4F:4E");
|
||||
ets_str2macaddr(config->mac_list[15], "4E:53:50:4F:4F:4F");
|
||||
|
||||
// Streetpass relay whitelist
|
||||
uint32_t daddr;
|
||||
uint32_t dmask;
|
||||
|
||||
// Clear all acl rules
|
||||
acl_clear(0);
|
||||
acl_clear(1);
|
||||
acl_clear(2);
|
||||
acl_clear(3);
|
||||
|
||||
// Whitelist broadcast to enable DHCP
|
||||
parse_IP_addr("255.255.255.255", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
// Whitelist DNS
|
||||
acl_add(0, 0, 0, 0, 0, IP_PROTO_UDP, 0, 53, ACL_ALLOW);
|
||||
|
||||
// Whitelist Streetpass relays
|
||||
// acl from_sta IP any 52.43.174.40 allow
|
||||
parse_IP_addr("52.43.174.40", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("104.70.153.178", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("104.74.48.110", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("23.7.18.146", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("23.7.24.35", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("52.11.210.152", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("52.25.179.65", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("52.89.56.205", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("54.148.137.96", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("54.218.98.74", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("54.218.99.79", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("54.244.22.201", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("69.25.139.140", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("192.195.204.216", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("52.10.249.207", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
// NOTE(m): New IP addresses found by Dal78
|
||||
// NOTE(m): The list of Streetpass IP addresses may be dynamic :-/
|
||||
parse_IP_addr("52.24.183.161", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("52.39.19.157", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("34.208.213.200", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("104.103.189.191", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("23.2.226.76", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
parse_IP_addr("35.167.248.201", &daddr, &dmask);
|
||||
acl_add(0, 0, 0, daddr, dmask, 0, 0, 0, ACL_ALLOW);
|
||||
|
||||
// Default implementation denies everything not matched above.
|
||||
// This last rule is not necessary and commented out to save memory space:
|
||||
// acl_add(0, 0, 0, 0, 0, 0, 0, 0, ACL_DENY);
|
||||
}
|
||||
|
||||
int
|
||||
@ -193,10 +105,7 @@ config_load(sysconfig_p config)
|
||||
config_save(config);
|
||||
return -1;
|
||||
}
|
||||
#ifdef ACLS
|
||||
os_memcpy(&acl, &(config->acl), sizeof(acl));
|
||||
os_memcpy(&acl_freep, &(config->acl_freep), sizeof(acl_freep));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -204,10 +113,6 @@ void
|
||||
config_save(sysconfig_p config)
|
||||
{
|
||||
uint16_t base_address = FLASH_BLOCK_NO;
|
||||
#ifdef ACLS
|
||||
os_memcpy(&(config->acl), &acl, sizeof(acl));
|
||||
os_memcpy(&(config->acl_freep), &acl_freep, sizeof(acl_freep));
|
||||
#endif
|
||||
os_printf("Saving configuration\r\n");
|
||||
spi_flash_erase_sector(base_address);
|
||||
spi_flash_write(base_address * SPI_FLASH_SEC_SIZE,
|
||||
|
||||
@ -11,13 +11,13 @@
|
||||
#include "lwip/app/dhcpserver.h"
|
||||
|
||||
#include "user_config.h"
|
||||
#include "acl.h"
|
||||
|
||||
#define FLASH_BLOCK_NO 0xc
|
||||
|
||||
#define MAGIC_NUMBER 0x112005fc
|
||||
|
||||
#define MAX_MAC_LIST_LENGTH 15
|
||||
// Number of mac addresses in StreetPass relay mac list
|
||||
#define MAC_LIST_LENGTH 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -35,9 +35,11 @@ typedef struct
|
||||
uint8_t bssid[6]; // Optional: BSSID the AP
|
||||
uint8_t sta_hostname[32]; // Name of the station
|
||||
uint8_t ap_ssid[32]; // SSID of the own AP
|
||||
|
||||
// ESPerPass specific configuration
|
||||
uint8_t first_run; // Has ESPerPass been configured yet?
|
||||
uint8_t current_mac_address; // Holds currently broadcasted HomePass mac address index
|
||||
int32_t mac_change_interval; // Interval to rotate HomePass mac address (in seconds)
|
||||
int32_t system_restart_interval;
|
||||
int32_t ap_enable_duration;
|
||||
|
||||
// Seconds without ap traffic will cause reset (-1 off, default)
|
||||
int32_t ap_watchdog;
|
||||
@ -60,14 +62,10 @@ typedef struct
|
||||
|
||||
uint16_t dhcps_entries; // number of allocated entries in the following table
|
||||
struct dhcps_pool dhcps_p[MAX_DHCP]; // DHCP entries
|
||||
#ifdef ACLS
|
||||
acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; // ACL entries
|
||||
uint8_t acl_freep[MAX_NO_ACLS]; // ACL free pointers
|
||||
#endif
|
||||
|
||||
// HomePass mac list
|
||||
// Allow 20 slots
|
||||
uint8_t mac_list[19][6];
|
||||
uint8_t mac_list[MAC_LIST_LENGTH][6];
|
||||
|
||||
} sysconfig_t, *sysconfig_p;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef _USER_CONFIG_
|
||||
#define _USER_CONFIG_
|
||||
|
||||
#define ESPERPASS_VERSION "V0.0.6"
|
||||
#define ESPERPASS_VERSION "V0.1.0"
|
||||
|
||||
#define WIFI_SSID "ssid"
|
||||
#define WIFI_PASSWORD "password"
|
||||
@ -27,11 +27,6 @@
|
||||
//
|
||||
#define PHY_MODE 1
|
||||
|
||||
//
|
||||
// Define this if you want to have ACLs for the SoftAP.
|
||||
//
|
||||
#define ACLS 1
|
||||
|
||||
// Internal
|
||||
typedef enum {SIG_DO_NOTHING=0, SIG_START_SERVER=1, SIG_SEND_DATA, SIG_UART0, SIG_CONSOLE_RX, SIG_CONSOLE_TX, SIG_CONSOLE_TX_RAW, SIG_GPIO_INT} USER_SIGNALS;
|
||||
|
||||
|
||||
353
user/user_main.c
353
user/user_main.c
@ -23,10 +23,6 @@
|
||||
|
||||
#include "easygpio.h"
|
||||
|
||||
#ifdef ACLS
|
||||
#include "acl.h"
|
||||
#endif
|
||||
|
||||
/* System Task, for signals refer to user_config.h */
|
||||
#define user_procTaskPrio 0
|
||||
#define user_procTaskQueueLen 1
|
||||
@ -37,7 +33,8 @@ static os_timer_t ptimer;
|
||||
|
||||
int32_t ap_watchdog_cnt;
|
||||
int32_t client_watchdog_cnt;
|
||||
int32_t mac_cnt;
|
||||
int32_t awake_cnt = 0;
|
||||
int32_t ap_enabled_cnt = 0;
|
||||
|
||||
/* Some stats */
|
||||
uint64_t Bytes_in, Bytes_out, Bytes_in_last, Bytes_out_last;
|
||||
@ -65,6 +62,14 @@ void ICACHE_FLASH_ATTR user_set_softap_wifi_config(void);
|
||||
void ICACHE_FLASH_ATTR user_set_softap_ip_config(void);
|
||||
void ICACHE_FLASH_ATTR user_set_station_config(void);
|
||||
|
||||
uint8_t current_mac_address_index = 0;;
|
||||
|
||||
int
|
||||
ICACHE_FLASH_ATTR random_mac_index()
|
||||
{
|
||||
return rand() % sizeof(config.mac_list) / sizeof(config.mac_list[0]);
|
||||
}
|
||||
|
||||
void
|
||||
ICACHE_FLASH_ATTR to_console(char *str)
|
||||
{
|
||||
@ -83,24 +88,6 @@ my_input_ap(struct pbuf *p, struct netif *inp)
|
||||
|
||||
client_watchdog_cnt = config.client_watchdog;
|
||||
|
||||
#ifdef ACLS
|
||||
// Check ACLs - store result
|
||||
uint8_t acl_check = ACL_ALLOW;
|
||||
if (!acl_is_empty(0))
|
||||
{
|
||||
acl_check = acl_check_packet(0, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACLS
|
||||
// If not allowed, drop packet
|
||||
if (!(acl_check&ACL_ALLOW))
|
||||
{
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Bytes_in += p->tot_len;
|
||||
Packets_in++;
|
||||
|
||||
@ -117,24 +104,6 @@ my_output_ap(struct netif *outp, struct pbuf *p)
|
||||
easygpio_outputSet (config.status_led, 0);
|
||||
}
|
||||
|
||||
#ifdef ACLS
|
||||
// Check ACLs - store result
|
||||
uint8_t acl_check = ACL_ALLOW;
|
||||
if (!acl_is_empty(1))
|
||||
{
|
||||
acl_check = acl_check_packet(1, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACLS
|
||||
// If not allowed, drop packet
|
||||
if (!(acl_check&ACL_ALLOW))
|
||||
{
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Bytes_out += p->tot_len;
|
||||
Packets_out++;
|
||||
|
||||
@ -145,26 +114,12 @@ err_t ICACHE_FLASH_ATTR
|
||||
my_input_sta(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
ap_watchdog_cnt = config.ap_watchdog;
|
||||
#ifdef ACLS
|
||||
if (!acl_is_empty(2) && !(acl_check_packet(2, p) & ACL_ALLOW))
|
||||
{
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
orig_input_sta (p, inp);
|
||||
}
|
||||
|
||||
err_t ICACHE_FLASH_ATTR
|
||||
my_output_sta(struct netif *outp, struct pbuf *p)
|
||||
{
|
||||
#ifdef ACLS
|
||||
if (!acl_is_empty(3) && !(acl_check_packet(3, p) & ACL_ALLOW))
|
||||
{
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
orig_output_sta (outp, p);
|
||||
}
|
||||
|
||||
@ -304,67 +259,6 @@ console_send_response(struct espconn *pespconn, uint8_t do_cmd)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ACLS
|
||||
void ICACHE_FLASH_ATTR
|
||||
parse_IP_addr(uint8_t *str, uint32_t *addr, uint32_t *mask)
|
||||
{
|
||||
int i;
|
||||
uint32_t net;
|
||||
if (strcmp(str, "any") == 0)
|
||||
{
|
||||
*addr = 0;
|
||||
*mask = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0; str[i]!=0 && str[i]!='/'; i++);
|
||||
|
||||
*mask = 0xffffffff;
|
||||
if (str[i]!=0)
|
||||
{
|
||||
str[i]=0;
|
||||
*mask <<= (32 - atoi(&str[i+1]));
|
||||
}
|
||||
*mask = htonl(*mask);
|
||||
*addr = ipaddr_addr(str);
|
||||
}
|
||||
|
||||
struct espconn *deny_cb_conn = 0;
|
||||
uint8_t acl_debug = 0;
|
||||
|
||||
uint8_t
|
||||
acl_deny_cb(uint8_t proto,
|
||||
uint32_t saddr,
|
||||
uint16_t s_port,
|
||||
uint32_t daddr,
|
||||
uint16_t d_port,
|
||||
uint8_t allow)
|
||||
{
|
||||
char response[128];
|
||||
|
||||
if (!acl_debug)
|
||||
{
|
||||
return allow;
|
||||
}
|
||||
|
||||
os_sprintf(response,
|
||||
"\rdeny: %s Src: %d.%d.%d.%d:%d Dst: %d.%d.%d.%d:%d\r\n",
|
||||
proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4",
|
||||
IP2STR((ip_addr_t *)&saddr),
|
||||
s_port,
|
||||
IP2STR((ip_addr_t *)&daddr),
|
||||
d_port);
|
||||
|
||||
if (acl_debug)
|
||||
{
|
||||
to_console(response);
|
||||
system_os_post(0, SIG_CONSOLE_TX, (ETSParam) deny_cb_conn);
|
||||
}
|
||||
return allow;
|
||||
}
|
||||
#endif /* ACLS */
|
||||
|
||||
// Use this from ROM instead
|
||||
int ets_str2macaddr(uint8 *mac, char *str_mac);
|
||||
#define parse_mac ets_str2macaddr
|
||||
@ -431,10 +325,6 @@ console_handle_command(struct espconn *pespconn)
|
||||
to_console(response);
|
||||
#endif
|
||||
|
||||
#ifdef ACLS
|
||||
os_sprintf(response, "acl [from_sta|to_sta|from_ap|to_ap] clear\r\nacl [from_sta|to_sta|from_ap|to_ap] [IP|TCP|UDP] <src_addr> [<src_port>] <dest_addr> [<dest_port>] [allow|deny|allow_monitor|deny_monitor]\r\n");
|
||||
to_console(response);
|
||||
#endif
|
||||
goto command_handled_2;
|
||||
}
|
||||
|
||||
@ -444,7 +334,7 @@ console_handle_command(struct espconn *pespconn)
|
||||
int16_t i;
|
||||
|
||||
to_console("HomePass mac list:\r\n");
|
||||
for (i = 0; i < MAX_MAC_LIST_LENGTH; i++)
|
||||
for (i = 0; i <= MAC_LIST_LENGTH - 1; i++)
|
||||
{
|
||||
os_sprintf(response, "%02x:%02x:%02x:%02x:%02x:%02x\r\n",
|
||||
config.mac_list[i][0], config.mac_list[i][1],
|
||||
@ -579,144 +469,8 @@ console_handle_command(struct espconn *pespconn)
|
||||
}
|
||||
goto command_handled_2;
|
||||
}
|
||||
#ifdef ACLS
|
||||
if (nTokens == 2 && strcmp(tokens[1], "acl") == 0)
|
||||
{
|
||||
char *txt[] = {"From STA:\r\n",
|
||||
"To STA:\r\n", "From AP:\r\n", "To AP:\r\n"};
|
||||
for (i = 0; i<MAX_NO_ACLS; i++)
|
||||
{
|
||||
if (!acl_is_empty(i))
|
||||
{
|
||||
ringbuf_memcpy_into(console_tx_buffer, txt[i], os_strlen(txt[i]));
|
||||
acl_show(i, response);
|
||||
to_console(response);
|
||||
}
|
||||
}
|
||||
os_sprintf(response, "Packets denied: %d Packets allowed: %d\r\n",
|
||||
acl_deny_count, acl_allow_count);
|
||||
to_console(response);
|
||||
goto command_handled_2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ACLS
|
||||
if (strcmp(tokens[0], "acl") == 0)
|
||||
{
|
||||
uint8_t acl_no;
|
||||
uint8_t proto;
|
||||
uint32_t saddr;
|
||||
uint32_t smask;
|
||||
uint16_t sport;
|
||||
uint32_t daddr;
|
||||
uint32_t dmask;
|
||||
uint16_t dport;
|
||||
uint8_t allow;
|
||||
uint8_t last_arg;
|
||||
|
||||
if (nTokens < 3)
|
||||
{
|
||||
os_sprintf(response, INVALID_NUMARGS);
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
if (strcmp(tokens[1],"from_sta")==0)
|
||||
{
|
||||
acl_no = 0;
|
||||
}
|
||||
else if (strcmp(tokens[1],"to_sta")==0)
|
||||
{
|
||||
acl_no = 1;
|
||||
}
|
||||
else if (strcmp(tokens[1],"from_ap")==0)
|
||||
{
|
||||
acl_no = 2;
|
||||
}
|
||||
else if (strcmp(tokens[1],"to_ap")==0)
|
||||
{
|
||||
acl_no = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(response, INVALID_ARG);
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
if (strcmp(tokens[2],"clear")==0)
|
||||
{
|
||||
acl_clear(acl_no);
|
||||
os_sprintf(response, "ACL cleared\r\n");
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
last_arg = 7;
|
||||
if (strcmp(tokens[2],"IP") == 0)
|
||||
{
|
||||
proto = 0;
|
||||
last_arg = 5;
|
||||
}
|
||||
else if (strcmp(tokens[2],"TCP") == 0)
|
||||
{
|
||||
proto = IP_PROTO_TCP;
|
||||
}
|
||||
else if (strcmp(tokens[2],"UDP") == 0)
|
||||
{
|
||||
proto = IP_PROTO_UDP;
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(response, INVALID_ARG);
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
if (nTokens != last_arg+1)
|
||||
{
|
||||
os_sprintf(response, INVALID_NUMARGS);
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
if (proto == 0)
|
||||
{
|
||||
parse_IP_addr(tokens[3], &saddr, &smask);
|
||||
parse_IP_addr(tokens[4], &daddr, &dmask);
|
||||
sport = dport = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
parse_IP_addr(tokens[3], &saddr, &smask);
|
||||
sport = (uint16_t)atoi(tokens[4]);
|
||||
parse_IP_addr(tokens[5], &daddr, &dmask);
|
||||
dport = (uint16_t)atoi(tokens[6]);
|
||||
}
|
||||
|
||||
if (strcmp(tokens[last_arg],"allow") == 0)
|
||||
{
|
||||
allow = ACL_ALLOW;
|
||||
}
|
||||
else if (strcmp(tokens[last_arg],"deny") == 0)
|
||||
{
|
||||
allow = ACL_DENY;
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(response, INVALID_ARG);
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
if (acl_add(acl_no, saddr, smask, daddr, dmask, proto, sport,
|
||||
dport, allow))
|
||||
{
|
||||
os_sprintf(response, "ACL added\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(response, "ACL add failed\r\n");
|
||||
}
|
||||
goto command_handled;
|
||||
}
|
||||
#endif /* ACLS */
|
||||
|
||||
if (strcmp(tokens[0], "connect") == 0)
|
||||
{
|
||||
if (nTokens > 1)
|
||||
@ -947,15 +701,6 @@ console_handle_command(struct espconn *pespconn)
|
||||
goto command_handled;
|
||||
}
|
||||
|
||||
#ifdef ACLS
|
||||
if (strcmp(tokens[1], "acl_debug") == 0)
|
||||
{
|
||||
acl_debug = atoi(tokens[2]);
|
||||
os_sprintf(response, "ACL debug set\r\n");
|
||||
goto command_handled;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(tokens[1], "speed") == 0)
|
||||
{
|
||||
uint16_t speed = atoi(tokens[2]);
|
||||
@ -1144,50 +889,34 @@ timer_func(void *arg)
|
||||
// Check if watchdogs
|
||||
if (toggle)
|
||||
{
|
||||
// Rotate HomePass mac address if necessary
|
||||
if (config.auto_connect == 1)
|
||||
{
|
||||
if (mac_cnt >= config.mac_change_interval)
|
||||
// NOTE(m): Restart the system after a while to set a new random
|
||||
// StreetPass MAC address from the list.
|
||||
if (awake_cnt >= config.system_restart_interval)
|
||||
{
|
||||
mac_cnt = 0;
|
||||
// os_printf("Rotating mac address...\r\n");
|
||||
// os_printf("config.current_mac_address = %d\r\n", config.current_mac_address);
|
||||
|
||||
// os_printf("OLD MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
|
||||
// config.mac_list[config.current_mac_address][0],
|
||||
// config.mac_list[config.current_mac_address][1],
|
||||
// config.mac_list[config.current_mac_address][2],
|
||||
// config.mac_list[config.current_mac_address][3],
|
||||
// config.mac_list[config.current_mac_address][4],
|
||||
// config.mac_list[config.current_mac_address][5]);
|
||||
|
||||
if (config.current_mac_address >= (MAX_MAC_LIST_LENGTH - 1))
|
||||
{
|
||||
config.current_mac_address = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
config.current_mac_address++;
|
||||
}
|
||||
|
||||
// os_printf("NEW MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n\r\n",
|
||||
// config.mac_list[config.current_mac_address][0],
|
||||
// config.mac_list[config.current_mac_address][1],
|
||||
// config.mac_list[config.current_mac_address][2],
|
||||
// config.mac_list[config.current_mac_address][3],
|
||||
// config.mac_list[config.current_mac_address][4],
|
||||
// config.mac_list[config.current_mac_address][5]);
|
||||
|
||||
// Save current mac address config to flash
|
||||
config_save(&config);
|
||||
|
||||
// Start using new mac address
|
||||
// wifi_set_macaddr(SOFTAP_IF, config.mac_list[config.current_mac_address]);
|
||||
system_restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
mac_cnt++;
|
||||
awake_cnt++;
|
||||
}
|
||||
|
||||
// NOTE(m): Switch off the access point after a while if
|
||||
// it's not switched off already.
|
||||
if (wifi_get_opmode() == STATIONAP_MODE)
|
||||
{
|
||||
if (ap_enabled_cnt >= config.ap_enable_duration)
|
||||
{
|
||||
ap_enabled_cnt = 0;
|
||||
{
|
||||
wifi_set_opmode(STATION_MODE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ap_enabled_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1456,6 +1185,11 @@ user_set_station_config(void)
|
||||
void ICACHE_FLASH_ATTR
|
||||
user_init()
|
||||
{
|
||||
// Generate random seed for rand() function
|
||||
srand(system_get_rtc_time());
|
||||
// Generate random mac address index
|
||||
current_mac_address_index = random_mac_index();
|
||||
|
||||
struct ip_info info;
|
||||
|
||||
connected = false;
|
||||
@ -1478,15 +1212,6 @@ user_init()
|
||||
// Load config
|
||||
config_load(&config);
|
||||
|
||||
#ifdef ACLS
|
||||
acl_debug = 0;
|
||||
int i;
|
||||
for(i=0; i< MAX_NO_ACLS; i++)
|
||||
{
|
||||
acl_clear_stats(i);
|
||||
}
|
||||
acl_set_deny_cb(acl_deny_cb);
|
||||
#endif
|
||||
// Config GPIO pin as output
|
||||
if (config.status_led == 1)
|
||||
{
|
||||
@ -1516,7 +1241,7 @@ user_init()
|
||||
}
|
||||
|
||||
wifi_set_opmode(STATIONAP_MODE);
|
||||
wifi_set_macaddr(SOFTAP_IF, config.mac_list[config.current_mac_address]);
|
||||
wifi_set_macaddr(SOFTAP_IF, config.mac_list[current_mac_address_index]);
|
||||
user_set_softap_wifi_config();
|
||||
do_ip_config = true;
|
||||
|
||||
@ -1569,7 +1294,7 @@ user_init()
|
||||
os_timer_setfn(&ptimer, timer_func, 0);
|
||||
os_timer_arm(&ptimer, 500, 0);
|
||||
|
||||
//Start task
|
||||
// Start task
|
||||
system_os_task(user_procTask, user_procTaskPrio, user_procTaskQueue,
|
||||
user_procTaskQueueLen);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user