Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/share/examples/kld/khelp/h_example.c
104132 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2010-2011 The FreeBSD Foundation
5
*
6
* This software was developed at the Centre for Advanced Internet
7
* Architectures, Swinburne University of Technology, Melbourne, Australia by
8
* Lawrence Stewart under sponsorship from the FreeBSD Foundation.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
/*
33
* This example Khelp module uses the helper hook points available in the TCP
34
* stack to calculate a per-connection count of inbound and outbound packets
35
* when the connection is in the established state. The code is verbosely
36
* documented in an attempt to explain how everything fits together.
37
*/
38
39
#include <sys/param.h>
40
#include <sys/kernel.h>
41
#include <sys/hhook.h>
42
#include <sys/khelp.h>
43
#include <sys/module.h>
44
#include <sys/module_khelp.h>
45
#include <sys/socket.h>
46
#include <sys/socketvar.h>
47
48
#include <netinet/in.h>
49
#include <netinet/in_pcb.h>
50
#include <netinet/tcp_var.h>
51
52
#include <vm/uma.h>
53
54
/*
55
* Function prototype for our helper hook (man 9 hhook) compatible hook
56
* function.
57
*/
58
static int example_hook(int hhook_type, int hhook_id, void *udata,
59
void *ctx_data, void *hdata, struct osd *hosd);
60
61
/*
62
* Our per-connection persistent data storage struct.
63
*/
64
struct example {
65
uint32_t est_in_count;
66
uint32_t est_out_count;
67
};
68
69
/*
70
* Fill in the required bits of our module's struct helper (defined in
71
* <sys/module_khelp.h>).
72
*
73
* - Our helper will be storing persistent state for each TCP connection, so we
74
* request the use the Object Specific Data (OSD) feature from the framework by
75
* setting the HELPER_NEEDS_OSD flag.
76
*
77
* - Our helper is related to the TCP subsystem, so tell the Khelp framework
78
* this by setting an appropriate class for the module. When a new TCP
79
* connection is created, the Khelp framework takes care of associating helper
80
* modules of the appropriate class with the new connection.
81
*/
82
struct helper example_helper = {
83
.h_flags = HELPER_NEEDS_OSD,
84
.h_classes = HELPER_CLASS_TCP
85
};
86
87
/*
88
* Set which helper hook points our module wants to hook by creating an array of
89
* hookinfo structs (defined in <sys/hhook.h>). We hook the TCP established
90
* inbound/outbound hook points (TCP hhook points are defined in
91
* <netinet/tcp_var.h>) with our example_hook() function. We don't require a user
92
* data pointer to be passed to our hook function when called, so we set it to
93
* NULL.
94
*/
95
struct hookinfo example_hooks[] = {
96
{
97
.hook_type = HHOOK_TYPE_TCP,
98
.hook_id = HHOOK_TCP_EST_IN,
99
.hook_udata = NULL,
100
.hook_func = &example_hook
101
},
102
{
103
.hook_type = HHOOK_TYPE_TCP,
104
.hook_id = HHOOK_TCP_EST_OUT,
105
.hook_udata = NULL,
106
.hook_func = &example_hook
107
}
108
};
109
110
/*
111
* Very simple helper hook function. Here's a quick run through the arguments:
112
*
113
* - hhook_type and hhook_id are useful if you use a single function with many
114
* hook points and want to know which hook point called the function.
115
*
116
* - udata will be NULL, because we didn't elect to pass a pointer in either of
117
* the hookinfo structs we instantiated above in the example_hooks array.
118
*
119
* - ctx_data contains context specific data from the hook point call site. The
120
* data type passed is subsystem dependent. In the case of TCP, the hook points
121
* pass a pointer to a "struct tcp_hhook_data" (defined in <netinet/tcp_var.h>).
122
*
123
* - hdata is a pointer to the persistent per-object storage for our module. The
124
* pointer is allocated automagically by the Khelp framework when the connection
125
* is created, and comes from a dedicated UMA zone. It will never be NULL.
126
*
127
* - hosd can be used with the Khelp framework's khelp_get_osd() function to
128
* access data belonging to a different Khelp module.
129
*/
130
static int
131
example_hook(int hhook_type, int hhook_id, void *udata, void *ctx_data,
132
void *hdata, struct osd *hosd)
133
{
134
struct example *data;
135
136
data = hdata;
137
138
if (hhook_id == HHOOK_TCP_EST_IN)
139
data->est_in_count++;
140
else if (hhook_id == HHOOK_TCP_EST_OUT)
141
data->est_out_count++;
142
143
return (0);
144
}
145
146
/*
147
* We use a convenient macro which handles registering our module with the Khelp
148
* framework. Note that Khelp modules which set the HELPER_NEEDS_OSD flag (i.e.
149
* require persistent per-object storage) must use the KHELP_DECLARE_MOD_UMA()
150
* macro. If you don't require per-object storage, use the KHELP_DECLARE_MOD()
151
* macro instead.
152
*/
153
KHELP_DECLARE_MOD_UMA(example, &example_helper, example_hooks, 1,
154
sizeof(struct example), NULL, NULL);
155
156