Can define ARP rules
This commit is contained in:
		@@ -1,3 +1,4 @@
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { TextInput } from "./TextInput";
 | 
			
		||||
 | 
			
		||||
export function IPInput(p: {
 | 
			
		||||
@@ -18,6 +19,47 @@ export function IPInput(p: {
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function IPInputWithMask(p: {
 | 
			
		||||
  label: string;
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  ip?: string;
 | 
			
		||||
  mask?: number;
 | 
			
		||||
  onValueChange?: (ip?: string, mask?: number) => void;
 | 
			
		||||
  version: 4 | 6;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const showSlash = React.useRef(!!p.mask);
 | 
			
		||||
 | 
			
		||||
  const currValue =
 | 
			
		||||
    (p.ip ?? "") + (p.mask || showSlash.current ? "/" : "") + (p.mask ?? "");
 | 
			
		||||
 | 
			
		||||
  const { onValueChange, ...props } = p;
 | 
			
		||||
  return (
 | 
			
		||||
    <TextInput
 | 
			
		||||
      onValueChange={(v) => {
 | 
			
		||||
        showSlash.current = false;
 | 
			
		||||
        if (!v) {
 | 
			
		||||
          onValueChange?.(undefined, undefined);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const split = v?.split("/");
 | 
			
		||||
        const ip =
 | 
			
		||||
          p.version === 4 ? sanitizeIpV4(split[0]) : sanitizeIpV6(split[0]);
 | 
			
		||||
        let mask = undefined;
 | 
			
		||||
 | 
			
		||||
        if (split.length > 1) {
 | 
			
		||||
          showSlash.current = true;
 | 
			
		||||
          mask = sanitizeMask(p.version, split[1]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        onValueChange?.(ip, mask);
 | 
			
		||||
      }}
 | 
			
		||||
      value={currValue}
 | 
			
		||||
      {...props}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sanitizeIpV4(s: string | undefined): string | undefined {
 | 
			
		||||
  if (s === "" || s === undefined) return s;
 | 
			
		||||
 | 
			
		||||
@@ -77,3 +119,15 @@ function sanitizeIpV6(s: string | undefined): string | undefined {
 | 
			
		||||
 | 
			
		||||
  return needAnotherIteration ? sanitizeIpV6(res) : res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sanitizeMask(version: 4 | 6, mask?: string): number | undefined {
 | 
			
		||||
  if (!mask) return undefined;
 | 
			
		||||
 | 
			
		||||
  const value = Math.floor(Number(mask));
 | 
			
		||||
 | 
			
		||||
  if (version === 4) {
 | 
			
		||||
    return value < 0 || value > 32 ? 32 : value;
 | 
			
		||||
  } else {
 | 
			
		||||
    return value < 0 || value > 64 ? 64 : value;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,13 +10,20 @@ import {
 | 
			
		||||
  Paper,
 | 
			
		||||
  Tooltip,
 | 
			
		||||
} from "@mui/material";
 | 
			
		||||
import { NWFSMac, NWFSelector, NWFilterRule } from "../../api/NWFilterApi";
 | 
			
		||||
import {
 | 
			
		||||
  NWFSArp,
 | 
			
		||||
  NWFSArpOrRARP,
 | 
			
		||||
  NWFSMac,
 | 
			
		||||
  NWFSelector,
 | 
			
		||||
  NWFilterRule,
 | 
			
		||||
} from "../../api/NWFilterApi";
 | 
			
		||||
import { EditSection } from "./EditSection";
 | 
			
		||||
import { SelectInput } from "./SelectInput";
 | 
			
		||||
import { TextInput } from "./TextInput";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
import PlaylistAddIcon from "@mui/icons-material/PlaylistAdd";
 | 
			
		||||
import { MACInput } from "./MACInput";
 | 
			
		||||
import { IPInput, IPInputWithMask } from "./IPInput";
 | 
			
		||||
 | 
			
		||||
export function NWFilterRules(p: {
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
@@ -235,6 +242,10 @@ function NWFSelectorEdit(p: {
 | 
			
		||||
            <NWFSelectorMac {...p} selector={p.selector} />
 | 
			
		||||
          )}
 | 
			
		||||
 | 
			
		||||
          {(p.selector.type === "arp" || p.selector.type === "rarp") && (
 | 
			
		||||
            <NWFSelectorArp {...p} selector={p.selector} />
 | 
			
		||||
          )}
 | 
			
		||||
 | 
			
		||||
          <TextInput
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            label="Comment"
 | 
			
		||||
@@ -311,3 +322,72 @@ function NWFSelectorMac(
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function NWFSelectorArp(
 | 
			
		||||
  p: SpecificSelectorEditor<NWFSArpOrRARP>
 | 
			
		||||
): React.ReactElement {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <MACInput
 | 
			
		||||
        {...p}
 | 
			
		||||
        label="Src mac address"
 | 
			
		||||
        value={p.selector.srcmacaddr}
 | 
			
		||||
        onValueChange={(v) => {
 | 
			
		||||
          p.selector.srcmacaddr = v;
 | 
			
		||||
          p.onChange?.();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <MACInput
 | 
			
		||||
        {...p}
 | 
			
		||||
        label="Src mac mask"
 | 
			
		||||
        value={p.selector.srcmacaddr}
 | 
			
		||||
        onValueChange={(v) => {
 | 
			
		||||
          p.selector.srcmacaddr = v;
 | 
			
		||||
          p.onChange?.();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <MACInput
 | 
			
		||||
        {...p}
 | 
			
		||||
        label="Dst mac address"
 | 
			
		||||
        value={p.selector.dstmacaddr}
 | 
			
		||||
        onValueChange={(v) => {
 | 
			
		||||
          p.selector.dstmacaddr = v;
 | 
			
		||||
          p.onChange?.();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <MACInput
 | 
			
		||||
        {...p}
 | 
			
		||||
        label="Dst mac mask"
 | 
			
		||||
        value={p.selector.dstmacaddr}
 | 
			
		||||
        onValueChange={(v) => {
 | 
			
		||||
          p.selector.dstmacaddr = v;
 | 
			
		||||
          p.onChange?.();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <IPInputWithMask
 | 
			
		||||
        {...p}
 | 
			
		||||
        label="ARP src ip"
 | 
			
		||||
        ip={p.selector.arpsrcipaddr}
 | 
			
		||||
        mask={p.selector.arpsrcipmask}
 | 
			
		||||
        version={4}
 | 
			
		||||
        onValueChange={(ip, mask) => {
 | 
			
		||||
          p.selector.arpsrcipaddr = ip;
 | 
			
		||||
          p.selector.arpsrcipmask = mask;
 | 
			
		||||
          p.onChange?.();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <IPInputWithMask
 | 
			
		||||
        {...p}
 | 
			
		||||
        label="ARP dst ip"
 | 
			
		||||
        ip={p.selector.arpdstipaddr}
 | 
			
		||||
        mask={p.selector.arpdstipmask}
 | 
			
		||||
        version={4}
 | 
			
		||||
        onValueChange={(ip, mask) => {
 | 
			
		||||
          p.selector.arpdstipaddr = ip;
 | 
			
		||||
          p.selector.arpdstipmask = mask;
 | 
			
		||||
          p.onChange?.();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user