Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- using ll = long long;
- struct rule
- {
- string ip_from;
- int mask;
- string ip_to;
- string left, right;
- string password;
- };
- bool match_id (string left, string right, string name)
- {
- if (left.empty())
- return true;
- return (int)name.size() == (int)left.size() && left <= name && name <= right;
- }
- bool match_pass (string pass, string attempt)
- {
- return pass.empty() || attempt == pass;
- }
- void parse_ip (string &parse_to, int &mask_to, string from)
- {
- int pos = find(from.begin(), from.end(), '/') - from.begin();
- if (pos == (int)from.size())
- from += "/32";
- from[pos] = ' ';
- for (char &ch : from)
- {
- if (ch == '.')
- ch = ' ';
- }
- stringstream str(from);
- int ptr[4], mask;
- // cerr << from << endl;
- assert(str >> ptr[0] >> ptr[1] >> ptr[2] >> ptr[3] >> mask);
- parse_to.clear();
- mask_to = mask;
- for (int i = 0; i < 4; i++)
- {
- for (int j = 7; j >= 0; j--)
- parse_to += ((ptr[i] >> j) & 1) + '0';
- }
- }
- string to_ip (string what)
- {
- int ptr[4];
- assert((int)what.size() == 32);
- for (int i = 0, k = 0; i < 4; i++)
- {
- ptr[i] = 0;
- for (int j = 0; j < 8; j++)
- ptr[i] *= 2, ptr[i] += (what[k] - '0'), k++;
- }
- stringstream str;
- for (int i = 0; i < 4; i++)
- {
- str << ptr[i];
- if (i + 1 < 4)
- str << ".";
- }
- return str.str();
- }
- void solve(istream &cin = std::cin, ostream &cout = std::cout)
- {
- vector<vector<rule>> by_port;
- vector<int> ports;
- string s;
- while (getline(cin, s))
- {
- if (!s.empty() && s[0] == '-')
- break;
- stringstream str(s);
- char type;
- str >> type;
- if (type == 'A')
- {
- by_port.push_back(vector<rule>());
- int port;
- str >> port;
- ports.push_back(port);
- }
- else
- {
- assert(!by_port.empty());
- assert(type == 'F');
- rule cur;
- string from;
- str >> from;
- parse_ip (cur.ip_from, cur.mask, from);
- char dt;
- str >> dt;
- assert(dt == 'T');
- string to;
- str >> to;
- int temp;
- parse_ip(cur.ip_to, temp, to);
- assert(temp == 32);
- // cerr << "here: " << str.str() << endl;
- while (str >> dt)
- {
- if (dt == 'I')
- {
- string what, left, right;
- str >> what;
- const int pos = find(what.begin(), what.end(), '-') - what.begin();
- if (pos != (int)what.size())
- {
- left = what.substr(0, pos);
- right = what.substr(pos + 1);
- }
- else
- {
- left = right = what;
- }
- cur.left = left;
- cur.right = right;
- }
- else if (dt == 'P')
- {
- str >> cur.password;
- }
- else
- assert(false);
- }
- by_port.back().push_back(cur);
- }
- }
- while (getline(cin, s))
- {
- stringstream str(s);
- string from, name, password;
- int port = -1;
- // cerr << "query : " << s << endl;
- char dt;
- while (str >> dt)
- {
- if (dt == 'F')
- {
- string ifrom;
- str >> ifrom;
- int temp;
- parse_ip(from, temp, ifrom);
- assert(temp == 32);
- }
- else if (dt == 'T')
- {
- str >> port;
- }
- else if (dt == 'I')
- {
- str >> name;
- }
- else if (dt == 'P')
- {
- str >> password;
- }
- else
- assert(false);
- }
- const int pos = find(ports.begin(), ports.end(), port) - ports.begin();
- const string no = "dev/null";
- auto f = [&] ()
- {
- if (pos == (int)ports.size())
- return no;
- for (const auto &r : by_port[pos])
- {
- if (from.substr(0, r.mask) == r.ip_from.substr(0, r.mask) && match_id(r.left, r.right, name) && match_pass(r.password, password))
- return to_ip(r.ip_to);
- }
- return no;
- };
- auto ans = f();
- cout << ans << endl;
- }
- }
- int main()
- {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout << fixed;
- #ifdef LOCAL
- ifstream fin("../input.txt");
- solve(fin);
- cout << setprecision(4) << "clock: " << clock() / (double) CLOCKS_PER_SEC << endl;
- #else
- cout << setprecision(20);
- solve();
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement