]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/rscript/nrmap_parser.cpp
254a3da683b2dfd279a55262b9e49facb543fd00
[stg.git] / projects / stargazer / plugins / other / rscript / nrmap_parser.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21  /*
22  $Revision: 1.8 $
23  $Author: faust $
24  $Date: 2009/10/22 09:58:53 $
25  */
26
27 #include <fstream>
28 #include <cerrno>
29 #include <cstring>
30 #include <algorithm>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <arpa/inet.h>
34
35 #include "stg/common.h"
36 #include "nrmap_parser.h"
37
38 NRMapParser::NRMapParser()
39 {
40 }
41
42 NRMapParser::~NRMapParser()
43 {
44 }
45
46 bool NRMapParser::ReadFile(const std::string & fileName)
47 {
48 std::ifstream source(fileName.c_str());
49
50 if (!source)
51     {
52     errorStr = "Error opening file ";
53     errorStr += fileName;
54     printfd(__FILE__, "NRMapParser::ReadFile(): %s\n", errorStr.c_str());
55     return true;
56     }
57
58 int lineNumber = 0;
59 std::string line;
60 std::vector<NET_ROUTER> _nrmap;
61
62 while (getline(source, line))
63     {
64     ++lineNumber;
65     NET_ROUTER nr;
66
67     if (Trim(line) == "")
68         {
69         continue;
70         }
71
72     if (ParseLine(line, nr))
73         {
74         printfd(__FILE__, "NRMapParser::ReadFile(): Error parsing line %d: '%s'\n", lineNumber, errorStr.c_str());
75         return true;
76         }
77
78     _nrmap.push_back(nr);
79     }
80
81 nrmap = _nrmap;
82
83 return false;
84 }
85
86 bool NRMapParser::ParseLine(const std::string & line, NET_ROUTER & nr) const
87 {
88 // xxx.xxx.xxx.xxx/yy zzz.zzz.zzz.zzz
89 size_t pos = line.find_first_of(" \t");
90
91 if (pos == std::string::npos)
92     {
93     errorStr = "No space between subnet and router";
94     return true;
95     }
96
97 std::string subnet(line.substr(0, pos)); // xxx.xxx.xxx.xxx/yy
98
99 uint32_t ip = 0;
100 uint32_t mask = 0;
101
102 if (ParseNet(subnet, ip, mask))
103     {
104     return true;
105     }
106
107 nr.subnetIP = ip;
108 nr.subnetMask = mask;
109
110 pos = line.find_first_not_of(" \t", pos);
111
112 if (pos == std::string::npos)
113     {
114     errorStr = "No router address found";
115     return true;
116     }
117
118 size_t pos2 = line.find_first_of(" \t", pos);
119
120 std::string router(line.substr(pos, pos2 == std::string::npos ? line.length() - pos2 - 1 : pos2 - pos)); //zzz.zzz.zzz.zzz
121
122 uint32_t routerIP;
123
124 if (ParseRouter(router, routerIP))
125     {
126     return true;
127     }
128
129 std::vector<uint32_t>::iterator it;
130
131 it = std::lower_bound(
132         nr.routers.begin(),
133         nr.routers.end(),
134         routerIP
135         );
136 nr.routers.insert(it, routerIP);
137
138 //nr.routers.push_back(routerIP);
139
140 while (pos2 != std::string::npos)
141     {
142     pos = line.find_first_not_of(" \t", pos2);
143
144     if (pos == std::string::npos)
145         {
146         return false;
147         }
148
149     pos2 = line.find_first_of(" \t", pos);
150
151     if (ParseRouter(line.substr(
152                         pos,
153                         pos2 == std::string::npos ? line.length() - pos2 - 1 : pos2 - pos),
154                     routerIP))
155         {
156         return true;
157         }
158
159     it = std::lower_bound(
160             nr.routers.begin(),
161             nr.routers.end(),
162             routerIP
163             );
164     nr.routers.insert(it, routerIP);
165
166     //nr.routers.push_back(routerIP);
167
168     }
169
170 return false;
171 }
172
173 bool NRMapParser::ParseNet(const std::string & line, uint32_t & ip, uint32_t & mask) const
174 {
175 // xxx.xxx.xxx.xxx/yy
176
177 size_t pos = line.find_first_of('/');
178
179 if (pos == std::string::npos)
180     {
181     errorStr = "Subnet is not in CIDR notation";
182     return true;
183     }
184
185 int res = inet_pton(AF_INET, line.substr(0, pos).c_str(), &ip); //xxx.xxx.xxx.xxx
186
187 if (res < 0)
188     {
189     errorStr = strerror(errno);
190     return true;
191     }
192 else if (res == 0)
193     {
194     errorStr = "Invalid subnet address";
195     return true;
196     }
197
198 if (str2x(line.substr(pos + 1, line.length() - pos - 1), mask)) //yy
199     {
200     errorStr = "Invalid subnet mask";
201     return true;
202     }
203 if (mask > 32)
204     {
205     errorStr = "Subnet mask is out of range [0..32]";
206     return true;
207     }
208 mask = htonl(0xffFFffFF << (32 - mask)); //bitmask
209
210 return false;
211 }
212
213 bool NRMapParser::ParseRouter(const std::string & line, uint32_t & ip) const
214 {
215 int res = inet_pton(AF_INET, line.c_str(), &ip); //zzz.zzz.zzz.zzz
216
217 if (res < 0)
218     {
219     errorStr = strerror(errno);
220     return true;
221     }
222 else if (res == 0)
223     {
224     printfd(__FILE__, "NRMapParser::ParseRouter(): IP '%s' is invalid\n", line.c_str());
225     errorStr = "Invalid router address";
226     return true;
227     }
228 return false;
229 }