summaryrefslogtreecommitdiffstats
path: root/VNFs/DPPD-PROX/genl4_stream_udp.c
blob: 3de2db093e0c6faa5defb0d711551fc03f8884db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

@media only all and (prefers-color-scheme: dark) {
.highlight .hll { background-color: #49483e }
.highlight .c { color: #75715e } /* Comment */
.highlight .err { color: #960050; background-color: #1e0010 } /* Error */
.highlight .k { color: #66d9ef } /* Keyword */
.highlight .l { color: #ae81ff } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #f92672 } /* Operator */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #75715e } /* Comment.Hashbang */
.highlight .cm { color: #75715e } /* Comment.Multiline */
.highlight .cp { color: #75715e } /* Comment.Preproc */
.highlight .cpf { color: #75715e } /* Comment.PreprocFile */
.highlight .c1 { color: #75715e } /* Comment.Single */
.highlight .cs { color: #75715e } /* Comment.Special */
.highlight .gd { color: #f92672 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gi { color: #a6e22e } /* Generic.Inserted */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #75715e } /* Generic.Subheading */
.highlight .kc { color: #66d9ef } /* Keyword.Constant */
.highlight .kd { color: #66d9ef } /* Keyword.Declaration */
.highlight .kn { color: #f92672 } /* Keyword.Namespace */
.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */
.highlight .kr { color: #66d9ef } /* Keyword.Reserved */
.highlight .kt { color: #66d9ef } /* Keyword.Type */
.highlight .ld { color: #e6db74 } /* Literal.Date */
.highlight .m { color: #ae81ff } /* Literal.Number */
.highlight .s
/*
// Copyright (c) 2010-2017 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include "genl4_stream_udp.h"
#include "mbuf_utils.h"

int stream_udp_is_ended(struct stream_ctx *ctx)
{
	return ctx->cur_action == ctx->stream_cfg->n_actions;
}

static void update_token_times(struct stream_ctx *ctx)
{
	uint64_t now = rte_rdtsc();

	token_time_update(&ctx->token_time_other, now);
	token_time_update(&ctx->token_time, now);
}

int stream_udp_proc(struct stream_ctx *ctx, struct rte_mbuf *mbuf, struct l4_meta *l4_meta, uint64_t *next_tsc)
{
	update_token_times(ctx);

	if (l4_meta) {
		enum l4gen_peer peer = ctx->stream_cfg->actions[ctx->cur_action].peer;
		plogx_dbg("Consuming UDP data\n");
		/* data should come from the other side */
		if (peer == ctx->peer) {
			plogx_err("Wrong peer\n");
			return -1;
		}
		/* Fixed length data expected */
		if (ctx->stream_cfg->actions[ctx->cur_action].len != l4_meta->len) {
			plogx_dbg("unexpected UDP len (expected = %u, got = %u, action = %u)\n",
				  ctx->stream_cfg->actions[ctx->cur_action].len,
				  l4_meta->len,
				  ctx->cur_action);

			return -1;
		}
		/* With specific payload */
		if (memcmp(ctx->stream_cfg->data[peer].content + ctx->stream_cfg->actions[ctx->cur_action].beg, l4_meta->payload, l4_meta->len) != 0) {
			plogx_dbg("Bad payload at action_id %d, with peer = %d and pos = %d and len=%d\n", ctx->cur_action, peer, ctx->cur_pos[peer], l4_meta->len);
			return -1;
		}
		ctx->cur_pos[peer] += l4_meta->len;
		ctx->cur_action++;

		if (stream_udp_is_ended(ctx))
			return -1;

		token_time_take(&ctx->token_time_other, mbuf_wire_size(mbuf));
		/* Time before next packet is expected to
		   arrive. Note, addition amount of time is accounted
		   for due to rate limiting. */
		uint64_t wait = token_time_tsc_until_full(&ctx->token_time_other);
		*next_tsc = wait + ctx->stream_cfg->tsc_timeout;
	}

	if (ctx->stream_cfg->actions[ctx->cur_action].peer != ctx->peer) {
		const char *other_peer_str = ctx->peer != PEER_SERVER? "server" : "client";

		plogx_dbg("Expecting more UDP data from %s, will expire = %s\n", other_peer_str, l4_meta == NULL? "yes" : "no");
		if (!l4_meta) {
			ctx->flags |= STREAM_CTX_F_EXPIRED;
		}
		return -1;
	}

	uint64_t wait_tsc = token_time_tsc_until_full(&ctx->token_time);

	if (wait_tsc != 0) {
		plogx_dbg("Wait = %"PRIu64"\n", wait_tsc);
		*next_tsc = wait_tsc;
		return -1;
	}

	const struct stream_cfg *stream_cfg = ctx->stream_cfg;

	uint8_t *pkt = rte_pktmbuf_mtod(mbuf, uint8_t *);
	const struct peer_action *act = &stream_cfg->actions[ctx->cur_action];

	uint16_t pkt_len = stream_cfg->data[act->peer].hdr_len + sizeof(struct udp_hdr) + act->len;

	rte_pktmbuf_pkt_len(mbuf) = pkt_len;
	rte_pktmbuf_data_len(mbuf) = pkt_len;
	plogx_dbg("Creating UDP data (peer = %s, payload len = %u)\n", act->peer == PEER_CLIENT? "client" : "server", act->len);
	/* Construct the packet. The template is used up to L4 header,
	   a gap of sizeof(l4_hdr) is skipped, followed by the payload. */
	rte_memcpy(pkt, stream_cfg->data[act->peer].hdr, stream_cfg->data[act->peer].hdr_len);
	rte_memcpy(pkt + stream_cfg->data[act->peer].hdr_len + sizeof(struct udp_hdr), stream_cfg->data[act->peer].content + act->beg, act->len);

	struct ipv4_hdr *l3_hdr = (struct ipv4_hdr*)&pkt[stream_cfg->data[act->peer].hdr_len - sizeof(struct ipv4_hdr)];
	struct udp_hdr *l4_hdr = (struct udp_hdr*)&pkt[stream_cfg->data[act->peer].hdr_len];

	l3_hdr->src_addr = ctx->tuple->dst_addr;
	l3_hdr->dst_addr = ctx->tuple->src_addr;
	l3_hdr->next_proto_id = IPPROTO_UDP;
	l4_hdr->src_port = ctx->tuple->dst_port;
	l4_hdr->dst_port = ctx->tuple->src_port;
	l4_hdr->dgram_len = rte_bswap16(sizeof(struct udp_hdr) + act->len);
	/* TODO: UDP checksum calculation */
	l3_hdr->total_length = rte_bswap16(sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr) + act->len);
	ctx->cur_pos[ctx->peer] += act->len;
	ctx->cur_action++;

	/* When the stream has ended, there is no need to schedule
	   another timeout (which will be unscheduled at the end of
	   the stream). */
	if (stream_udp_is_ended(ctx))
		return 0;

	token_time_take(&ctx->token_time, mbuf_wire_size(mbuf));

	/* Send next packet as soon as possible */
	if (ctx->stream_cfg->actions[ctx->cur_action].peer == ctx->peer) {
		*next_tsc = token_time_tsc_until_full(&ctx->token_time);
	}
	else {
		uint64_t wait = token_time_tsc_until_full(&ctx->token_time_other);
		*next_tsc = wait + ctx->stream_cfg->tsc_timeout;
	}

	return 0;
}

uint16_t stream_udp_reply_len(struct stream_ctx *ctx)
{
	if (stream_udp_is_ended(ctx))
		return 0;
	else if (ctx->stream_cfg->actions[ctx->cur_action].peer == ctx->peer)
		return 0;
	else
		return ctx->stream_cfg->data[ctx->stream_cfg->actions[ctx->cur_action].peer].hdr_len + sizeof(struct udp_hdr) +
			ctx->stream_cfg->actions[ctx->cur_action].len;
}

void stream_udp_calc_len(struct stream_cfg *cfg, uint32_t *n_pkts, uint32_t *n_bytes)
{
	const uint32_t client_hdr_len = cfg->data[PEER_CLIENT].hdr_len;
	const uint32_t server_hdr_len = cfg->data[PEER_SERVER].hdr_len;

	*n_pkts = 0;
	*n_bytes = 0;

	for (uint32_t i = 0; i < cfg->n_actions; ++i) {
		const uint32_t send_hdr_len = cfg->actions[i].peer == PEER_CLIENT? client_hdr_len : server_hdr_len;
		uint32_t len = send_hdr_len + sizeof(struct udp_hdr) + cfg->actions[i].len;
		*n_bytes += (len < 60? 60 : len) + 24;
		(*n_pkts)++;
	}
}
audit_rules_networkconfig_modification' order : 26 'Record Events that Modify the Systems Network Environment - /etc/sysconfig/network': content: '-w /etc/sysconfig/network -p wa -k audit_rules_networkconfig_modification' order : 27 'Record Events that Modify the Systems Mandatory Access Controls': content: '-w /etc/selinux/ -p wa -k MAC-policy' order : 28 'Ensure auditd Collects Unauthorized Access Attempts to Files (unsuccessful / EACCES)': content: '-a always,exit -F arch=b64 -S creat -S open -S openat -S open_by_handle_at -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access' order : 29 'Ensure auditd Collects Unauthorized Access Attempts to Files (unsuccessful / EPERM)': content: '-a always,exit -F arch=b64 -S creat -S open -S openat -S open_by_handle_at -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access' order : 30 'Ensure auditd Collects Information on the Use of Privileged Commands': content: '-a always,exit -F path=SETUID_PROG_PATH -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged' order : 31 'Ensure auditd Collects Information on Exporting to Media (successful)': content: '-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k export' order : 32 'Ensure auditd Collects File Deletion Events by User': content: '-a always,exit -F arch=b64 -S rmdir -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete' order : 33 'Ensure auditd Collects System Administrator Actions': content: '-w /etc/sudoers -p wa -k actions' order : 34 'Ensure auditd Collects Information on Kernel Module Loading and Unloading (insmod)': content: '-w /usr/sbin/insmod -p x -k modules' order : 35 'Ensure auditd Collects Information on Kernel Module Loading and Unloading (rmmod)': content: '-w /usr/sbin/rmmod -p x -k modules' order : 36 'Ensure auditd Collects Information on Kernel Module Loading and Unloading (modprobe)': content: '-w /usr/sbin/modprobe -p x -k modules' order : 37