Added version to server
[tunnel6.git] / server / src / ndp.c
blob33328fe7543a0904d8d99d593ac0e42efa3f96eb
1 /*
2 * tunnel6
3 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <stdio.h>
21 #include <string.h>
22 #include "db.h"
23 #include "ndp.h"
24 #include "ipv6.h"
25 #include "sniff.h"
26 #include "packet.h"
27 #include "checksum.h"
29 extern struct netdev_t netdev;
31 /* send neighbour advertisement - we lie about existing address :-B */
32 int ndp_reply (struct proto_eth_t *eth, char *data)
34 struct proto_ipv6_t *ip = (struct proto_ipv6_t *) data;
35 struct proto_ndp_t *ndp = (struct proto_ndp_t *) ((char *) data + sizeof (struct proto_ipv6_t));
37 /* check for neighbour solicitation packet */
38 if (ndp->type != NDP_TYPE_NBSOL)
39 return -1;
41 /* check target with database */
42 client_t *c = db_check (ndp->target);
44 if (!c)
45 return 0;
47 if (!c->info)
48 return 0;
50 /* build a new packet */
51 char packet[sizeof (struct proto_eth_t) + sizeof (struct proto_ipv6_t) + sizeof (struct proto_ndp_t) + 1];
53 /* ethernet layer */
54 struct proto_eth_t *packet_eth = (struct proto_eth_t *) &packet;
56 memcpy (&packet_eth->src, netdev.hwaddr, sizeof (mac_addr_t));
57 memcpy (&packet_eth->dest, eth->src, sizeof (mac_addr_t));
58 packet_eth->type = PACKET_TYPE_IPV6;
60 /* IPv6 layer */
61 struct proto_ipv6_t *packet_ip = (struct proto_ipv6_t *) ((char *) &packet + sizeof (struct proto_eth_t));
63 packet_ip->ver = 0x60;
64 packet_ip->tclass = 0x0;
65 packet_ip->flabel = 0x0;
66 packet_ip->pl_len = htons (32);
67 packet_ip->nhead = IPV6_TYPE_ICMPv6;
68 packet_ip->hop = 0xff;
69 memcpy (packet_ip->src, (void *) ndp->target, sizeof (ipv6_addr_t));
70 memcpy (packet_ip->dest, (void *) ip->src, sizeof (ipv6_addr_t));
72 /* ICMPv6 - NDP layer */
73 struct proto_ndp_t *packet_ndp = (struct proto_ndp_t *) ((char *) &packet + sizeof (struct proto_eth_t) + sizeof (struct proto_ipv6_t));
75 packet_ndp->type = NDP_TYPE_NBADV;
76 packet_ndp->code = 0;
77 packet_ndp->flags = htonl (0x60000000);
78 memcpy (packet_ndp->target, (void *) ndp->target, sizeof (ipv6_addr_t));
80 packet_ndp->ll_type = 2;
81 packet_ndp->ll_length = 1;
82 memcpy (&packet_ndp->ll_mac, netdev.hwaddr, sizeof (mac_addr_t));
83 packet_ndp->checksum = 0x0;
85 /* calculate checksum */
86 packet_ndp->checksum = checksum16_ipv6 (packet_ip->src, packet_ip->dest, (char *) packet_ndp, sizeof (struct proto_ndp_t), IPV6_TYPE_ICMPv6);
88 /* send RAW packet */
89 return sniff_send (packet, sizeof (struct proto_eth_t) + sizeof (struct proto_ipv6_t) + sizeof (struct proto_ndp_t));
92 int ndp_init ()
95 return 0;