Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / 2 / lab.05.by mice / spice / src / csp_filter

.cpp
Скачиваний:
9
Добавлен:
17.04.2013
Размер:
13.35 Кб
Скачать
/*******************************************************************************
* file:         csp_filter.cpp                                                 *
* version:      0.0.1                                                          *
* author:       d-evil [tmd] (mailto:d-evil.tmd@mail.ru)                       *
* description:  not available                                                  *
*******************************************************************************/

#include "csp_filter.h"


////////////////////////////////////////////////////////////////////////////////
// csp_filter public definitions
const char *csp_filter::DEF_FILTER_FILE = "filter.txt";


csp_filter::csp_filter() {
	_is_visible = false;
	_no_filter = true;

	_from_mode = MODE_EXCEPT;
	_to_mode = MODE_EXCEPT;
	_on_mode = MODE_EXCEPT;

	_icon = NULL;
	_test_mtx = CreateMutex(NULL, FALSE, NULL);
}


csp_filter::~csp_filter() {
	CloseHandle(_test_mtx);
}


BOOL csp_filter::OnInitDialog() {
	// getting controls
	_btn_ok = (CButton *)GetDlgItem(IDC_BTN_OK);
	_btn_cancel = (CButton *)GetDlgItem(IDC_BTN_CANCEL);
	_btn_apply = (CButton *)GetDlgItem(IDC_BTN_APPLY);
	_btn_del_from = (CButton *)GetDlgItem(IDC_BTN_DEL_FROM);
	_btn_del_to = (CButton *)GetDlgItem(IDC_BTN_DEL_TO);
	_btn_del_proto = (CButton *)GetDlgItem(IDC_BTN_DEL_PROTO);
	_btn_add_from = (CButton *)GetDlgItem(IDC_BTN_ADD_FROM);
	_btn_add_to = (CButton *)GetDlgItem(IDC_BTN_ADD_TO);
	_btn_add_proto = (CButton *)GetDlgItem(IDC_BTN_ADD_PROTO);
	_btn_chk_only_to = (CButton *)GetDlgItem(IDC_CHK_ONLY_TO);
	_btn_chk_excpt_to = (CButton *)GetDlgItem(IDC_CHK_EXCPT_TO);
	_btn_chk_only_from = (CButton *)GetDlgItem(IDC_CHK_ONLY_FROM);
	_btn_chk_excpt_from = (CButton *)GetDlgItem(IDC_CHK_EXCPT_FROM);
	_btn_chk_only_proto = (CButton *)GetDlgItem(IDC_CHK_ONLY_PROTO);
	_btn_chk_excpt_proto = (CButton *)GetDlgItem(IDC_CHK_EXCPT_PROTO);

	_edit_host = (CEdit *)GetDlgItem(IDC_EDIT_HOST);
	_lsb_from = (CListBox *)GetDlgItem(IDC_LST_FROM);
	_lsb_to = (CListBox *)GetDlgItem(IDC_LST_TO);
	_lsb_proto = (CListBox *)GetDlgItem(IDC_LST_PROTO);
	_cmb_proto = (CComboBox *)GetDlgItem(IDC_CMB_PROTO);

	// load controls content
	CString str;
	_cmb_proto->ResetContent();
	for (int i = 0; 0xFF >= i; ++i) {
		_proto_str(i, str);
		_cmb_proto->AddString(str);
	}

	// setting defaults
	set_from_mode(_from_mode);
	set_to_mode(_to_mode);

	// House on the moon
	SetIcon(_icon, TRUE);

	return TRUE;
}


void csp_filter::OnClose() {
	GetParent()->PostMessage(SPM_FLT_CLOSE_ME);
}


int csp_filter::create(CWnd *const parent) {
	if (FALSE == Create(IDD_DLG_FILTER, parent)) return -1;
	CenterWindow(parent);

	return 0;
}


int csp_filter::destroy() {
	DestroyWindow();

	return 0;
}


int csp_filter::show() {
	_update();
	ShowWindow(SW_SHOW);
	_is_visible = true;

	return 0;
}


int csp_filter::hide() {
	ShowWindow(SW_HIDE);
	_is_visible = false;

	return 0;
}


int csp_filter::apply() {
	// i have a girl-friend and she is a blue...
	if (WAIT_TIMEOUT == WaitForSingleObject(_test_mtx, 2000)) return -1;

	_from_mode = _from_mode_tmp;
	_to_mode = _to_mode_tmp;
	_on_mode = _on_mode_tmp;

	_from_ips = _from_ips_tmp;
	_to_ips = _to_ips_tmp;
	_on_protos = _on_protos_tmp;
	_set_no_filter();

	ReleaseMutex(_test_mtx);

	return 0;
}


