Bringing this thread back to life. I noticed a few glitches that I would like to fix. I made some minor adjustments to the code. Here is the current source.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <ws2tcpip.h>
#include <sstream>
#include <locale>
#include <iterator>
#pragma comment(lib, "Ws2_32.lib")
struct sockaddr_in sa;
bool StringIPCompare( const std::string& a, const std::string& b )
{
static std::string localA;
static std::string localB;
static std::string ipPartsA[4];
static std::string ipPartsB[4];
localA = a;
localB = b;
localA += ".";
localB += ".";
for( unsigned int i = 0; i < 4; i++ )
{
size_t dotPos = localA.find_first_of( '.' );
if( dotPos == std::string::npos )
continue;
ipPartsA[i] = localA.substr( 0, dotPos );
localA.erase( 0, dotPos + 1 );
dotPos = localB.find_first_of( '.' );
if( dotPos == std::string::npos )
continue;
ipPartsB[i] = localB.substr( 0, dotPos );
localB.erase( 0, dotPos + 1 );
}
for( unsigned int i = 0; i < 4; i++ )
{
//Add logic here that checks for wildcards or other specialties and handles them accordingly
//Example: if you want wildcards to always top the list of similar IPs:
if( ipPartsA[i] == ipPartsB[i] )
continue;
if( ipPartsA[i] == "*" )
return true;
if( ipPartsB[i] == "*" )
return false;
unsigned int uintA;
unsigned int uintB;
sscanf_s( ipPartsA[i].c_str(), "%u", &uintA );
sscanf_s( ipPartsB[i].c_str(), "%u", &uintB );
if( uintA > uintB ) //If any number we encounter in A's parts is larger than B's equivalent we know A is bigger than B and can return false
return false;
else if( uintA < uintB )
return true;
}
return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::fstream ipFilterInput;
ipFilterInput.open("ipfilter.cfg", std::ios::in );
std::fstream ipFilterOutput;
ipFilterOutput.open("ipfilter2.cfg", std::ios::out );
std::vector<std::string> ip;
std::string current;
std::size_t badIP;
std::size_t blankSpace;
std::vector<int> octets;
std::string temp;
std::vector<std::string> value;
while(getline(ipFilterInput,current))
{
//Delete Ports from IP's with port numbers
std::string::size_type pos = current.find(":");
if(pos != std::string::npos)
current.erase(pos);
//Validate IP, but don't include wildcards '*'
if((inet_pton(AF_INET, current.c_str(), &(sa.sin_addr)) != 1))
{
badIP = current.find("*");
if(badIP != std::string::npos)
{
//These IP's fail the inet_pton() function because they have a wildcard which technically is invalid
//However we will exempt this logic for now because we don't want to filter out wildcards
//printf("A: %s\n", current.c_str());
}
else
{
current.erase();
}
}
ip.push_back(current);
}
value = ip;
//Sort Function
std::sort(value.begin(), value.end(), StringIPCompare);
//Delete Duplicates
value.erase(std::unique(value.begin(), value.end()), value.end());
//Print Results
copy(value.begin(), value.end(), std::ostream_iterator<std::string> (ipFilterOutput, "\n"));
ipFilterOutput.close();
ipFilterInput.close();
return 0;
}
The line I highlighted in red is the area I am having an issue with. Basically just to break it down.. The function inet_pton(), is used to check if the IP is valid.
I have an additional check to see if there are any wildcards “*” and if so, then they should be excluded from being removed.
In the ipconfig.cfg file though, there were IP’s that were outside of the range for example 298.298.20.17.
So I check that, and when I come across an IP out of range I use:
current.erase();
To remove that line. The issue I’m running into is that it doesn’t remove the line either. There is a break in between the next IP, and I want to remove these “whitespace”
Here are some things I have tried, and none of these gave me the results I wanted. I know some of the syntax below is off, but just to give you a general idea of what I did.
//This value is NOT a valid IP because it exceeds or is under the proper ipv4 address range 0.0.0.0 - 255.255.255.255
//current.erase(current.begin(), current.end());
//current.erase(std::unique(current.begin(), current.end()), current.end());
//printf("B: %s\n", current.c_str());
//current.erase(current.begin(), current.end());
//current.erase(std::unique(current.begin(), current.end()), current.end());
/*
current.erase();
blankSpace = current.find_last_not_of(" \n\r\t")+1;
if(badIP != std::string::npos)
{
printf("Blank space not found\n");
}
else
{
current.push_back(current - 1);
//printf("Blank space found\n");
}
*/
//current.erase(current.find_last_not_of(" \n\r\t")+1);
//current.erase(std::unique(current.begin(), current.end(), (char a, char b) { return a == '\n' && b == '\n'; }), current.end());
Any thoughts? I’m sure I’m over complicating this…