diff --git a/virtweb_frontend/src/widgets/forms/NWFilterRules.tsx b/virtweb_frontend/src/widgets/forms/NWFilterRules.tsx
index fe56dd6..84eac90 100644
--- a/virtweb_frontend/src/widgets/forms/NWFilterRules.tsx
+++ b/virtweb_frontend/src/widgets/forms/NWFilterRules.tsx
@@ -1,6 +1,7 @@
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
import DeleteIcon from "@mui/icons-material/Delete";
+import PlaylistAddIcon from "@mui/icons-material/PlaylistAdd";
import {
Button,
Card,
@@ -11,20 +12,20 @@ import {
Tooltip,
} from "@mui/material";
import {
- NWFSArp,
NWFSArpOrRARP,
NWFSIPBase,
+ NWFSLayer4Base,
NWFSMac,
NWFSelector,
NWFilterRule,
} from "../../api/NWFilterApi";
+import { ServerApi } from "../../api/ServerApi";
import { EditSection } from "./EditSection";
+import { IPInput, IPInputWithMask } from "./IPInput";
+import { MACInput } from "./MACInput";
+import { PortInput } from "./PortInput";
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;
@@ -255,6 +256,20 @@ function NWFSelectorEdit(p: {
)}
+ {(p.selector.type === "tcp" ||
+ p.selector.type === "udp" ||
+ p.selector.type === "sctp" ||
+ p.selector.type === "icmp") && (
+
+ )}
+
+ {(p.selector.type === "tcpipv6" ||
+ p.selector.type === "udpipv6" ||
+ p.selector.type === "sctpipv6" ||
+ p.selector.type === "icmpipv6") && (
+
+ )}
+
{
- p.selector.srcmacaddr = v;
+ p.selector.srcmacmask = v;
p.onChange?.();
}}
/>
@@ -372,9 +387,9 @@ function NWFSelectorArp(
{
- p.selector.dstmacaddr = v;
+ p.selector.dstmacmask = v;
p.onChange?.();
}}
/>
@@ -423,9 +438,9 @@ function NWFSelectorIP(
{
- p.selector.srcmacaddr = v;
+ p.selector.srcmacmask = v;
p.onChange?.();
}}
/>
@@ -441,9 +456,9 @@ function NWFSelectorIP(
{
- p.selector.dstmacaddr = v;
+ p.selector.dstmacmask = v;
p.onChange?.();
}}
/>
@@ -474,3 +489,134 @@ function NWFSelectorIP(
>
);
}
+
+function NWFSelectorLayer4(
+ p: SpecificSelectorEditorWithIPVersion
+): React.ReactElement {
+ return (
+ <>
+ {
+ p.selector.srcmacaddr = v;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.srcipaddr = ip;
+ p.selector.srcipmask = mask;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.dstipaddr = ip;
+ p.selector.dstipmask = mask;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.srcipfrom = ip;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.srcipto = ip;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.dstipfrom = ip;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.dstipto = ip;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.srcportstart = port;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.srcportend = port;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.dstportstart = port;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.dstportend = port;
+ p.onChange?.();
+ }}
+ />
+ {
+ p.selector.state = s as any;
+ p.onChange?.();
+ }}
+ options={[
+ { label: "None", value: undefined },
+ { label: "NEW", value: "NEW" },
+ { label: "ESTABLISHED", value: "ESTABLISHED" },
+ { label: "RELATED", value: "RELATED" },
+ { label: "INVALID", value: "INVALID" },
+ { label: "NONE", value: "NONE" },
+ ]}
+ />
+ >
+ );
+}
diff --git a/virtweb_frontend/src/widgets/forms/PortInput.tsx b/virtweb_frontend/src/widgets/forms/PortInput.tsx
new file mode 100644
index 0000000..aead89e
--- /dev/null
+++ b/virtweb_frontend/src/widgets/forms/PortInput.tsx
@@ -0,0 +1,28 @@
+import { TextInput } from "./TextInput";
+
+export function PortInput(p: {
+ editable: boolean;
+ label: string;
+ value?: number;
+ onChange: (value: number | undefined) => void;
+}): React.ReactElement {
+ return (
+ {
+ p.onChange?.(sanitizePort(v));
+ }}
+ />
+ );
+}
+
+function sanitizePort(port?: string): number | undefined {
+ if (port === undefined) return undefined;
+ const val = Number(port);
+
+ if (val < 0) return 0;
+ if (val > 65535) return 65535;
+ return val;
+}