int csp_filter::load_from_file(const char *const fn) {
	const char *const fname = (NULL == fn)? DEF_FILTER_FILE: fn;
	FILE *f = fopen(fname, "a+");
	if (NULL == f) return -1;

	std::vector<unsigned int> *act_v = NULL;
	char buf[_DEF_BUF_LEN];
	while (!feof(f)) {
		if (NULL == fgets(buf, _DEF_BUF_LEN, f)) break;
		
		for (int i = (int)strlen(buf) - 1; 0 <= i; --i) {
			if (' ' < buf[i]) break;
			buf[i] = '\0';
		}

		if (0 >= strlen(buf)) continue;

		if (0 == stricmp("only from:", buf)) {
			act_v = &_from_ips;
			_from_mode = MODE_ONLY;
		} else if (0 == stricmp("except from:", buf)) {
			act_v = &_from_ips;
			_from_mode = MODE_EXCEPT;
		} else if (0 == stricmp("only to:", buf)) {
			act_v = &_to_ips;
			_to_mode = MODE_ONLY;
		} else if (0 == stricmp("except to:", buf)) {
			act_v = &_to_ips;
			_to_mode = MODE_EXCEPT;
		} else if (0 == stricmp("only on:", buf)) {
			act_v = &_on_protos;
			_on_mode = MODE_ONLY;
		} else if (0 == stricmp("except on:", buf)) {
			act_v = &_on_protos;
			_on_mode = MODE_EXCEPT;
		} else if (NULL != act_v) {
			if (':' == buf[0] && 1 < strlen(buf)) {
				const unsigned char proto = atoi(buf + 1);
				if (0 <= _get_val_pos(*act_v, (unsigned int)proto)) continue;
				act_v->push_back(proto);
			} else {
				const unsigned int ip = inet_addr(buf);
				if (0 <= _get_val_pos(*act_v, ip)) continue;
				act_v->push_back(ip);
			}
		}
	}

	fclose(f);

	_set_no_filter();
	_update();

	return 0;
}


int csp_filter::save_to_file(const char *const fn) {
	const char *const fname = (NULL == fn)? DEF_FILTER_FILE: fn;
	FILE *f = fopen(fname, "w");
	if (NULL == f) return -1;
	int n;

	if (MODE_ONLY == _from_mode) fprintf(f, "only from:\n");
	else fprintf(f, "except from:\n");
	n = (int)_from_ips.size();
	for (int i = 0; i < n; ++i) {
		in_addr addr;
		addr.s_addr = _from_ips[i];
		fprintf(f, "%s\n", inet_ntoa(addr));
	}

	if (MODE_ONLY == _to_mode) fprintf(f, "only to:\n");
	else fprintf(f, "except to:\n");
	n = (int)_to_ips.size();
	for (int i = 0; i < n; ++i) {
		in_addr addr;
		addr.s_addr = _to_ips[i];
		fprintf(f, "%s\n", inet_ntoa(addr));
	}

	if (MODE_ONLY == _on_mode) fprintf(f, "only on:\n");
	else fprintf(f, "except on:\n");
	n = (int)_on_protos.size();
	for (int i = 0; i < n; ++i) {
		fprintf(f, ":%i\n", _on_protos[i]);
	}

	fclose(f);

	return 0;
}


int csp_filter::set_from_mode(const int mode) {
	_from_mode_tmp = mode;
	if (MODE_EXCEPT == mode) {
		_btn_chk_excpt_from->SetCheck(BST_CHECKED);
		_btn_chk_only_from->SetCheck(BST_UNCHECKED);
	} else {
		_btn_chk_excpt_from->SetCheck(BST_UNCHECKED);
		_btn_chk_only_from->SetCheck(BST_CHECKED);
	}

	return 0;
}


int csp_filter::set_to_mode(const int mode) {
	_to_mode_tmp = mode;
	if (MODE_EXCEPT == mode) {
		_btn_chk_excpt_to->SetCheck(BST_CHECKED);
		_btn_chk_only_to->SetCheck(BST_UNCHECKED);
	} else {
		_btn_chk_excpt_to->SetCheck(BST_UNCHECKED);
		_btn_chk_only_to->SetCheck(BST_CHECKED);
	}

	return 0;
}


int csp_filter::set_on_mode(const int mode) {
	_on_mode_tmp = mode;
	if (MODE_EXCEPT == mode) {
		_btn_chk_excpt_proto->SetCheck(BST_CHECKED);
		_btn_chk_only_proto->SetCheck(BST_UNCHECKED);
	} else {
		_btn_chk_excpt_proto->SetCheck(BST_UNCHECKED);
		_btn_chk_only_proto->SetCheck(BST_CHECKED);
	}

	return 0;
}


