this.requestUpdate()}
>
${endpointTemplate(source, 'source', availableSourcePorts, edge.data('inPort'), msg('Source'))}
${endpointTemplate(target, 'target', availableTargetPorts, edge.data('outPort'), msg('Target'))}
`;
}
function networkConfigDrawerTemplate(this: NetworkComponent) {
const network: any = this.selectedObject;
return html`
this.requestUpdate()}
>
{
const value = (e.target as SlInput).value;
const subnet: Net = this.selectedObject.data();
if (Ipv4Address.validateAddress(value, this.ipv4Database) == null) {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('IPv4 address is invalid.'));
return;
} else {
(e.target as SlInput).classList.remove('danger');
(e.target as SlInput).classList.add('success');
(e.target as SlInput).setAttribute('help-text', '');
}
const success = subnet.handleChangesOnNewNetInfo(value, subnet.netmask, subnet.bitmask, this);
if (success) {
this.selectedObject.toggleClass('unconfigured-net', false);
const name = this.selectedObject.data('name');
this.selectedObject.data('name', name);
} else {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('Invalid net id.'));
}
}}
>
{
const value = (e.target as SlInput).value;
const subnet: Net = this.selectedObject.data();
if (Ipv4Address.validateAddress(value, this.ipv4Database) == null) {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('IPv4 address is invalid.'));
return;
} else {
(e.target as SlInput).classList.remove('danger');
(e.target as SlInput).classList.add('success');
(e.target as SlInput).setAttribute('help-text', '');
}
const success = subnet.handleChangesOnNewNetInfo(
subnet.networkAddress.address,
value,
subnet.bitmask,
this
);
if (success) {
this.selectedObject.toggleClass('unconfigured-net', false);
const name = this.selectedObject.data('name');
this.selectedObject.data('name', name);
const bitmask = (
AddressingHelper.decimalStringWithDotToBinary(value).match(new RegExp('1', 'g')) || []
).length;
this.shadowRoot?.querySelector('#bitmask')?.setAttribute('value', bitmask.toString());
} else {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('Invalid netmask.'));
}
}}
>
{
const value = parseInt((e.target as SlInput).value);
const subnet: Net = this.selectedObject.data();
const netmask = AddressingHelper.binaryToDecimalOctets(''.padStart(value, '1').padEnd(32, '0'));
const success = subnet.handleChangesOnNewNetInfo(
subnet.networkAddress.address,
netmask.join('.'),
value,
this
);
this.shadowRoot?.querySelector('#netmask')?.setAttribute('value', netmask.join('.'));
if (success) {
this.selectedObject.toggleClass('unconfigured-net', false);
const name = this.selectedObject.data('name');
this.selectedObject.data('name', name);
(e.target as SlInput).classList.remove('danger');
(e.target as SlInput).classList.add('success');
(e.target as SlInput).setAttribute('help-text', '');
} else {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('Invalid bitmask.'));
}
}}
>
`;
}
function handleMacAddressChangeGenerator(this: NetworkComponent, index: string) {
return function handleMacAddressChange(this: NetworkComponent, e: SlChangeEvent) {
const v = (e.target as SlInput).value;
const mac = MacAddress.validateAddress(v, this.macDatabase);
if (mac != null) {
MacAddress.removeAddressFromDatabase(
this.selectedObject.data('portData').get(index).get('MAC'),
this.macDatabase
);
const portData = this.selectedObject.data('portData');
portData.get(index).set('MAC', mac);
this.selectedObject.data('portData', portData);
MacAddress.addAddressToDatabase(mac, this.macDatabase, this.selectedObject.id);
(e.target as SlInput).classList.remove('danger');
(e.target as SlInput).classList.add('success');
(e.target as SlInput).setAttribute('help-text', '');
} else {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('MAC address is invalid.'));
}
};
}
function handleIPv4AddressChangeGenerator(this: NetworkComponent, index: string) {
const subnet = this.selectedObject.isChild() ? this.selectedObject.parent().data() : null;
const gateway: boolean = this.selectedObject.hasClass('gateway-node');
return function handleIPv4AddressChange(this: NetworkComponent, e: SlChangeEvent) {
const v = (e.target as SlInput).value;
const ipv4 = Ipv4Address.validateAddress(v, this.ipv4Database);
if (ipv4 != null) {
if (subnet != null && this.subnettingMode == 'HOST_BASED') {
Net.calculateCIDRGivenNewHost(subnet, ipv4, this.ipv4Database, this);
this.selectedObject.parent().classes(subnet.cssClass);
}
if (subnet != null && this.subnettingMode == 'NET_BASED' && !ipv4.matchesNetworkCidr(subnet)) {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg("Inserted IPv4 doesn't match the subnet mask."));
return;
}
if (gateway) {
// console.log('gateway', this.selectedObject.data(), index);
const affectedNetwork: Net | undefined = (this.selectedObject.data() as Router).portNetMapping.get(
parseInt(index)
);
if (this.subnettingMode == 'HOST_BASED' && affectedNetwork) {
Net.calculateCIDRGivenNewHost(affectedNetwork, ipv4, this.ipv4Database, this);
this._graph.$('#' + affectedNetwork.id).classes(affectedNetwork.cssClass);
}
if (this.subnettingMode == 'NET_BASED' && affectedNetwork && !ipv4.matchesNetworkCidr(affectedNetwork)) {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute(
'help-text',
msg("Inserted IPv4 for gateway doesn't match the subnet mask or the network is not configured.")
);
return;
}
}
Ipv4Address.removeAddressFromDatabase(
this.selectedObject.data('portData').get(index).get('IPv4'),
this.ipv4Database
);
const portData = this.selectedObject.data('portData');
portData.get(index).set('IPv4', ipv4);
this.selectedObject.data('portData', portData);
Ipv4Address.addAddressToDatabase(ipv4, this.ipv4Database, this.selectedObject.data('id'));
(e.target as SlInput).classList.remove('danger');
(e.target as SlInput).classList.add('success');
(e.target as SlInput).setAttribute('help-text', '');
} else {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('IPv4 address is invalid.'));
}
};
}
function handleIPv6AddressChangeGenerator(this: NetworkComponent, index: string) {
return function handleIPv6AddressChange(this: NetworkComponent, e: SlChangeEvent) {
const v = (e.target as SlInput).value;
const ipv6 = Ipv6Address.validateAddress(v, this.ipv6Database);
if (ipv6 != null) {
Ipv6Address.removeAddressFromDatabase(
this.selectedObject.data('portData').get(index).get('IPv6'),
this.ipv6Database
);
const portData = this.selectedObject.data('portData');
portData.get(index).set('IPv6', ipv6);
this.selectedObject.data('portData', portData);
Ipv6Address.addAddressToDatabase(ipv6, this.ipv6Database, this.selectedObject.data('id'));
(e.target as SlInput).classList.remove('danger');
(e.target as SlInput).classList.add('success');
(e.target as SlInput).setAttribute('help-text', '');
} else {
(e.target as SlInput).classList.add('danger');
(e.target as SlInput).classList.remove('success');
(e.target as SlInput).setAttribute('help-text', msg('IPv6 address is invalid.'));
}
};
}
function handlePortTypeChangeGenerator(this: NetworkComponent, index: string) {
return function handlePortTypeChange(this: NetworkComponent, e: SlChangeEvent) {
const v = (e.target as SlSelect).value;
const portData = this.selectedObject.data('portData');
portData.get(index).set('Connection Type', v);
this.selectedObject.data('portData', portData);
};
}
function addPort(this: NetworkComponent, node: any) {
const portInfo = new Map();
if (
node.data('cssClass').includes('access-point-node') ||
node.data('cssClass').includes('switch-node') ||
node.data('cssClass').includes('bridge-node')
) {
const mac = MacAddress.generateRandomAddress(this.macDatabase);
portInfo.set('MAC', mac);
}
if (node.data('cssClass').includes('bridge-node') || node.data('cssClass').includes('repeater-node')) {
portInfo.set('Connection Type', 'ethernet');
}
if (node.data('cssClass').includes('router-node') || node.data('cssClass').includes('host-node')) {
const mac = MacAddress.generateRandomAddress(this.macDatabase);
const ipv4 = Ipv4Address.getLoopBackAddress();
const ipv6 = Ipv6Address.getLoopBackAddress();
const takenNames = new Set([...node.data('portData').values()].map((port: any) => port.get('Name')));
let nameNumber = node.data('portData').size + 1;
while (takenNames.has('port-' + nameNumber)) nameNumber++;
const name = 'port-' + nameNumber;
const connectionType = 'ethernet';
portInfo.set('MAC', mac);
portInfo.set('IPv4', ipv4);
portInfo.set('IPv6', ipv6);
portInfo.set('Name', name);
portInfo.set('Connection Type', connectionType);
}
node.data('portData').set(node.data('portData').size + 1, portInfo);
node.data('portLinkMapping').set(node.data('portLinkMapping').size + 1, null);
node.data('numberOfInterfacesOrPorts', node.data('numberOfInterfacesOrPorts') + 1);
this.requestUpdate();
}
function removePort(this: NetworkComponent, node: any, index: string) {
if (isPortConnected.bind(this)(node, index)) {
AlertHelper.toastAlert('warning', 'exclamation-triangle', '', msg('Disconnect the port to remove it.'));
return;
}
const ipv4 = node.data('portData').get(index).get('IPv4');
if (ipv4 != null) Ipv4Address.removeAddressFromDatabase(ipv4, this.ipv4Database);
const ipv6 = node.data('portData').get(index).get('IPv6');
if (ipv6 != null) Ipv6Address.removeAddressFromDatabase(ipv6, this.ipv6Database);
const mac = node.data('portData').get(index).get('MAC');
if (mac != null) MacAddress.removeAddressFromDatabase(mac, this.macDatabase);
node.data('portData').delete(index);
node.data('portLinkMapping').delete(index);
node.data('portNetMapping')?.delete(index);
compactPortNumbers.bind(this)(node);
node.data('numberOfInterfacesOrPorts', node.data('portData').size);
this.requestUpdate();
}
function compactPortNumbers(this: NetworkComponent, node: any): void {
const renumber = new Map