1 /**************************************************
2 OpengateM - a MAC address authentication system
3 module for checking ttl (or hlim in v6) to detect router
5 Copyright (C) 2011 Opengate Project Team
6 Written by Yoshiaki Watanabe
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
24 #include "opengatemd.h"
27 unsigned long subnetBits;
32 static char validInitialTtl[256];
33 static struct SubnetSet* pSubnet;
36 /**********************************
37 initialize ttl check routine
38 **********************************/
39 int initTtlCheck(void){
45 struct SubnetSet* pNext;
46 unsigned long subnetBits;
52 /***** ttl table setting ******/
53 /* initial values of table is false */
54 for(i=0; i<256; i++) validInitialTtl[i] = FALSE;
56 /* get string for initial ttls from conf file, eg:[64 128 255] */
57 pStart = GetConfValue("ValidInitialTtl");
58 if(isNull(pStart)) return FALSE;
60 /* loop for setting ttl table */
63 /* get number and set table entry */
64 if(sscanf(pStart, "%d", &ttlValue)==1){
65 validInitialTtl[ttlValue]=TRUE;
68 /* set next scan point */
69 pStart = strchr(pStart+1, ' ');
70 if(isNull(pStart)) break;
73 /******** subnet setting ***********/
74 /* count subnet setting */
76 subnetStr=GetFirstConfValue("SubnetHopCount");
77 while(!isNull(subnetStr)){
79 subnetStr=GetNextConfValue();
82 /* get memory for the setting */
83 pSubnet=malloc(sizeof(struct SubnetSet)*(nSubnet));
86 /*loop all subnet setting */
87 subnetStr=GetFirstConfValue("SubnetHopCount");
88 while(!isNull(subnetStr)){
90 /* get address and hop count defined as [192.168.1.0/24 1] */
91 if(sscanf(subnetStr, "%d.%d.%d.%d/%d %d",
92 &byte[0], &byte[1], &byte[2], &byte[3],
93 &maskLength, &hopCount)==6){
95 /* sum up address bytes to a long int */
98 subnetBits = subnetBits<<8;
99 subnetBits += byte[i];
102 /* save subnet setting to malloc area */
103 pNext->subnetBits=subnetBits;
104 if(maskLength<=32) pNext->maskLength=maskLength;
105 else pNext->maskLength=0;
106 pNext->hopCount=hopCount;
108 /* goto next store area */
112 /* get next subnet setting */
113 subnetStr=GetNextConfValue();
119 /*********************************
120 check ttl for detecting access via nat/router
121 *********************************/
122 int isSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl){
124 unsigned int byte[4]; /* 4 bytes representing given ipv4 address */
125 unsigned long addressBits=0;
126 unsigned long subnetMask=0;
129 struct SubnetSet* pNext;
132 /* if ttl is valid initial ttl then no router/nat */
133 if( validInitialTtl[ttl] ) return 0; /* no router/nat */
135 /* if ipv6, the nat/router is assumed as a router */
136 if( strchr(ipAddress, ':')!=NULL){
137 if( validInitialTtl[ttl] ) return 0; /* direct (no router/nat) */
138 else return 2; /* router */
141 /* if ipv4, calculate initial ttl as (present ttl)+(router hops) */
142 /* and compare to the router hop setting in conf file */
143 /* get 4 bytes of ipv4 address */
144 if(sscanf(ipAddress, "%d.%d.%d.%d",
145 &byte[0], &byte[1], &byte[2], &byte[3])!=4) return -1;/*error */
147 /* sum up address bytes to a long int */
150 addressBits = addressBits<<8;
151 addressBits += byte[i];
154 /* check each subnet setting */
158 for(i=0; i<nSubnet; i++){
160 /* compare subnet and address */
161 /* subnetBits 1011 0011 1100 0011 0000 */
162 /* addressBits 1011 0011 0110 0011 1100 */
163 /* Bit XOR 0000 0000 1010 0000 1100 */
164 /* subnet mask 1111 1111 1111 1111 0000 */
165 /* Bit AND 0000 0000 1010 0000 0000 */
166 /* If result is all-zero, the address is in the subnet */
167 subnetMask=0xFFFFFFFF<<(32 - (pNext->maskLength));
168 if(!( ((pNext->subnetBits)^addressBits) & subnetMask )){
170 /* if the address is included in subnet having longest mask */
171 /* save the hop count */
172 if((pNext->maskLength) > maxMaskLength){
173 maxMaskLength = pNext->maskLength;
174 hopSave = pNext->hopCount;
178 /* get next SubnetHopCount */
182 /* add hop to ttl, then compare to valid initial ttl */
183 if( hopSave<0 || (ttl+hopSave)>=256 ) return ERROR; /* error */
184 if( validInitialTtl[ttl+hopSave] ){
185 if(hopSave==0) return NONAT; /* no nat/router */
186 else return ROUTER; /* valid router */
188 return NAT; /* unknown nat or router inserted */
191 /***********************************************
192 putout log at nat/router detection
193 isNatOrRouter:1=UnknownNatOrRouter, 2=FormalRouterOnly, 0=None, -1=err
194 **********************************************/
195 void putLogAtNatOrRouter(int isNatOrRouter, char* ipAddress, char* macAddress, int ttl){
197 if(isNatOrRouter==1 && atoi(GetConfValue("ShowNat"))){
198 err_msg("INFO : packet is sent via unknown nat/router[%s][%s][%d]",
199 ipAddress, macAddress, ttl);
201 if(isNatOrRouter==2 && atoi(GetConfValue("ShowRouter"))){
202 err_msg("INFO : packet is sent via formal router[%s][%s][%d]",
203 ipAddress, macAddress, ttl);
207 /***********************************************
208 routines for debugging output
209 **********************************************/
210 int InitTtlCheck(void){
212 if(debug>1) err_msg("DEBUG:=>initTtlCheck( )");
213 ret = initTtlCheck();
214 if(debug>1) err_msg("DEBUG:(%d)<=initTtlCheck( )",ret);
218 int IsSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl){
220 if(debug>2) err_msg("DEBUG:=>isSentViaNatOrRouter(%s,%s,%d)", ipAddress, macAddress, ttl);
221 ret = isSentViaNatOrRouter(ipAddress, macAddress, ttl);
222 if(debug>2) err_msg("DEBUG:(%d)<=isSentViaNatOrRouter( )", ret);
226 void PutLogAtNatOrRouter(int isNatOrRouter, char* ipAddress, char* macAddress, int ttl){
227 if(debug>2) err_msg("DEBUG:=>putLogAtNatOrRouter(%d,%s,%s,%d)",
228 isNatOrRouter,ipAddress,macAddress,ttl);
229 putLogAtNatOrRouter(isNatOrRouter,ipAddress,macAddress,ttl);
230 if(debug>2) err_msg("DEBUG:(%d)<=putLOgAtNatOrRouter( )");
235 /**************test main********************
239 ******************************************/