Skip to content

Commit

Permalink
Add IpRange Model and Form with Validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-burwood committed Mar 14, 2024
1 parent 0881f81 commit 114c68f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
6 changes: 6 additions & 0 deletions NetworkMapper/ip/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from django import forms

from .models import ClientDevice, VLAN, WifiNetwork
from .models.ip import IpRange

class IpRangeForm(forms.Form):
class Meta:
model = IpRange
fields = ["start_address", "end_address", "num_addresses", "description"]


class VLANForm(forms.ModelForm):
Expand Down
47 changes: 47 additions & 0 deletions NetworkMapper/ip/models/ip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from django.core.exceptions import ValidationError
from django.db import models


class IpRange(models.Model):
start_address = models.GenericIPAddressField()
end_address = models.GenericIPAddressField()
num_addresses = models.PositiveIntegerField()
description = models.TextField(blank=True, null=True)

def clean(self):
super().clean()

if self.start_address > self.end_address:
raise ValidationError("Start Address must be Lower than End Address")

if self.start_address.protocol != self.end_address.protocol:
raise ValidationError("Start Address and End Address must be of the same IP Version")

for other_ip_range in IpRange.objects.exclude(pk=self.pk):
if self.check_overlap(other_ip_range):
raise ValidationError("IP Range overlaps with another IP Range : " + other_ip_range)

def check_overlap(self, other: "IpRange") -> bool:
"""Check if the given IP Range overlaps with the current IP Range"""
if self.start_address <= other.start_address <= self.end_address:
return True
if self.start_address <= other.end_address <= self.end_address:
return True
if other.start_address <= self.start_address <= other.end_address:
return True
if other.start_address <= self.end_address <= other.end_address:
return True
return False

@staticmethod
def ipv4_to_numeric(ip):
octets = ip.split(".")

for octet in octets:
if not octet.isdigit() or not 0 <= int(octet) <= 255:
raise ValueError("Invalid IPv4 address format")

numeric_ip = 0
for i in range(4):
numeric_ip += int(octets[i]) * (256 ** (3 - i))
return numeric_ip

0 comments on commit 114c68f

Please sign in to comment.