summaryrefslogtreecommitdiff
path: root/toxcore/LAN_discovery.c
diff options
context:
space:
mode:
authorjin-eld <jin at mediatomb dot cc>2013-08-04 15:10:37 +0300
committerjin-eld <jin at mediatomb dot cc>2013-08-24 03:25:07 +0300
commite658892793c42b2d058eed0937025ef2ddaaa372 (patch)
tree2a022cab057f2c16ca95860ed980092880052f6e /toxcore/LAN_discovery.c
parente2aa8161adc85795fe4d63d4642f47e90937ddc2 (diff)
Rename core directory because of autoconf name clash
While doing the checks configure might generate "core" files and will then try to remove them. Having a "core" directory generates an error while runing the configure script. There's no workaround but to rename the core directory.
Diffstat (limited to 'toxcore/LAN_discovery.c')
-rw-r--r--toxcore/LAN_discovery.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
new file mode 100644
index 00000000..49f52ce7
--- /dev/null
+++ b/toxcore/LAN_discovery.c
@@ -0,0 +1,152 @@
1/* LAN_discovery.c
2 *
3 * LAN discovery implementation.
4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#include "LAN_discovery.h"
25
26#define MAX_INTERFACES 16
27
28#ifdef __linux
29/* get the first working broadcast address that's not from "lo"
30 * returns higher than 0 on success
31 * returns 0 on error */
32static uint32_t get_broadcast(void)
33{
34 /* not sure how many platforms this will
35 * run on, so it's wrapped in __linux for now */
36 struct sockaddr_in *sock_holder = NULL;
37 struct ifreq i_faces[MAX_INTERFACES];
38 struct ifconf ifconf;
39 int count = 0;
40 int sock = 0;
41 int i = 0;
42
43 /* configure ifconf for the ioctl call */
44 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
45 perror("[!] get_broadcast: socket() error");
46 return 0;
47 }
48
49 memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES);
50
51 ifconf.ifc_buf = (char *)i_faces;
52 ifconf.ifc_len = sizeof(i_faces);
53 count = ifconf.ifc_len / sizeof(struct ifreq);
54
55 if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
56 perror("get_broadcast: ioctl() error");
57 return 0;
58 }
59
60 for (i = 0; i < count; i++) {
61 /* skip the loopback interface, as it's useless */
62 if (strcmp(i_faces[i].ifr_name, "lo") != 0) {
63 if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
64 perror("[!] get_broadcast: ioctl error");
65 return 0;
66 }
67
68 /* just to clarify where we're getting the values from */
69 sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
70 break;
71 }
72 }
73
74 close(sock);
75
76 if (sock_holder == NULL) {
77 perror("[!] no broadcast device found");
78 return 0;
79 }
80
81 return sock_holder->sin_addr.s_addr;
82}
83#endif
84
85/* Return the broadcast ip */
86static IP broadcast_ip(void)
87{
88 IP ip;
89#ifdef __linux
90 ip.i = get_broadcast();
91
92 if (ip.i == 0)
93 /* error errored, but try anyway? */
94 ip.i = ~0;
95
96#else
97 ip.i = ~0;
98#endif
99 return ip;
100}
101
102/*return 0 if ip is a LAN ip
103 return -1 if it is not */
104static int LAN_ip(IP ip)
105{
106 if (ip.c[0] == 127)/* Loopback */
107 return 0;
108
109 if (ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */
110 return 0;
111
112 if (ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */
113 return 0;
114
115 if (ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */
116 return 0;
117
118 if (ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */
119 return 0;
120
121 return -1;
122}
123
124static int handle_LANdiscovery(void *object, IP_Port source, uint8_t *packet, uint32_t length)
125{
126 DHT *dht = object;
127
128 if (LAN_ip(source.ip) == -1)
129 return 1;
130
131 if (length != crypto_box_PUBLICKEYBYTES + 1)
132 return 1;
133
134 DHT_bootstrap(dht, source, packet + 1);
135 return 0;
136}
137
138
139int send_LANdiscovery(uint16_t port, Net_Crypto *c)
140{
141 uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
142 data[0] = NET_PACKET_LAN_DISCOVERY;
143 memcpy(data + 1, c->self_public_key, crypto_box_PUBLICKEYBYTES);
144 IP_Port ip_port = {broadcast_ip(), port};
145 return sendpacket(c->lossless_udp->net->sock, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES);
146}
147
148
149void LANdiscovery_init(DHT *dht)
150{
151 networking_registerhandler(dht->c->lossless_udp->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
152}