OSDN Git Service

Fixed link error
[opengatem/opengatem.git] / mdsrc / ttlcheck.c
1 /**************************************************
2 OpengateM - a MAC address authentication system
3  module for checking TTL(TimeToLive) (or hlim in ipv6) to detect router
4  defaut TTL has some fixed value (depending OS).
5  and it is decrement at passing the router/NAT.
6
7 Copyright (C) 2011 Opengate Project Team
8 Written by Yoshiaki Watanabe
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23
24 Email: watanaby@is.saga-u.ac.jp
25 **************************************************/
26 #include "opengatemd.h"
27
28 struct SubnetSet{
29   unsigned long subnetBits;
30   int maskLength;
31   int hopCount;
32 };
33
34 static char validInitialTtl[256];
35 static struct SubnetSet* pSubnet;
36 static int nSubnet;
37
38 /**********************************
39 initialize ttl check routine
40 **********************************/
41 int initTtlCheck(void){
42
43   char* pStart;
44   int ttlValue;
45   int i;
46   char* subnetStr=NULL;
47   struct SubnetSet* pNext;
48   unsigned long subnetBits;
49   unsigned int byte[4];
50   int maskLength=0;
51   int hopCount=0;
52
53
54   /***** ttl table setting ******/
55   /* initial values of table is false */
56   for(i=0; i<256; i++) validInitialTtl[i] = FALSE;
57
58   /* get string for initial ttls from conf file, eg:[64 128 255] */
59   pStart = GetConfValue("ValidInitialTtl");
60   if(isNull(pStart)) return FALSE;
61   
62   /* loop for setting ttl table */
63   while(1){
64
65     /* get number and set table entry */
66     if(sscanf(pStart, "%d", &ttlValue)==1){
67       validInitialTtl[ttlValue]=TRUE;
68     }
69
70     /* set next scan point */
71     pStart = strchr(pStart+1, ' ');
72     if(isNull(pStart)) break;
73   }
74
75   /******** subnet setting ***********/
76   /* count subnet setting */
77   nSubnet=0;
78   subnetStr=GetFirstConfValue("SubnetHopCount");
79   while(!isNull(subnetStr)){
80     nSubnet++;
81     subnetStr=GetNextConfValue();
82   }
83
84   /* get memory for the setting */
85   pSubnet=malloc(sizeof(struct SubnetSet)*(nSubnet));
86   pNext=pSubnet;
87   
88   /*loop all subnet setting */
89   subnetStr=GetFirstConfValue("SubnetHopCount");
90   while(!isNull(subnetStr)){
91
92     /* get address and hop count defined as [192.168.1.0/24 1] */
93     if(sscanf(subnetStr, "%d.%d.%d.%d/%d %d", 
94               &byte[0], &byte[1], &byte[2], &byte[3], 
95               &maskLength, &hopCount)==6){
96
97       /* sum up address bytes to a long int */
98       subnetBits=0;
99       for(i=0; i<4; i++){
100         subnetBits = subnetBits<<8;
101         subnetBits += byte[i];
102       }
103       
104       /* save subnet setting to malloc area */
105       pNext->subnetBits=subnetBits;
106       if(maskLength<=32) pNext->maskLength=maskLength;
107       else               pNext->maskLength=0;
108       pNext->hopCount=hopCount;
109
110       /* goto next store area */
111       pNext++;
112     }
113
114     /* get next subnet setting */
115     subnetStr=GetNextConfValue();
116   }
117
118   return TRUE;
119 }
120
121 /*********************************
122 check ttl for detecting access via nat/router
123 *********************************/
124 int isSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl){
125
126   unsigned int byte[4]; /* 4 bytes representing given ipv4 address */
127   unsigned long addressBits=0;
128   unsigned long subnetMask=0;
129   int maxMaskLength=0;
130   int hopSave=0;
131   struct SubnetSet* pNext;
132   int i;
133
134   /* if ttl is valid initial ttl then no router/nat */
135   if( validInitialTtl[ttl] ) return 0; /* no router/nat */
136
137   /* if ipv6, the nat/router is assumed as a router */
138   if( strchr(ipAddress, ':')!=NULL){
139     if( validInitialTtl[ttl] ) return 0; /* direct (no router/nat) */
140     else return 2; /* router */ 
141   }
142
143   /* if ipv4, calculate initial ttl as (present ttl)+(router hops) */
144   /* and compare to the router hop setting in conf file */
145   /* get 4 bytes of ipv4 address */
146   if(sscanf(ipAddress, "%d.%d.%d.%d", 
147             &byte[0], &byte[1], &byte[2], &byte[3])!=4) return -1;/*error */
148
149   /* sum up address bytes to a long int */
150   addressBits=0;
151   for(i=0; i<4; i++){
152     addressBits = addressBits<<8;
153     addressBits += byte[i];
154   }
155
156   /* check each subnet setting */
157   pNext=pSubnet;
158   maxMaskLength=0;
159   hopSave=0;
160   for(i=0; i<nSubnet; i++){
161
162     /* compare subnet and address */
163     /*  subnetBits  1011 0011 1100 0011 0000 */
164     /*  addressBits 1011 0011 0110 0011 1100 */
165     /*    Bit XOR   0000 0000 1010 0000 1100 */ 
166     /*  subnet mask 1111 1111 1111 1111 0000 */
167     /*    Bit AND   0000 0000 1010 0000 0000 */
168     /* If result is all-zero, the address is in the subnet */
169     subnetMask=0xFFFFFFFF<<(32 - (pNext->maskLength));
170     if(!( ((pNext->subnetBits)^addressBits) & subnetMask )){
171
172       /* if the address is included in subnet having longest mask */
173       /* save the hop count */
174       if((pNext->maskLength) > maxMaskLength){
175         maxMaskLength = pNext->maskLength;
176         hopSave = pNext->hopCount;
177       }
178     }
179
180     /* get next SubnetHopCount */
181     pNext++;
182   }
183   
184   /* add hop to ttl, then compare to valid initial ttl */
185   if( hopSave<0 || (ttl+hopSave)>=256 ) return ERROR; /* error */
186   if( validInitialTtl[ttl+hopSave] ){
187     if(hopSave==0) return NONAT; /* no nat/router */
188     else  return ROUTER; /* valid router */
189   }
190   return NAT; /* unknown nat or router inserted */
191 }
192
193 /***********************************************
194  putout log at nat/router detection 
195  isNatOrRouter:1=UnknownNatOrRouter, 2=FormalRouterOnly, 0=None, -1=err
196 **********************************************/
197 void putLogAtNatOrRouter(int isNatOrRouter, char* ipAddress, char* macAddress, int ttl){
198
199   if(isNatOrRouter==1 && atoi(GetConfValue("ShowNat"))){
200     err_msg("INFO : packet is sent via unknown nat/router[%s][%s][%d]", 
201             ipAddress, macAddress, ttl);
202   }
203   if(isNatOrRouter==2 && atoi(GetConfValue("ShowRouter"))){
204     err_msg("INFO : packet is sent via formal router[%s][%s][%d]", 
205             ipAddress, macAddress, ttl);
206   }
207 }
208
209 /***********************************************
210  routines for debugging output 
211 **********************************************/
212 int InitTtlCheck(void){
213   int ret;
214   if(debug>1) err_msg("DEBUG:=>initTtlCheck( )");
215   ret = initTtlCheck();
216   if(debug>1) err_msg("DEBUG:(%d)<=initTtlCheck( )",ret);
217   return ret;
218 }
219
220 int IsSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl){
221   int ret;
222   if(debug>2) err_msg("DEBUG:=>isSentViaNatOrRouter(%s,%s,%d)", ipAddress, macAddress, ttl);
223   ret = isSentViaNatOrRouter(ipAddress, macAddress, ttl);
224   if(debug>2) err_msg("DEBUG:(%d)<=isSentViaNatOrRouter( )", ret);
225   return ret;
226 }
227
228 void PutLogAtNatOrRouter(int isNatOrRouter, char* ipAddress, char* macAddress, int ttl){
229   if(debug>2) err_msg("DEBUG:=>putLogAtNatOrRouter(%d,%s,%s,%d)", 
230                       isNatOrRouter,ipAddress,macAddress,ttl);
231   putLogAtNatOrRouter(isNatOrRouter,ipAddress,macAddress,ttl);
232   if(debug>2) err_msg("DEBUG:(%d)<=putLOgAtNatOrRouter( )");
233 }
234
235
236
237 /**************test main********************
238 int testmain(){
239
240 }
241 ******************************************/