bool csp_filter::test(const header_ip *const hdr) {
	if (_no_filter) return true;

	// better receive packet then lose it :)
	if (WAIT_TIMEOUT == WaitForSingleObject(_test_mtx, 2000)) return true;

	bool f = (0 <= _get_val_pos(_from_ips, hdr->sourceIP)) == (MODE_ONLY == _from_mode);
	bool t = (0 <= _get_val_pos(_to_ips, hdr->destIP)) == (MODE_ONLY == _to_mode);
	bool p = (0 <= _get_val_pos(_on_protos, (unsigned int)hdr->proto)) == (MODE_ONLY == _on_mode);

	ReleaseMutex(_test_mtx);

	return f && t && p;
}


////////////////////////////////////////////////////////////////////////////////
// csp_filter protected definitions
BEGIN_MESSAGE_MAP(csp_filter, CDialog)
	ON_WM_CLOSE()
	ON_COMMAND(IDC_BTN_OK, _on_btn_ok)
	ON_COMMAND(IDC_BTN_CANCEL, _on_btn_cancel)
	ON_COMMAND(IDC_BTN_APPLY, _on_btn_apply)
	ON_COMMAND(IDC_BTN_DEL_FROM, _on_btn_del_from)
	ON_COMMAND(IDC_BTN_DEL_TO, _on_btn_del_to)
	ON_COMMAND(IDC_BTN_DEL_PROTO, _on_btn_del_proto)
	ON_COMMAND(IDC_BTN_ADD_FROM, _on_btn_add_from)
	ON_COMMAND(IDC_BTN_ADD_TO, _on_btn_add_to)
	ON_COMMAND(IDC_BTN_ADD_PROTO, _on_btn_add_proto)
	ON_COMMAND(IDC_CHK_ONLY_TO, _on_btn_chk_only_to)
	ON_COMMAND(IDC_CHK_EXCPT_TO, _on_btn_chk_excpt_to)
	ON_COMMAND(IDC_CHK_ONLY_FROM, _on_btn_chk_only_from)
	ON_COMMAND(IDC_CHK_EXCPT_FROM, _on_btn_chk_excpt_from)
	ON_COMMAND(IDC_CHK_ONLY_PROTO, _on_btn_chk_only_proto)
	ON_COMMAND(IDC_CHK_EXCPT_PROTO, _on_btn_chk_excpt_proto)

	ON_CBN_DROPDOWN(IDC_CMB_PROTO, _on_proto_drop)
END_MESSAGE_MAP()


void csp_filter::_on_btn_ok() {
	apply();
	PostMessage(WM_CLOSE);
}


void csp_filter::_on_btn_cancel() {
	PostMessage(WM_CLOSE);
}


void csp_filter::_on_btn_apply() {
	apply();
}


void csp_filter::_on_btn_del_from() {
	int i = _lsb_from->GetCurSel();
	if (LB_ERR == i) return;

	CString str;
	_lsb_from->GetText(i, str);
	_lsb_from->DeleteString(i);

	unsigned int addr = inet_addr(str);
	i = _get_val_pos(_from_ips_tmp, addr);
	if (0 > i) return;

	std::vector<unsigned int>::iterator b = _from_ips_tmp.begin();
	_from_ips_tmp.erase(b + i);
}


void csp_filter::_on_btn_del_to() {
	int i = _lsb_to->GetCurSel();
	if (LB_ERR == i) return;

	CString str;
	_lsb_to->GetText(i, str);
	_lsb_to->DeleteString(i);

	unsigned int addr = inet_addr(str);
	i = _get_val_pos(_to_ips_tmp, addr);
	if (0 > i) return;

	std::vector<unsigned int>::iterator b = _to_ips_tmp.begin();
	_to_ips_tmp.erase(b + i);
}


void csp_filter::_on_btn_del_proto() {
	int i = _lsb_proto->GetCurSel();
	if (LB_ERR == i) return;

	unsigned int proto = (unsigned int)_lsb_proto->GetItemData(i);
	_lsb_proto->DeleteString(i);
	if (0 > proto || 0xFF < proto) return;

	i = _get_val_pos(_on_protos_tmp, proto);
	if (0 > i) return;

	std::vector<unsigned int>::iterator b = _on_protos_tmp.begin();
	_on_protos_tmp.erase(b + i);
}


