diff --git a/src/composable/validation.ts b/src/composable/validation.ts
index fc008de8..2c58b60b 100644
--- a/src/composable/validation.ts
+++ b/src/composable/validation.ts
@@ -20,7 +20,7 @@ export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean {
}
}
-type ValidationAttrs = {
+export type ValidationAttrs = {
feedback: string;
validationStatus: string | undefined;
};
diff --git a/src/tools/index.ts b/src/tools/index.ts
index f1d63b79..c68c20aa 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,6 +1,7 @@
import { tool as base64FileConverter } from './base64-file-converter';
import { tool as base64StringConverter } from './base64-string-converter';
import { tool as basicAuthGenerator } from './basic-auth-generator';
+import { tool as ipv6UlaGenerator } from './ipv6-ula-generator';
import { tool as ipv4AddressConverter } from './ipv4-address-converter';
import { tool as benchmarkBuilder } from './benchmark-builder';
import { tool as userAgentParser } from './user-agent-parser';
@@ -104,7 +105,7 @@ export const toolsByCategory: ToolCategory[] = [
},
{
name: 'Network',
- components: [ipv4SubnetCalculator, ipv4AddressConverter, macAddressLookup],
+ components: [ipv4SubnetCalculator, ipv4AddressConverter, macAddressLookup, ipv6UlaGenerator],
},
{
name: 'Math',
diff --git a/src/tools/ipv6-ula-generator/index.ts b/src/tools/ipv6-ula-generator/index.ts
new file mode 100644
index 00000000..def3dfed
--- /dev/null
+++ b/src/tools/ipv6-ula-generator/index.ts
@@ -0,0 +1,13 @@
+import { BuildingFactory } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+ name: 'IPv6 ULA generator',
+ path: '/ipv6-ula-generator',
+ description:
+ 'Generate your own local, non-routable IP addresses on your network according to RFC4193.',
+ keywords: ['ipv6', 'ula', 'generator', 'rfc4193', 'network', 'private'],
+ component: () => import('./ipv6-ula-generator.vue'),
+ icon: BuildingFactory,
+ createdAt: new Date('2023-04-09'),
+});
diff --git a/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue b/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
new file mode 100644
index 00000000..d5c3766d
--- /dev/null
+++ b/src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
@@ -0,0 +1,64 @@
+
+
+
+
+ This page uses the first method suggested by IETF using the current timestamp plus the mac address, sha1 hashed,
+ and the lower 40 bits to generate your random ULA.
+
+
+
+
+
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/mac-address-lookup/mac-address-lookup.vue b/src/tools/mac-address-lookup/mac-address-lookup.vue
index 60e4836b..99b8342d 100644
--- a/src/tools/mac-address-lookup/mac-address-lookup.vue
+++ b/src/tools/mac-address-lookup/mac-address-lookup.vue
@@ -30,23 +30,15 @@
diff --git a/src/utils/macAddress.ts b/src/utils/macAddress.ts
new file mode 100644
index 00000000..5451a36c
--- /dev/null
+++ b/src/utils/macAddress.ts
@@ -0,0 +1,16 @@
+import { useValidation, type ValidationAttrs } from '@/composable/validation';
+import type { Ref } from 'vue';
+
+function macAddressValidation(value: Ref) {
+ return useValidation({
+ source: value,
+ rules: [
+ {
+ message: 'Invalid MAC address',
+ validator: (value) => value.trim().match(/^([0-9A-Fa-f]{2}[:-]){2,5}([0-9A-Fa-f]{2})$/),
+ },
+ ],
+ });
+}
+
+export { macAddressValidation };