OSDN Git Service

Ver.0.8.1
[opengatem/opengatem.git] / mdsrc / ttlcheck.c
1 /**************************************************
2 OpengateM - a MAC address authentication system
3  module for checking ttl (or hlim in v6) to detect router
4
5 Copyright (C) 2011 Opengate Project Team
6 Written by Yoshiaki Watanabe
7
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.
12
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.
17
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.
21
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
24 #include "opengatemd.h"
25
26 struct SubnetSet{
27   unsigned long subnetBits;
28   int maskLength;
29   int hopCount;
30 };
31
32 static char validInitialTtl[256];
33 static struct SubnetSet* pSubnet;
34 static int nSubnet;
35
36 /**********************************
37 initialize ttl check routine
38 **********************************/
39 int initTtlCheck(void){
40
41   char* pStart;
42   int ttlValue;
43   int i;
44   char* subnetStr=NULL;
45   struct SubnetSet* pNext;
46   unsigned long subnetBits;
47   unsigned int byte[4];
48   int maskLength=0;
49   int hopCount=0;
50
51
52   /***** ttl table setting ******/
53   /* initial values of table is false */
54   for(i=0; i<256; i++) validInitialTtl[i] = FALSE;
55
56   /* get string for initial ttls from conf file, eg:[64 128 255] */
57   pStart = GetConfValue("ValidInitialTtl");
58   if(isNull(pStart)) return FALSE;
59   
60   /* loop for setting ttl table */
61   while(1){
62
63     /* get number and set table entry */
64     if(sscanf(pStart, "%d", &ttlValue)==1){
65       validInitialTtl[ttlValue]=TRUE;
66     }
67
68     /* set next scan point */
69     pStart = strchr(pStart+1, ' ');
70     if(isNull(pStart)) break;
71   }
72
73   /******** subnet setting ***********/
74   /* count subnet setting */
75   nSubnet=0;
76   subnetStr=GetFirstConfValue("SubnetHopCount");
77   while(!isNull(subnetStr)){
78     nSubnet++;
79     subnetStr=GetNextConfValue();
80   }
81
82   /* get memory for the setting */
83   pSubnet=malloc(sizeof(struct SubnetSet)*(nSubnet));
84   pNext=pSubnet;
85   
86   /*loop all subnet setting */
87   subnetStr=GetFirstConfValue("SubnetHopCount");
88   while(!isNull(subnetStr)){
89
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){
94
95       /* sum up address bytes to a long int */
96       subnetBits=0;
97       for(i=0; i<4; i++){
98         subnetBits = subnetBits<<8;
99         subnetBits += byte[i];
100       }
101       
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;
107
108       /* goto next store area */
109       pNext++;
110     }
111
112     /* get next subnet setting */
113     subnetStr=GetNextConfValue();
114   }
115
116   return TRUE;
117 }
118
119 /*********************************
120 check ttl for detecting access via nat/router
121 *********************************/
122 int isSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl){
123
124   unsigned int byte[4]; /* 4 bytes representing given ipv4 address */
125   unsigned long addressBits=0;
126   unsigned long subnetMask=0;
127   int maxMaskLength=0;
128   int hopSave=0;
129   struct SubnetSet* pNext;
130   int i;
131
132   /* if ttl is valid initial ttl then no router/nat */
133   if( validInitialTtl[ttl] ) return 0; /* no router/nat */
134
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 */ 
139   }
140
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 */
146
147   /* sum up address bytes to a long int */
148   addressBits=0;
149   for(i=0; i<4; i++){
150     addressBits = addressBits<<8;
151     addressBits += byte[i];
152   }
153
154   /* check each subnet setting */
155   pNext=pSubnet;
156   maxMaskLength=0;
157   hopSave=0;
158   for(i=0; i<nSubnet; i++){
159
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 )){
169
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;
175       }
176     }
177
178     /* get next SubnetHopCount */
179     pNext++;
180   }
181   
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 */
187   }
188   return NAT; /* unknown nat or router inserted */
189 }
190
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){
196
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);
200   }
201   if(isNatOrRouter==2 && atoi(GetConfValue("ShowRouter"))){
202     err_msg("INFO : packet is sent via formal router[%s][%s][%d]", 
203             ipAddress, macAddress, ttl);
204   }
205 }
206
207 /***********************************************
208  routines for debugging output 
209 **********************************************/
210 int InitTtlCheck(void){
211   int ret;
212   if(debug>1) err_msg("DEBUG:=>initTtlCheck( )");
213   ret = initTtlCheck();
214   if(debug>1) err_msg("DEBUG:(%d)<=initTtlCheck( )",ret);
215   return ret;
216 }
217
218 int IsSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl){
219   int ret;
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);
223   return ret;
224 }
225
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( )");
231 }
232
233
234
235 /**************test main********************
236 int testmain(){
237
238 }
239 ******************************************/