1 /********************************************************************************
2 NDPMon - Neighbor Discovery Protocol Monitor
3 Copyright (C) 2006 MADYNES Project, LORIA - INRIA Lorraine (France)
4 
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9 
10 This library 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 GNU
13 Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 
19 Author Info:
20   Name: Thibault Cholez
21   Mail: thibault.cholez@esial.uhp-nancy.fr
22 
23 Maintainer:
24   Name: Frederic Beck
25   Mail: frederic.beck@loria.fr
26 
27 MADYNES Project, LORIA-INRIA Lorraine, hereby disclaims all copyright interest in
28 the tool 'NDPMon' (Neighbor Discovery Protocol Monitor) written by Thibault Cholez.
29 
30 Olivier Festor, Scientific Leader of the MADYNEs Project, 20 August 2006
31 ***********************************************************************************/
32 
33 
34 #include "membounds.h"
35 #include "monitoring_na.h"
36 
37 
38 /*Test if the NA enable the router flag and if true
39  *test if this neighbor is an official router
40  */
watch_R_flag(char * message,struct ether_header * eptr,struct ip6_hdr * ipptr,struct nd_neighbor_advert * naptr)41 int watch_R_flag(char* message, struct ether_header* eptr, struct ip6_hdr* ipptr, struct nd_neighbor_advert* naptr)
42 {
43 
44 	/*Mask is used to select the R_FLAG from the NA*/
45 	int R_FLAG = (naptr->nd_na_flags_reserved)&ND_NA_FLAG_ROUTER;
46 	int ret = 0;
47 
48 	if(DEBUG)
49 		printf("NA flag router: %d\n", R_FLAG);
50 
51 	if (R_FLAG)
52 	{
53 
54 		char ip_address[IP6_STR_SIZE];
55 		char* mac_address = NULL;
56 		struct ether_addr *src_eth = (struct ether_addr *)eptr->ether_shost;
57 
58 		int found_mac = is_router_mac_in(routers, *src_eth);
59 		int found_lla = is_router_lla_in(routers, ipptr->ip6_src);
60 
61 		mac_address= (char*)ether_ntoa((struct ether_addr*) (eptr->ether_shost));
62 		ipv6_ntoa(ip_address, ipptr->ip6_src);
63 
64 		if(!found_mac)
65 		{
66 			snprintf (message, NOTIFY_BUFFER_SIZE, "NA router flag %s %s", mac_address, ip_address);
67 			notify(2,message, "NA router flag", (struct ether_addr*) (eptr->ether_shost), ip_address, NULL);
68 			return 2;
69 		}
70 		else
71 		{
72 			if(!found_lla)
73 			{
74 				int found_ip = router_has_address(routers, *src_eth, ipptr->ip6_src);
75 
76 				if( !found_ip)
77 				{
78 					snprintf (message, NOTIFY_BUFFER_SIZE, "NA router flag %s %s", mac_address, ip_address);
79 					notify(2,message, "NA router flag", (struct ether_addr*) (eptr->ether_shost), ip_address, NULL);
80 					return 2;
81 				}
82 			}
83 		}
84 	}
85 
86 	return ret;
87 
88 }
89 
90 
91 
92 /*Test if the NA is doing Duplicate Address Detection DOS
93   Detect if a host is responding a wrong IPv6 not corresponding to its mac addr
94  */
watch_dad_dos(char * message,struct ether_header * eptr,struct ip6_hdr * ipptr,struct nd_neighbor_advert * naptr,int new_eth)95 int watch_dad_dos(char* message, struct ether_header* eptr, struct ip6_hdr* ipptr, struct nd_neighbor_advert* naptr, int new_eth)
96 {
97 	neighbor_list_t *tmp = neighbors;
98 	struct in6_addr wanted_addr = *get_last_dad_addr();
99 	char buffer[255];
100 
101 	ipv6_ntoa(buffer, wanted_addr);
102 
103 	if(IN6_ARE_ADDR_EQUAL(&naptr->nd_na_target, &wanted_addr))
104 	{
105 		/* NA against the last NS for DAD :-/ */
106 		/* Is this response true ? */
107 		int find_mac = -1;
108 		int dos = 0;
109 
110 		/*If DOS is done by a station never seen before this NA, it should be an attack*/
111 		if(new_eth)
112 		{
113 			fprintf(stderr,"New Ethernet DAD DoS\n");
114 			dos=1;
115 		}
116 		else
117 		{
118 			/*Is the mac addr in the neighbor list ?*/
119 			while(tmp != NULL)
120 			{
121 				if (MEMCMP(&(tmp->mac),(struct ether_addr*)eptr->ether_shost,6) == 0)
122 				{
123 					find_mac = 1;
124 					break;
125 				}
126 				tmp = tmp->next;
127 			}
128 
129 			if(find_mac == 1)
130 			{
131 				struct ether_addr * src_eth = (struct ether_addr*)eptr->ether_shost;
132 
133 				if( !IN6_ARE_ADDR_EQUAL(&naptr->nd_na_target,&(tmp->lla)))
134 				{
135 					char toto[INET6_ADDRSTRLEN];
136 					char ip_address[40];
137 					ipv6_ntoa(ip_address, ipptr->ip6_src);
138 					ipv6_ntoa(toto,(tmp->lla));
139 					if (!neighbor_has_ip(neighbors, *src_eth, naptr->nd_na_target))
140 					{
141 						dos = 1;
142 					}
143 				}
144 			}
145 		}
146 
147 		if(dos)
148 		{
149 			char ip_address[40];
150 			ipv6_ntoa(ip_address, ipptr->ip6_src);
151 			snprintf (message, NOTIFY_BUFFER_SIZE, "dad dos %s %s", (char*)ether_ntoa((struct ether_addr*) (eptr->ether_shost)), ip_address);
152 			notify(2,message, "dad dos", (struct ether_addr*) (eptr->ether_shost), ip_address, NULL);
153 			return 2;
154 		}
155 		else
156 			return 0;
157 	}
158 	else
159 		return 0;
160 }
161