00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <ctype.h>
00026
00027 #include "RoutingTableParser.h"
00028 #include "IPv4InterfaceData.h"
00029
00030
00031
00032
00033 const int MAX_FILESIZE = 10000;
00034 const int MAX_ENTRY_STRING_SIZE = 500;
00035
00036
00037
00038
00039 const char *IFCONFIG_START_TOKEN = "ifconfig:",
00040 *IFCONFIG_END_TOKEN = "ifconfigend.",
00041 *ROUTE_START_TOKEN = "route:",
00042 *ROUTE_END_TOKEN = "routeend.";
00043
00044 RoutingTableParser::RoutingTableParser(IInterfaceTable *i, IRoutingTable *r)
00045 {
00046 ift = i;
00047 rt = r;
00048 }
00049
00050
00051 int RoutingTableParser::streq(const char *str1, const char *str2)
00052 {
00053 return (strncmp(str1, str2, strlen(str2)) == 0);
00054 }
00055
00056
00057 int RoutingTableParser::strcpyword(char *dest, const char *src)
00058 {
00059 int i;
00060 for (i = 0; !isspace(dest[i] = src[i]); i++) ;
00061 dest[i] = '\0';
00062 return i;
00063 }
00064
00065
00066 void RoutingTableParser::skipBlanks(char *str, int &charptr)
00067 {
00068 for (;isspace(str[charptr]); charptr++) ;
00069 }
00070
00071
00072 int RoutingTableParser::readRoutingTableFromFile(const char *filename)
00073 {
00074 FILE *fp;
00075 int charpointer;
00076 char *file = new char[MAX_FILESIZE];
00077 char *ifconfigFile = NULL;
00078 char *routeFile = NULL;
00079
00080 fp = fopen(filename, "r");
00081 if (fp == NULL)
00082 opp_error("Error opening routing table file `%s'", filename);
00083
00084
00085 for (charpointer = 0;
00086 (file[charpointer] = getc(fp)) != EOF;
00087 charpointer++) ;
00088
00089 charpointer++;
00090 for (; charpointer < MAX_FILESIZE; charpointer++)
00091 file[charpointer] = '\0';
00092
00093
00094 fclose(fp);
00095
00096
00097
00098 for (charpointer = 0;
00099 (charpointer < MAX_FILESIZE) && (file[charpointer] != EOF);
00100 charpointer++) {
00101
00102 if (charpointer == 0 || file[charpointer - 1] == '\n') {
00103
00104 if (streq(file + charpointer, IFCONFIG_START_TOKEN)) {
00105 ifconfigFile = createFilteredFile(file,
00106 charpointer,
00107 IFCONFIG_END_TOKEN);
00108
00109 }
00110
00111
00112 if (streq(file + charpointer, ROUTE_START_TOKEN)) {
00113 routeFile = createFilteredFile(file,
00114 charpointer,
00115 ROUTE_END_TOKEN);
00116
00117 }
00118 }
00119 }
00120
00121 delete file;
00122
00123
00124 if (ifconfigFile)
00125 parseInterfaces(ifconfigFile);
00126 if (routeFile)
00127 parseRouting(routeFile);
00128
00129 delete ifconfigFile;
00130 delete routeFile;
00131
00132 return 0;
00133
00134 }
00135
00136 char *RoutingTableParser::createFilteredFile(char *file, int &charpointer, const char *endtoken)
00137 {
00138 int i = 0;
00139 char *filterFile = new char[MAX_FILESIZE];
00140 filterFile[0] = '\0';
00141
00142 while(true) {
00143
00144 while ( !isalnum(file[charpointer]) && !isspace(file[charpointer]) ) {
00145 while (file[charpointer++] != '\n') ;
00146 }
00147
00148
00149 if (streq(file + charpointer, endtoken)) {
00150 filterFile[i] = '\0';
00151 break;
00152 }
00153
00154
00155 while ((filterFile[i++] = file[charpointer++]) != '\n') ;
00156 }
00157
00158 return filterFile;
00159 }
00160
00161
00162 void RoutingTableParser::parseInterfaces(char *ifconfigFile)
00163 {
00164 char buf[MAX_ENTRY_STRING_SIZE];
00165 int charpointer = 0;
00166 InterfaceEntry *ie;
00167
00168
00169 while(ifconfigFile[charpointer] != '\0')
00170 {
00171
00172 if (streq(ifconfigFile + charpointer, "name:")) {
00173
00174 char *name = parseEntry(ifconfigFile, "name:", charpointer,buf);
00175 ie = ift->getInterfaceByName(name);
00176 if (!ie)
00177 opp_error("Error in routing file: interface name `%s' not registered by any L2 module", name);
00178 continue;
00179 }
00180
00181
00182 if (streq(ifconfigFile + charpointer, "encap:")) {
00183
00184 parseEntry(ifconfigFile, "encap:", charpointer, buf);
00185 continue;
00186 }
00187
00188
00189 if (streq(ifconfigFile + charpointer, "HWaddr:")) {
00190
00191 parseEntry(ifconfigFile, "HWaddr:", charpointer, buf);
00192 continue;
00193 }
00194
00195
00196 if (streq(ifconfigFile + charpointer, "inet_addr:")) {
00197 ie->ipv4Data()->setIPAddress(IPAddress(parseEntry(ifconfigFile, "inet_addr:", charpointer,buf)));
00198 continue;
00199 }
00200
00201
00202 if (streq(ifconfigFile + charpointer, "Bcast:")) {
00203
00204 parseEntry(ifconfigFile, "Bcast:", charpointer, buf);
00205 continue;
00206 }
00207
00208
00209 if (streq(ifconfigFile + charpointer, "Mask:")) {
00210 ie->ipv4Data()->setNetmask(IPAddress(parseEntry(ifconfigFile, "Mask:", charpointer,buf)));
00211 continue;
00212 }
00213
00214
00215 if (streq(ifconfigFile + charpointer, "Groups:")) {
00216 char *grStr = parseEntry(ifconfigFile, "Groups:", charpointer, buf);
00217 parseMulticastGroups(grStr, ie);
00218 continue;
00219 }
00220
00221
00222 if (streq(ifconfigFile + charpointer, "MTU:")) {
00223 ie->setMtu(atoi(parseEntry(ifconfigFile, "MTU:", charpointer,buf)));
00224 continue;
00225 }
00226
00227
00228 if (streq(ifconfigFile + charpointer, "Metric:")) {
00229 ie->ipv4Data()->setMetric(atoi(parseEntry(ifconfigFile, "Metric:", charpointer,buf)));
00230 continue;
00231 }
00232
00233
00234 if (streq(ifconfigFile + charpointer, "BROADCAST")) {
00235 ie->setBroadcast(true);
00236 charpointer += strlen("BROADCAST");
00237 skipBlanks(ifconfigFile, charpointer);
00238 continue;
00239 }
00240
00241
00242 if (streq(ifconfigFile + charpointer, "MULTICAST")) {
00243 ie->setMulticast(true);
00244 charpointer += strlen("MULTICAST");
00245 skipBlanks(ifconfigFile, charpointer);
00246 continue;
00247 }
00248
00249
00250 if (streq(ifconfigFile + charpointer, "POINTTOPOINT")) {
00251 ie->setPointToPoint(true);
00252 charpointer += strlen("POINTTOPOINT");
00253 skipBlanks(ifconfigFile, charpointer);
00254 continue;
00255 }
00256
00257
00258 charpointer++;
00259 }
00260 }
00261
00262
00263 char *RoutingTableParser::parseEntry(char *ifconfigFile, const char *tokenStr,
00264 int& charpointer, char *destStr)
00265 {
00266 int temp = 0;
00267
00268 charpointer += strlen(tokenStr);
00269 skipBlanks(ifconfigFile, charpointer);
00270 temp = strcpyword(destStr, ifconfigFile + charpointer);
00271 charpointer += temp;
00272
00273 skipBlanks(ifconfigFile, charpointer);
00274
00275 return destStr;
00276 }
00277
00278
00279 void RoutingTableParser::parseMulticastGroups(char *groupStr, InterfaceEntry *itf)
00280 {
00281 IPv4InterfaceData::IPAddressVector mcg = itf->ipv4Data()->getMulticastGroups();
00282
00283
00284 mcg.push_back(IPAddress::ALL_HOSTS_MCAST);
00285
00286
00287 if (rt->isIPForwardingEnabled())
00288 mcg.push_back(IPAddress::ALL_ROUTERS_MCAST);
00289
00290
00291 cStringTokenizer tokenizer(groupStr,":");
00292 const char *token;
00293 while ((token = tokenizer.nextToken())!=NULL)
00294 mcg.push_back(IPAddress(token));
00295
00296 itf->ipv4Data()->setMulticastGroups(mcg);
00297 }
00298
00299 void RoutingTableParser::parseRouting(char *routeFile)
00300 {
00301 char *str = new char[MAX_ENTRY_STRING_SIZE];
00302
00303 int pos = strlen(ROUTE_START_TOKEN);
00304 skipBlanks(routeFile, pos);
00305 while (routeFile[pos] != '\0')
00306 {
00307
00308 pos += strcpyword(str, routeFile + pos);
00309 skipBlanks(routeFile, pos);
00310 IPRoute *e = new IPRoute();
00311 if (strcmp(str, "default:"))
00312 {
00313
00314 if (!IPAddress::isWellFormed(str))
00315 opp_error("Syntax error in routing file: `%s' on 1st column should be `default:' or a valid IP address", str);
00316 e->setHost(IPAddress(str));
00317 }
00318
00319
00320 pos += strcpyword(str, routeFile + pos);
00321 skipBlanks(routeFile, pos);
00322 if (!strcmp(str, "*") || !strcmp(str, "0.0.0.0"))
00323 {
00324 e->setGateway(IPAddress::UNSPECIFIED_ADDRESS);
00325 }
00326 else
00327 {
00328 if (!IPAddress::isWellFormed(str))
00329 opp_error("Syntax error in routing file: `%s' on 2nd column should be `*' or a valid IP address", str);
00330 e->setGateway(IPAddress(str));
00331 }
00332
00333
00334 pos += strcpyword(str, routeFile + pos);
00335 skipBlanks(routeFile, pos);
00336 if (!IPAddress::isWellFormed(str))
00337 opp_error("Syntax error in routing file: `%s' on 3rd column should be a valid IP address", str);
00338 e->setNetmask(IPAddress(str));
00339
00340
00341 pos += strcpyword(str, routeFile + pos);
00342 skipBlanks(routeFile, pos);
00343
00344 for (int i = 0; str[i]; i++)
00345 {
00346 if (str[i] == 'H') {
00347 e->setType(IPRoute::DIRECT);
00348 } else if (str[i] == 'G') {
00349 e->setType(IPRoute::REMOTE);
00350 } else {
00351 opp_error("Syntax error in routing file: 4th column should be `G' or `H' not `%s'", str);
00352 }
00353 }
00354
00355
00356 pos += strcpyword(str, routeFile + pos);
00357 skipBlanks(routeFile, pos);
00358 int metric = atoi(str);
00359 if (metric==0 && str[0]!='0')
00360 opp_error("Syntax error in routing file: 5th column should be numeric not `%s'", str);
00361 e->setMetric(metric);
00362
00363
00364 opp_string interfaceName;
00365 interfaceName.reserve(MAX_ENTRY_STRING_SIZE);
00366 pos += strcpyword(interfaceName.buffer(), routeFile + pos);
00367 skipBlanks(routeFile, pos);
00368 InterfaceEntry *ie = ift->getInterfaceByName(interfaceName.c_str());
00369 if (!ie)
00370 opp_error("Syntax error in routing file: 6th column: `%s' is not an existing interface", interfaceName.c_str());
00371 e->setInterface(ie);
00372
00373
00374 rt->addRoute(e);
00375 }
00376 }
00377