Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkg/model/fields/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ func IsNumeric(v string) bool {
Packets,
Proto,
Bytes,
DSCP,
TCPFlags:
DSCP:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rely on field types in config since these were introduced for doc.
WDYT ?

We can create a followup for that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing some discrepancies with the frontend config, so not sure if that would break something or if that's fine.
Frontend config number fields not mentioned here:

  • IcmpType
  • IcmpCode
  • FlowDirection (probably because it's an index)
  • IfDirections (btw, weird to say it's a number since it's an array?)
  • PktDropBytes
  • PktDropPackets
  • PktDropLatestFlags
  • DnsFlags

In the other way around, there is "Port" defined here which isn't a formal field...

So maybe it's doable to use frontend config here but that sounds more a work for a PR of its own

return true
default:
return false
Expand All @@ -95,7 +94,8 @@ func IsArray(v string) bool {
case
IfDirections,
Interfaces,
NetworkEvents:
NetworkEvents,
TCPFlags:
return true
default:
return false
Expand Down
2 changes: 1 addition & 1 deletion web/src/api/ipfix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export interface Fields {
/** Network Events */
NetworkEvents?: string[];
/** Logical OR combination of unique TCP flags comprised in the flow, as per RFC-9293, with additional custom flags to represent the following per-packet combinations: SYN+ACK (0x100), FIN+ACK (0x200) and RST+ACK (0x400). */
Flags?: number;
Flags?: string[];
/** Number of packets */
Packets?: number;
/** In conversation tracking, A to B packets counter per conversation */
Expand Down
12 changes: 6 additions & 6 deletions web/src/components/drawer/record/record-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { dropCausesNames, getDropCauseDescription, getDropCauseDocUrl } from '../../../utils/pkt-drop';
import { formatPort } from '../../../utils/port';
import { formatProtocol, getProtocolDocUrl } from '../../../utils/protocol';
import { decomposeTCPFlagsBitfield, getTCPFlagsDocUrl } from '../../../utils/tcp-flags';
import { getFlagsList, getTCPFlagsDocUrl } from '../../../utils/tcp-flags';
import { Size } from '../../dropdowns/table-display-dropdown';
import './record-field.css';

Expand Down Expand Up @@ -473,9 +473,9 @@ export const RecordField: React.FC<RecordFieldProps> = ({
}
case ColumnsId.tcpflags: {
let child = emptyText();
if (typeof value === 'number' && !isNaN(value)) {
const flags = decomposeTCPFlagsBitfield(value);
const name = flags.length > 0 ? flags.map(f => f.name).join(', ') : String(value);
if (Array.isArray(value) && value.length > 0) {
const flags = getFlagsList(value as string[]);
const joined = value.join(', ');
if (detailed) {
let description = `${t('Value')}: ${value}`;
if (flags.length === 1) {
Expand All @@ -486,9 +486,9 @@ export const RecordField: React.FC<RecordFieldProps> = ({
t('The flow contains packets with various flags: ') +
flags.map(f => f.name + ' (' + f.description + ')').join('; ');
}
child = clickableContent(name, description, getTCPFlagsDocUrl());
child = clickableContent(joined, description, getTCPFlagsDocUrl());
} else {
child = simpleTextWithTooltip(name)!;
child = simpleTextWithTooltip(joined)!;
}
}
return singleContainer(child);
Expand Down
17 changes: 0 additions & 17 deletions web/src/utils/__tests__/tcp-flags.spec.ts

This file was deleted.

4 changes: 2 additions & 2 deletions web/src/utils/filter-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ export const getDSCPOptions = (value: string): Promise<FilterOption[]> => {
export const getTCPFlagsOptions = (value: string): Promise<FilterOption[]> => {
return Promise.resolve(
tcpFlagsList
.filter(opt => String(opt.value).includes(value) || opt.name.toLowerCase().includes(value.toLowerCase()))
.map(v => ({ name: v.name, value: String(v.value) }))
.filter(opt => opt.name.toLowerCase().includes(value.toLowerCase()))
.map(v => ({ name: v.name, value: v.name }))
);
};

Expand Down
36 changes: 14 additions & 22 deletions web/src/utils/tcp-flags.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { ReadOnlyValue, ReadOnlyValues } from './values';

export const getTCPFlagsDocUrl = () => {
return 'https://www.rfc-editor.org/rfc/rfc9293';
};

export const tcpFlagsList: ReadOnlyValues = [
{ value: 1, name: 'FIN', description: 'No more data from sender' },
{ value: 2, name: 'SYN', description: 'Synchronize sequence numbers' },
{ value: 4, name: 'RST', description: 'Reset the connection' },
{ value: 8, name: 'PSH', description: 'Push function' },
{ value: 16, name: 'ACK', description: 'Acknowledgement field is significant' },
{ value: 32, name: 'URG', description: 'Urgent pointer field is significant' },
{ value: 64, name: 'ECE', description: 'ECN-Echo' },
{ value: 128, name: 'CWR', description: 'Congestion Window Reduced' },
{ value: 256, name: 'SYN_ACK', description: 'Acknowledgement of SYN (custom flag)' },
{ value: 512, name: 'FIN_ACK', description: 'Acknowledgement of FIN (custom flag)' },
{ value: 1024, name: 'RST_ACK', description: 'Acknowledgement of RST (custom flag)' }
export const tcpFlagsList = [
{ name: 'FIN', description: 'No more data from sender' },
{ name: 'SYN', description: 'Synchronize sequence numbers' },
{ name: 'RST', description: 'Reset the connection' },
{ name: 'PSH', description: 'Push function' },
{ name: 'ACK', description: 'Acknowledgement field is significant' },
{ name: 'URG', description: 'Urgent pointer field is significant' },
{ name: 'ECE', description: 'ECN-Echo' },
{ name: 'CWR', description: 'Congestion Window Reduced' },
{ name: 'SYN_ACK', description: 'Acknowledgement of SYN (custom flag)' },
{ name: 'FIN_ACK', description: 'Acknowledgement of FIN (custom flag)' },
{ name: 'RST_ACK', description: 'Acknowledgement of RST (custom flag)' }
] as const;

export const decomposeTCPFlagsBitfield = (bitfield: number): ReadOnlyValues => {
const values: ReadOnlyValue[] = [];
tcpFlagsList.forEach(flag => {
if (bitfield & flag.value) {
values.push(flag);
}
});
return values;
export const getFlagsList = (names: string[]): { name: string; description: string }[] => {
return tcpFlagsList.filter(f => names.includes(f.name));
};
Loading