]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/rscript/nrmap_parser.cpp
Fix libs order (for --as-needed)
[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 bool NRMapParser::ReadFile(const std::string & fileName)
39 {
40 std::ifstream source(fileName.c_str());
41
42 if (!source)
43     {
44     errorStr = "Error opening file ";
45     errorStr += fileName;
46     printfd(__FILE__, "NRMapParser::ReadFile(): %s\n", errorStr.c_str());
47     return true;
48     }
49
50 int lineNumber = 0;
51 std::string line;
52 std::vector<NET_ROUTER> _nrmap;
53
54 while (getline(source, line))
55     {
56     ++lineNumber;
57     NET_ROUTER nr;
58
59     if (Trim(line) == "")
60         {
61         continue;
62         }
63
64     if (ParseLine(line, nr))
65         {
66         printfd(__FILE__, "NRMapParser::ReadFile(): Error parsing line %d: '%s'\n", lineNumber, errorStr.c_str());
67         return true;
68         }
69
70     _nrmap.push_back(nr);
71     }
72
73 nrmap = _nrmap;
74
75 return false;
76 }
77
78 bool NRMapParser::ParseLine(const std::string & line, NET_ROUTER & nr) const
79 {
80 // xxx.xxx.xxx.xxx/yy zzz.zzz.zzz.zzz
81 size_t pos = line.find_first_of(" \t");
82
83 if (pos == std::string::npos)
84     {
85     errorStr = "No space between subnet and router";
86     return true;
87     }
88
89 std::string subnet(line.substr(0, pos)); // xxx.xxx.xxx.xxx/yy
90
91 uint32_t ip = 0;
92 uint32_t mask = 0;
93
94 if (ParseNet(subnet, ip, mask))
95     {
96     return true;
97     }
98
99 nr.subnetIP = ip;
100 nr.subnetMask = mask;
101
102 pos = line.find_first_not_of(" \t", pos);
103
104 if (pos == std::string::npos)
105     {
106     errorStr = "No router address found";
107     return true;
108     }
109
110 size_t pos2 = line.find_first_of(" \t", pos);
111
112 std::string router(line.substr(pos, pos2 == std::string::npos ? line.length() - pos2 - 1 : pos2 - pos)); //zzz.zzz.zzz.zzz
113
114 uint32_t routerIP;
115
116 if (ParseRouter(router, routerIP))
117     {
118     return true;
119     }
120
121 std::vector<uint32_t>::iterator it;
122
123 it = std::lower_bound(
124         nr.routers.begin(),
125         nr.routers.end(),
126         routerIP
127         );
128 nr.routers.insert(it, routerIP);
129
130 //nr.routers.push_back(routerIP);
131
132 while (pos2 != std::string::npos)
133     {
134     pos = line.find_first_not_of(" \t", pos2);
135
136     if (pos == std::string::npos)
137         {
138         return false;
139         }
140
141     pos2 = line.find_first_of(" \t", pos);
142
143     if (ParseRouter(line.substr(
144                         pos,
145                         pos2 == std::string::npos ? line.length() - pos2 - 1 : pos2 - pos),
146                     routerIP))
147         {
148         return true;
149         }
150
151     it = std::lower_bound(
152             nr.routers.begin(),
153             nr.routers.end(),
154             routerIP
155             );
156     nr.routers.insert(it, routerIP);
157
158     //nr.routers.push_back(routerIP);
159
160     }
161
162 return false;
163 }
164
165 bool NRMapParser::ParseNet(const std::string & line, uint32_t & ip, uint32_t & mask) const
166 {
167 // xxx.xxx.xxx.xxx/yy
168
169 size_t pos = line.find_first_of('/');
170
171 if (pos == std::string::npos)
172     {
173     errorStr = "Subnet is not in CIDR notation";
174     return true;
175     }
176
177 int res = inet_pton(AF_INET, line.substr(0, pos).c_str(), &ip); //xxx.xxx.xxx.xxx
178
179 if (res < 0)
180     {
181     errorStr = strerror(errno);
182     return true;
183     }
184 else if (res == 0)
185     {
186     errorStr = "Invalid subnet address";
187     return true;
188     }
189
190 if (str2x(line.substr(pos + 1, line.length() - pos - 1), mask)) //yy
191     {
192     errorStr = "Invalid subnet mask";
193     return true;
194     }
195 if (mask > 32)
196     {
197     errorStr = "Subnet mask is out of range [0..32]";
198     return true;
199     }
200 mask = htonl(0xffFFffFF << (32 - mask)); //bitmask
201
202 return false;
203 }
204
205 bool NRMapParser::ParseRouter(const std::string & line, uint32_t & ip) const
206 {
207 int res = inet_pton(AF_INET, line.c_str(), &ip); //zzz.zzz.zzz.zzz
208
209 if (res < 0)
210     {
211     errorStr = strerror(errno);
212     return true;
213     }
214 else if (res == 0)
215     {
216     printfd(__FILE__, "NRMapParser::ParseRouter(): IP '%s' is invalid\n", line.c_str());
217     errorStr = "Invalid router address";
218     return true;
219     }
220 return false;
221 }