1/* Copyright (C) 2007-2015 B.A.T.M.A.N. contributors:
2 *
3 * Marek Lindner
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "icmp_socket.h"
19#include "main.h"
20
21#include <linux/atomic.h>
22#include <linux/compiler.h>
23#include <linux/debugfs.h>
24#include <linux/errno.h>
25#include <linux/etherdevice.h>
26#include <linux/export.h>
27#include <linux/fcntl.h>
28#include <linux/fs.h>
29#include <linux/if_ether.h>
30#include <linux/kernel.h>
31#include <linux/list.h>
32#include <linux/module.h>
33#include <linux/netdevice.h>
34#include <linux/pkt_sched.h>
35#include <linux/poll.h>
36#include <linux/printk.h>
37#include <linux/sched.h> /* for linux/wait.h */
38#include <linux/skbuff.h>
39#include <linux/slab.h>
40#include <linux/spinlock.h>
41#include <linux/stat.h>
42#include <linux/stddef.h>
43#include <linux/string.h>
44#include <linux/uaccess.h>
45#include <linux/wait.h>
46
47#include "hard-interface.h"
48#include "originator.h"
49#include "packet.h"
50#include "send.h"
51
52static struct batadv_socket_client *batadv_socket_client_hash[256];
53
54static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
55				     struct batadv_icmp_header *icmph,
56				     size_t icmp_len);
57
58void batadv_socket_init(void)
59{
60	memset(batadv_socket_client_hash, 0, sizeof(batadv_socket_client_hash));
61}
62
63static int batadv_socket_open(struct inode *inode, struct file *file)
64{
65	unsigned int i;
66	struct batadv_socket_client *socket_client;
67
68	if (!try_module_get(THIS_MODULE))
69		return -EBUSY;
70
71	nonseekable_open(inode, file);
72
73	socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
74	if (!socket_client) {
75		module_put(THIS_MODULE);
76		return -ENOMEM;
77	}
78
79	for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) {
80		if (!batadv_socket_client_hash[i]) {
81			batadv_socket_client_hash[i] = socket_client;
82			break;
83		}
84	}
85
86	if (i == ARRAY_SIZE(batadv_socket_client_hash)) {
87		pr_err("Error - can't add another packet client: maximum number of clients reached\n");
88		kfree(socket_client);
89		module_put(THIS_MODULE);
90		return -EXFULL;
91	}
92
93	INIT_LIST_HEAD(&socket_client->queue_list);
94	socket_client->queue_len = 0;
95	socket_client->index = i;
96	socket_client->bat_priv = inode->i_private;
97	spin_lock_init(&socket_client->lock);
98	init_waitqueue_head(&socket_client->queue_wait);
99
100	file->private_data = socket_client;
101
102	return 0;
103}
104
105static int batadv_socket_release(struct inode *inode, struct file *file)
106{
107	struct batadv_socket_client *socket_client = file->private_data;
108	struct batadv_socket_packet *socket_packet;
109	struct list_head *list_pos, *list_pos_tmp;
110
111	spin_lock_bh(&socket_client->lock);
112
113	/* for all packets in the queue ... */
114	list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) {
115		socket_packet = list_entry(list_pos,
116					   struct batadv_socket_packet, list);
117
118		list_del(list_pos);
119		kfree(socket_packet);
120	}
121
122	batadv_socket_client_hash[socket_client->index] = NULL;
123	spin_unlock_bh(&socket_client->lock);
124
125	kfree(socket_client);
126	module_put(THIS_MODULE);
127
128	return 0;
129}
130
131static ssize_t batadv_socket_read(struct file *file, char __user *buf,
132				  size_t count, loff_t *ppos)
133{
134	struct batadv_socket_client *socket_client = file->private_data;
135	struct batadv_socket_packet *socket_packet;
136	size_t packet_len;
137	int error;
138
139	if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0))
140		return -EAGAIN;
141
142	if ((!buf) || (count < sizeof(struct batadv_icmp_packet)))
143		return -EINVAL;
144
145	if (!access_ok(VERIFY_WRITE, buf, count))
146		return -EFAULT;
147
148	error = wait_event_interruptible(socket_client->queue_wait,
149					 socket_client->queue_len);
150
151	if (error)
152		return error;
153
154	spin_lock_bh(&socket_client->lock);
155
156	socket_packet = list_first_entry(&socket_client->queue_list,
157					 struct batadv_socket_packet, list);
158	list_del(&socket_packet->list);
159	socket_client->queue_len--;
160
161	spin_unlock_bh(&socket_client->lock);
162
163	packet_len = min(count, socket_packet->icmp_len);
164	error = copy_to_user(buf, &socket_packet->icmp_packet, packet_len);
165
166	kfree(socket_packet);
167
168	if (error)
169		return -EFAULT;
170
171	return packet_len;
172}
173
174static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
175				   size_t len, loff_t *off)
176{
177	struct batadv_socket_client *socket_client = file->private_data;
178	struct batadv_priv *bat_priv = socket_client->bat_priv;
179	struct batadv_hard_iface *primary_if = NULL;
180	struct sk_buff *skb;
181	struct batadv_icmp_packet_rr *icmp_packet_rr;
182	struct batadv_icmp_header *icmp_header;
183	struct batadv_orig_node *orig_node = NULL;
184	struct batadv_neigh_node *neigh_node = NULL;
185	size_t packet_len = sizeof(struct batadv_icmp_packet);
186	u8 *addr;
187
188	if (len < sizeof(struct batadv_icmp_header)) {
189		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
190			   "Error - can't send packet from char device: invalid packet size\n");
191		return -EINVAL;
192	}
193
194	primary_if = batadv_primary_if_get_selected(bat_priv);
195
196	if (!primary_if) {
197		len = -EFAULT;
198		goto out;
199	}
200
201	if (len >= BATADV_ICMP_MAX_PACKET_SIZE)
202		packet_len = BATADV_ICMP_MAX_PACKET_SIZE;
203	else
204		packet_len = len;
205
206	skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
207	if (!skb) {
208		len = -ENOMEM;
209		goto out;
210	}
211
212	skb->priority = TC_PRIO_CONTROL;
213	skb_reserve(skb, ETH_HLEN);
214	icmp_header = (struct batadv_icmp_header *)skb_put(skb, packet_len);
215
216	if (copy_from_user(icmp_header, buff, packet_len)) {
217		len = -EFAULT;
218		goto free_skb;
219	}
220
221	if (icmp_header->packet_type != BATADV_ICMP) {
222		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
223			   "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
224		len = -EINVAL;
225		goto free_skb;
226	}
227
228	switch (icmp_header->msg_type) {
229	case BATADV_ECHO_REQUEST:
230		if (len < sizeof(struct batadv_icmp_packet)) {
231			batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
232				   "Error - can't send packet from char device: invalid packet size\n");
233			len = -EINVAL;
234			goto free_skb;
235		}
236
237		if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
238			goto dst_unreach;
239
240		orig_node = batadv_orig_hash_find(bat_priv, icmp_header->dst);
241		if (!orig_node)
242			goto dst_unreach;
243
244		neigh_node = batadv_orig_router_get(orig_node,
245						    BATADV_IF_DEFAULT);
246		if (!neigh_node)
247			goto dst_unreach;
248
249		if (!neigh_node->if_incoming)
250			goto dst_unreach;
251
252		if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
253			goto dst_unreach;
254
255		icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header;
256		if (packet_len == sizeof(*icmp_packet_rr)) {
257			addr = neigh_node->if_incoming->net_dev->dev_addr;
258			ether_addr_copy(icmp_packet_rr->rr[0], addr);
259		}
260
261		break;
262	default:
263		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
264			   "Error - can't send packet from char device: got unknown message type\n");
265		len = -EINVAL;
266		goto free_skb;
267	}
268
269	icmp_header->uid = socket_client->index;
270
271	if (icmp_header->version != BATADV_COMPAT_VERSION) {
272		icmp_header->msg_type = BATADV_PARAMETER_PROBLEM;
273		icmp_header->version = BATADV_COMPAT_VERSION;
274		batadv_socket_add_packet(socket_client, icmp_header,
275					 packet_len);
276		goto free_skb;
277	}
278
279	ether_addr_copy(icmp_header->orig, primary_if->net_dev->dev_addr);
280
281	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
282	goto out;
283
284dst_unreach:
285	icmp_header->msg_type = BATADV_DESTINATION_UNREACHABLE;
286	batadv_socket_add_packet(socket_client, icmp_header, packet_len);
287free_skb:
288	kfree_skb(skb);
289out:
290	if (primary_if)
291		batadv_hardif_free_ref(primary_if);
292	if (neigh_node)
293		batadv_neigh_node_free_ref(neigh_node);
294	if (orig_node)
295		batadv_orig_node_free_ref(orig_node);
296	return len;
297}
298
299static unsigned int batadv_socket_poll(struct file *file, poll_table *wait)
300{
301	struct batadv_socket_client *socket_client = file->private_data;
302
303	poll_wait(file, &socket_client->queue_wait, wait);
304
305	if (socket_client->queue_len > 0)
306		return POLLIN | POLLRDNORM;
307
308	return 0;
309}
310
311static const struct file_operations batadv_fops = {
312	.owner = THIS_MODULE,
313	.open = batadv_socket_open,
314	.release = batadv_socket_release,
315	.read = batadv_socket_read,
316	.write = batadv_socket_write,
317	.poll = batadv_socket_poll,
318	.llseek = no_llseek,
319};
320
321int batadv_socket_setup(struct batadv_priv *bat_priv)
322{
323	struct dentry *d;
324
325	if (!bat_priv->debug_dir)
326		goto err;
327
328	d = debugfs_create_file(BATADV_ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
329				bat_priv->debug_dir, bat_priv, &batadv_fops);
330	if (!d)
331		goto err;
332
333	return 0;
334
335err:
336	return -ENOMEM;
337}
338
339/**
340 * batadv_socket_receive_packet - schedule an icmp packet to be sent to
341 *  userspace on an icmp socket.
342 * @socket_client: the socket this packet belongs to
343 * @icmph: pointer to the header of the icmp packet
344 * @icmp_len: total length of the icmp packet
345 */
346static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
347				     struct batadv_icmp_header *icmph,
348				     size_t icmp_len)
349{
350	struct batadv_socket_packet *socket_packet;
351	size_t len;
352
353	socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC);
354
355	if (!socket_packet)
356		return;
357
358	len = icmp_len;
359	/* check the maximum length before filling the buffer */
360	if (len > sizeof(socket_packet->icmp_packet))
361		len = sizeof(socket_packet->icmp_packet);
362
363	INIT_LIST_HEAD(&socket_packet->list);
364	memcpy(&socket_packet->icmp_packet, icmph, len);
365	socket_packet->icmp_len = len;
366
367	spin_lock_bh(&socket_client->lock);
368
369	/* while waiting for the lock the socket_client could have been
370	 * deleted
371	 */
372	if (!batadv_socket_client_hash[icmph->uid]) {
373		spin_unlock_bh(&socket_client->lock);
374		kfree(socket_packet);
375		return;
376	}
377
378	list_add_tail(&socket_packet->list, &socket_client->queue_list);
379	socket_client->queue_len++;
380
381	if (socket_client->queue_len > 100) {
382		socket_packet = list_first_entry(&socket_client->queue_list,
383						 struct batadv_socket_packet,
384						 list);
385
386		list_del(&socket_packet->list);
387		kfree(socket_packet);
388		socket_client->queue_len--;
389	}
390
391	spin_unlock_bh(&socket_client->lock);
392
393	wake_up(&socket_client->queue_wait);
394}
395
396/**
397 * batadv_socket_receive_packet - schedule an icmp packet to be received
398 *  locally and sent to userspace.
399 * @icmph: pointer to the header of the icmp packet
400 * @icmp_len: total length of the icmp packet
401 */
402void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
403				  size_t icmp_len)
404{
405	struct batadv_socket_client *hash;
406
407	hash = batadv_socket_client_hash[icmph->uid];
408	if (hash)
409		batadv_socket_add_packet(hash, icmph, icmp_len);
410}
411