void csp_filter::_on_btn_add_from() {
	CString str;
	_edit_host->GetWindowText(str);
	if (0 >= str.GetLength()) return;

	in_addr addr;
	addr.s_addr = inet_addr(str);
	if (0 <= _get_val_pos(_from_ips_tmp, (unsigned int)addr.s_addr)) {
		show_error_msg("This ip address already in list", 0, this);
		return;
	}

	_from_ips_tmp.push_back(addr.s_addr);
	_lsb_from->AddString(inet_ntoa(addr));
}


void csp_filter::_on_btn_add_to() {
	CString str;
	_edit_host->GetWindowText(str);
	if (0 >= str.GetLength()) return;

	in_addr addr;
	addr.s_addr = inet_addr(str);
	if (0 <= _get_val_pos(_to_ips_tmp, (unsigned int)addr.s_addr)) {
		show_error_msg("This ip address already in list", 0, this);
		return;
	}

	_to_ips_tmp.push_back(addr.s_addr);
	_lsb_to->AddString(inet_ntoa(addr));
}


void csp_filter::_on_btn_add_proto() {
	const unsigned int proto = _cmb_proto->GetCurSel();
	if (0 > proto || 0xFF < proto) return;

	if (0 <= _get_val_pos(_on_protos_tmp, proto)) {
		show_error_msg("This proto already in list", 0, this);
		return;
	}

	CString str;
	_proto_str(proto, str);
	int k = _lsb_proto->AddString(str);
	_lsb_proto->SetItemData(k, proto);
	_on_protos_tmp.push_back(proto);
}


void csp_filter::_on_btn_chk_only_to() {
	set_to_mode(MODE_ONLY);
}


void csp_filter::_on_btn_chk_excpt_to() {
	set_to_mode(MODE_EXCEPT);
}


void csp_filter::_on_btn_chk_only_from() {
	set_from_mode(MODE_ONLY);
}


void csp_filter::_on_btn_chk_excpt_from() {
	set_from_mode(MODE_EXCEPT);
}


void csp_filter::_on_btn_chk_only_proto() {
	set_on_mode(MODE_ONLY);
}


void csp_filter::_on_btn_chk_excpt_proto() {
	set_on_mode(MODE_EXCEPT);
}


void csp_filter::_on_proto_drop() {
	RECT rect;
	_cmb_proto->GetWindowRect(&rect);
	int w = rect.right - rect.left;
	int h = rect.bottom - rect.top;
	int ih = _cmb_proto->GetItemHeight(0);
	if (ih < 0) ih = 0;

	_cmb_proto->SetWindowPos(0, 0, 0,  w,
		h + ih*16 + 2, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW|SWP_HIDEWINDOW);

	_cmb_proto->SetWindowPos(0, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|
		SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW|SWP_SHOWWINDOW);

	return;
}


int csp_filter::_update() {
	_from_ips_tmp = _from_ips;
	_to_ips_tmp = _to_ips;
	_on_protos_tmp = _on_protos;

	_lsb_from->ResetContent();
	for (unsigned int i = 0; i < _from_ips_tmp.size(); ++i) {
		in_addr addr;
		addr.s_addr = _from_ips_tmp[i];
		_lsb_from->AddString(inet_ntoa(addr));
	}

	_lsb_to->ResetContent();
	for (unsigned int i = 0; i < _to_ips_tmp.size(); ++i) {
		in_addr addr;
		addr.s_addr = _to_ips_tmp[i];
		_lsb_to->AddString(inet_ntoa(addr));
	}

	_lsb_proto->ResetContent();
	CString str;
	for (unsigned int i = 0; i < _on_protos_tmp.size(); ++i) {
		_proto_str(_on_protos_tmp[i], str);
		int k = _lsb_proto->AddString(str);
		_lsb_proto->SetItemData(k, _on_protos_tmp[i]);
	}

	set_from_mode(_from_mode);
	set_to_mode(_to_mode);
	set_on_mode(_on_mode);

	return 0;
}


void csp_filter::_set_no_filter() {
	const bool f = (0 == _from_ips.size()) && (MODE_EXCEPT == _from_mode);
	const bool t = (0 == _to_ips.size()) && (MODE_EXCEPT == _to_mode);
	const bool p = (0 == _on_protos.size()) && (MODE_EXCEPT == _on_mode);

	_no_filter = f && t && p;
}


int csp_filter::_proto_str(const unsigned char proto, CString &str) {
	str.Format("[%03i] %s", proto, csp_parser::proto_str(proto));

	return 0;
}


template <class T>
int csp_filter::_get_val_pos(std::vector<T>& v, const T val) {
	for (int i = (int)v.size() - 1; 0 <= i; --i) {
		if (val == v[i]) return i;
	}

	return -1;
}

Соседние файлы в папке src