309 lines
7.6 KiB
TypeScript
309 lines
7.6 KiB
TypeScript
import {
|
|
Component, EventEmitter, Input,
|
|
Output, OnChanges, SimpleChanges
|
|
} from '@angular/core';
|
|
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
|
|
import * as CIDR from 'ip-cidr';
|
|
import * as ipRangeCheck from 'ip-range-check';
|
|
import { DiscoverPort, DiscoverService, DiscoverZone } from '@overflow/commons-typescript/model/discovery';
|
|
import { Checkbox } from 'primeng/primeng';
|
|
|
|
@Component({
|
|
selector: 'of-discovery-search-config',
|
|
templateUrl: './search-config.component.html',
|
|
})
|
|
export class SearchConfigComponent implements OnChanges {
|
|
|
|
SUPPORT_V6 = false;
|
|
|
|
@Input() probeHost: ProbeHost;
|
|
@Output() requestDiscovery = new EventEmitter<DiscoverZone>();
|
|
|
|
ipVer: string;
|
|
startIP: string;
|
|
endIP: string;
|
|
startPort: string;
|
|
endPort: string;
|
|
excludeIPs = [];
|
|
excludePorts = [];
|
|
includeServices = [];
|
|
|
|
hostChecked = true;
|
|
portChecked = true;
|
|
serviceChecked = true;
|
|
tcpChecked = true;
|
|
udpChecked = true;
|
|
|
|
validation = false;
|
|
ipErrMsg: string;
|
|
portErrMsg: string;
|
|
|
|
fixedIPrange: number;
|
|
ipArray = [];
|
|
portExcludeDisplay = false;
|
|
portChips = [];
|
|
|
|
constructor(
|
|
) {
|
|
}
|
|
|
|
ngOnChanges(changes: SimpleChanges): void {
|
|
if (changes['probeHost']) {
|
|
this.initByProbe();
|
|
}
|
|
this.validation = true;
|
|
}
|
|
|
|
initByProbe() {
|
|
const cidr = new CIDR(this.probeHost.probe.cidr);
|
|
if (!cidr.isValid()) {
|
|
return;
|
|
}
|
|
this.ipVer = 'v4';
|
|
this.startIP = cidr.start();
|
|
this.endIP = cidr.end();
|
|
this.startPort = '1';
|
|
this.endPort = '1024';
|
|
// TODO: Initialize services
|
|
|
|
this.checkEditableIPrange(cidr);
|
|
}
|
|
|
|
onIPExcludeFocus() {
|
|
const cidr = new CIDR(this.probeHost.probe.cidr);
|
|
this.ipArray = cidr.toArray().filter((value) => {
|
|
return this.inRange(value) || this.excludeIPs.find(obj => obj.ip === value);
|
|
}).map(value => {
|
|
return { ip: value };
|
|
});
|
|
|
|
}
|
|
|
|
inRange(value) {
|
|
const min = this.startIP;
|
|
const max = this.endIP;
|
|
if (this.ipToNum(min) <= this.ipToNum(value) && this.ipToNum(max) >= this.ipToNum(value)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ipToNum(ip) {
|
|
return Number(
|
|
ip.split('.')
|
|
.map(d => ('000' + d).substr(-3))
|
|
.join('')
|
|
);
|
|
}
|
|
|
|
onRequestDiscovery() {
|
|
let discoverPort: DiscoverPort = null;
|
|
let discoverService: DiscoverService = null;
|
|
|
|
if (this.serviceChecked) {
|
|
const services = new Array();
|
|
for (const service of this.includeServices) {
|
|
services.push(service.description);
|
|
}
|
|
discoverService = {
|
|
includeServices: services,
|
|
};
|
|
}
|
|
if (this.portChecked) {
|
|
discoverPort = {
|
|
firstScanRange: Number(this.startPort),
|
|
lastScanRange: Number(this.endPort),
|
|
includeTCP: this.tcpChecked,
|
|
includeUDP: this.udpChecked,
|
|
excludePorts: this.excludePorts,
|
|
discoverService: discoverService
|
|
};
|
|
}
|
|
const discoverZone: DiscoverZone = {
|
|
discoverHost: {
|
|
firstScanRangev4: this.startIP,
|
|
lastScanRangev4: this.endIP,
|
|
discoverPort: discoverPort,
|
|
excludeHostsv4: this.excludeIPs,
|
|
},
|
|
};
|
|
|
|
this.requestDiscovery.emit(discoverZone);
|
|
}
|
|
|
|
checkEditableIPrange(cidr) {
|
|
const startIPArray = cidr.addressStart.parsedAddress;
|
|
const endIPArray = cidr.addressEnd.parsedAddress;
|
|
let count = 0;
|
|
endIPArray.forEach((element, idx) => {
|
|
if (element === startIPArray[idx]) {
|
|
count++;
|
|
}
|
|
});
|
|
this.fixedIPrange = count;
|
|
}
|
|
|
|
onPortCheckChange(serviceCheckbox: Checkbox, checked: boolean) {
|
|
if (!checked) {
|
|
serviceCheckbox.checked = false;
|
|
this.serviceChecked = false;
|
|
} else {
|
|
if (!this.tcpChecked && !this.udpChecked) {
|
|
this.tcpChecked = true;
|
|
this.udpChecked = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
onServiceCheckChange(portCheckbox: Checkbox, checked: boolean) {
|
|
if (checked) {
|
|
portCheckbox.checked = true;
|
|
this.portChecked = true;
|
|
}
|
|
}
|
|
|
|
onPortTypeCheck(portCheckbox: Checkbox, serviceCheckbox: Checkbox): void {
|
|
if (!this.tcpChecked && !this.udpChecked) {
|
|
this.portChecked = false;
|
|
portCheckbox.checked = false;
|
|
this.serviceChecked = false;
|
|
serviceCheckbox.checked = false;
|
|
}
|
|
}
|
|
|
|
onInputIP(e, idx: number) {
|
|
const value = e.value;
|
|
if (idx === 0) {
|
|
this.startIP = value;
|
|
} else {
|
|
this.endIP = value;
|
|
}
|
|
this.ipErrMsg = this.validateIP(value, idx);
|
|
|
|
if (this.ipErrMsg) {
|
|
this.validation = false;
|
|
} else {
|
|
this.validation = true;
|
|
}
|
|
}
|
|
|
|
validateIP(value: string, idx): string {
|
|
if (!this.isValidIPregex(value)) {
|
|
return 'Not valid IP format.';
|
|
}
|
|
if (!ipRangeCheck(value, this.probeHost.probe.cidr)) {
|
|
return 'Not valid IP range.';
|
|
}
|
|
const ipArray = [this.startIP, this.endIP];
|
|
const sortedIpArray = this.sortIP([this.startIP, this.endIP]);
|
|
if (ipArray[0] !== sortedIpArray[0]) {
|
|
return 'Not valiad range';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
isValidIPregex(ip: string): boolean {
|
|
if (this.ipVer === 'v4') {
|
|
return /^(?=\d+\.\d+\.\d+\.\d+$)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.?){4}$/.test(ip);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
sortIP(ipAddressArray) {
|
|
return ipAddressArray.sort((a, b) => {
|
|
a = a.split('.');
|
|
b = b.split('.');
|
|
for (let i = 0; i < a.length; i++) {
|
|
// tslint:disable-next-line:radix
|
|
if ((a[i] = parseInt(a[i])) < (b[i] = parseInt(b[i]))) {
|
|
return -1;
|
|
} else if (a[i] > b[i]) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
onInputPort(portNum: string, idx: number) {
|
|
if (idx === 0) {
|
|
this.startPort = portNum;
|
|
} else {
|
|
this.endPort = portNum;
|
|
}
|
|
this.portErrMsg = this.validatePort(portNum);
|
|
|
|
if (this.portErrMsg) {
|
|
this.validation = false;
|
|
} else {
|
|
this.validation = true;
|
|
}
|
|
}
|
|
|
|
validatePort(portNum): string {
|
|
if (Number(this.startPort) > Number(this.endPort)) {
|
|
return 'Not valid port range.';
|
|
}
|
|
if (Number(portNum) <= 0 || Number(portNum) > 65535) {
|
|
return 'Not valid port range.';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
onAddExcludePort(event) {
|
|
const port = event.value.replace(/\s/g, '');
|
|
if (port.indexOf('~') > 0) { // e.g. 1~3000
|
|
const splited = port.split('~');
|
|
this.portChips.pop();
|
|
const from = Number(splited[0]);
|
|
const to = Number(splited[1]);
|
|
if (this.checkInvalidPort(from)
|
|
|| this.checkInvalidPort(to)
|
|
|| !Number.isInteger(from)
|
|
|| !Number.isInteger(to)) {
|
|
return;
|
|
}
|
|
const chipItem = 'All ' + from + ' ~ ' + to;
|
|
this.portChips.push(chipItem);
|
|
for (let i = from; i <= to; i++) {
|
|
this.excludePorts.push(String(i));
|
|
}
|
|
} else {
|
|
const num = Number(event.value);
|
|
if (!Number.isInteger(num) || this.checkInvalidPort(num) || this.checkExistExcludePort(event.value)) {
|
|
this.portChips.pop();
|
|
return;
|
|
}
|
|
this.excludePorts.push(event.value);
|
|
}
|
|
}
|
|
|
|
onRemoveExcludePort(event) {
|
|
if (event.value.indexOf('~') > 0) {
|
|
// e.g. 'All 1 ~ 30'
|
|
const splited = event.value.replace(/\s/g, '').replace('All', '').split('~');
|
|
for (let i = Number(splited[0]); i <= Number(splited[1]); i++) {
|
|
console.log(String(i));
|
|
const index = this.excludePorts.indexOf(String(i));
|
|
this.excludePorts.splice(index, 1);
|
|
}
|
|
return;
|
|
}
|
|
const idx = this.excludePorts.indexOf(event.value);
|
|
this.excludePorts.splice(idx, 1);
|
|
}
|
|
|
|
checkExistExcludePort(portNum) {
|
|
return this.excludePorts.find((value) => {
|
|
return value === portNum;
|
|
});
|
|
}
|
|
|
|
checkInvalidPort(port) {
|
|
return port <= 0 || port > 65535;
|
|
}
|
|
|
|
}
|