feat(new-tool): generate ula based on timestamp and mac address (#344)
* feat(ipv6-ula-generator): new tool: generate ula based on timestamp and mac address This new tool generates a random unique ula based on the current timestamp and the provided mac address. An ULA is your "secondary" IPV6-Address only for internal use. It can also be used as a backup address if your provider gets offline and your Prefix-IPs are not longer valid.Also you can create the most of your internal firewall rules based on your ULAs. * feat(ipv6-ula-generator): changes requested by review * Update src/tools/ipv6-ula-generator/index.ts * Update src/tools/ipv6-ula-generator/ipv6-ula-generator.vue --------- Co-authored-by: Corentin THOMASSET <corentin.thomasset74@gmail.com>
This commit is contained in:
		
							parent
							
								
									ec7cb9351c
								
							
						
					
					
						commit
						1d7f8b9a8c
					
				| @ -20,7 +20,7 @@ export function isFalsyOrHasThrown(cb: () => ValidatorReturnType): boolean { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ValidationAttrs = { | export type ValidationAttrs = { | ||||||
|   feedback: string; |   feedback: string; | ||||||
|   validationStatus: string | undefined; |   validationStatus: string | undefined; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { tool as base64FileConverter } from './base64-file-converter'; | import { tool as base64FileConverter } from './base64-file-converter'; | ||||||
| import { tool as base64StringConverter } from './base64-string-converter'; | import { tool as base64StringConverter } from './base64-string-converter'; | ||||||
| import { tool as basicAuthGenerator } from './basic-auth-generator'; | 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 ipv4AddressConverter } from './ipv4-address-converter'; | ||||||
| import { tool as benchmarkBuilder } from './benchmark-builder'; | import { tool as benchmarkBuilder } from './benchmark-builder'; | ||||||
| import { tool as userAgentParser } from './user-agent-parser'; | import { tool as userAgentParser } from './user-agent-parser'; | ||||||
| @ -104,7 +105,7 @@ export const toolsByCategory: ToolCategory[] = [ | |||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     name: 'Network', |     name: 'Network', | ||||||
|     components: [ipv4SubnetCalculator, ipv4AddressConverter, macAddressLookup], |     components: [ipv4SubnetCalculator, ipv4AddressConverter, macAddressLookup, ipv6UlaGenerator], | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     name: 'Math', |     name: 'Math', | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								src/tools/ipv6-ula-generator/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/tools/ipv6-ula-generator/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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'), | ||||||
|  | }); | ||||||
							
								
								
									
										64
									
								
								src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/tools/ipv6-ula-generator/ipv6-ula-generator.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <n-space vertical :size="50"> | ||||||
|  |       <n-alert title="Info" type="info"> | ||||||
|  |         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. | ||||||
|  |       </n-alert> | ||||||
|  | 
 | ||||||
|  |       <n-form-item label="MAC address:" v-bind="validationAttrs"> | ||||||
|  |         <n-input | ||||||
|  |           v-model:value="macAddress" | ||||||
|  |           size="large" | ||||||
|  |           placeholder="Type a MAC address" | ||||||
|  |           clearable | ||||||
|  |           autocomplete="off" | ||||||
|  |           autocorrect="off" | ||||||
|  |           autocapitalize="off" | ||||||
|  |           spellcheck="false" | ||||||
|  |         /> | ||||||
|  |       </n-form-item> | ||||||
|  |     </n-space> | ||||||
|  | 
 | ||||||
|  |     <div v-if="validationAttrs.validationStatus !== 'error'"> | ||||||
|  |       <n-input-group v-for="{ label, value } in calculatedSections" :key="label" style="margin: 5px 0"> | ||||||
|  |         <n-input-group-label style="flex: 0 0 160px"> {{ label }} </n-input-group-label> | ||||||
|  |         <input-copyable :value="value" readonly /> | ||||||
|  |       </n-input-group> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import { SHA1 } from 'crypto-js'; | ||||||
|  | import InputCopyable from '@/components/InputCopyable.vue'; | ||||||
|  | import { macAddressValidation } from '@/utils/macAddress'; | ||||||
|  | 
 | ||||||
|  | const macAddress = ref('20:37:06:12:34:56'); | ||||||
|  | const calculatedSections = computed(() => { | ||||||
|  |   const timestamp = new Date().getTime(); | ||||||
|  |   const hex40bit = SHA1(timestamp + macAddress.value) | ||||||
|  |     .toString() | ||||||
|  |     .substring(30); | ||||||
|  |   const ula = 'fd' + hex40bit.substring(0, 2) + ':' + hex40bit.substring(2, 6) + ':' + hex40bit.substring(6); | ||||||
|  | 
 | ||||||
|  |   return [ | ||||||
|  |     { | ||||||
|  |       label: 'IPv6 ULA : ', | ||||||
|  |       value: `${ula}::/48`, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'First routable block: ', | ||||||
|  |       value: `${ula}:0::/64`, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Last routable block: ', | ||||||
|  |       value: `${ula}:ffff::/64`, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const { attrs: validationAttrs } = macAddressValidation(macAddress); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped></style> | ||||||
| @ -30,23 +30,15 @@ | |||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { useValidation } from '@/composable/validation'; |  | ||||||
| import db from 'oui/oui.json'; | import db from 'oui/oui.json'; | ||||||
|  | import { macAddressValidation } from '@/utils/macAddress'; | ||||||
| 
 | 
 | ||||||
| const getVendorValue = (address: string) => address.trim().replace(/[.:-]/g, '').toUpperCase().substring(0, 6); | const getVendorValue = (address: string) => address.trim().replace(/[.:-]/g, '').toUpperCase().substring(0, 6); | ||||||
| 
 | 
 | ||||||
| const macAddress = ref('20:37:06:12:34:56'); | const macAddress = ref('20:37:06:12:34:56'); | ||||||
| const details = computed<string | undefined>(() => db[getVendorValue(macAddress.value)]); | const details = computed<string | undefined>(() => db[getVendorValue(macAddress.value)]); | ||||||
| 
 | 
 | ||||||
| const { attrs: validationAttrs } = useValidation({ | const { attrs: validationAttrs } = macAddressValidation(macAddress); | ||||||
|   source: macAddress, |  | ||||||
|   rules: [ |  | ||||||
|     { |  | ||||||
|       message: 'Invalid MAC address', |  | ||||||
|       validator: (value) => value.trim().match(/^([0-9A-Fa-f]{2}[:-]){2,5}([0-9A-Fa-f]{2})$/), |  | ||||||
|     }, |  | ||||||
|   ], |  | ||||||
| }); |  | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="less" scoped></style> | <style lang="less" scoped></style> | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								src/utils/macAddress.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/utils/macAddress.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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 }; | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user