Coverage Report

Created: 2026-09-27 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open5gs/lib/ipfw/glue.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
 * SUCH DAMAGE.
24
 */
25
/*
26
 * $Id: glue.h 8327 2011-03-22 17:01:35Z marta $
27
 *
28
 * glue code to adapt the FreeBSD version to linux and windows,
29
 * userland and kernel.
30
 * This is included before any other headers, so we do not have
31
 * a chance to override any #define that should appear in other
32
 * headers.
33
 * First handle headers for userland and kernel. Then common code
34
 * (including headers that require a specific order of inclusion),
35
 * then the user- and kernel- specific parts.
36
 */
37
 
38
#ifndef _GLUE_H
39
#define _GLUE_H
40
41
/*
42
 * common definitions to allow portability
43
 */
44
#ifndef __FBSDID
45
#define __FBSDID(x) struct __hack
46
#endif  /* FBSDID */
47
48
#include <stdint.h> /* linux needs it in addition to sys/types.h */
49
#include <sys/types.h>  /* for size_t */
50
51
#define true 1    /* stdbool */
52
#ifdef _KERNEL    /* prevent a warning */
53
#undef _KERNEL
54
#include <sys/ioctl.h>
55
#include <sys/time.h>
56
#include <errno.h>  /* we want errno */
57
#define _KERNEL
58
#else
59
#include <sys/ioctl.h>
60
#endif
61
62
#include <time.h>
63
#ifndef USERSPACE
64
#include <netinet/ether.h>
65
#endif
66
67
68
/*----- */
69
70
/* ipfw2.c - from timeconv.h */
71
static __inline time_t
72
_long_to_time(long tlong)
73
0
{
74
#if 0 /* modified by acetcom */
75
    if (sizeof(long) == sizeof(__int32_t))
76
        return((time_t)(__int32_t)(tlong));
77
#else
78
0
    if (sizeof(long) == sizeof(int32_t))
79
0
        return((time_t)(int32_t)(tlong));
80
0
#endif
81
0
    return((time_t)tlong);
82
0
}
Unexecuted instantiation: ogs-ipfw.c:_long_to_time
Unexecuted instantiation: ipfw2.c:_long_to_time
Unexecuted instantiation: dummynet.c:_long_to_time
Unexecuted instantiation: ipv6.c:_long_to_time
Unexecuted instantiation: tables.c:_long_to_time
Unexecuted instantiation: expand_number.c:_long_to_time
Unexecuted instantiation: humanize_number.c:_long_to_time
Unexecuted instantiation: glue.c:_long_to_time
83
84
#define min(a, b) ((a) < (b) ? (a) : (b) )  // radix.c
85
/*
86
 * debugging macros from ip_dn_private.h
87
 */
88
#include <sys/time.h>
89
#include <stdio.h>
90
extern char *strrchr(const char *, int);
91
0
static inline const char *xyz(const char *s) {
92
0
  static char buf[128];
93
0
  struct timeval t;
94
0
  const char *ret = strrchr(s, '/');
95
0
  if (ret) s = ret + 1;
96
0
  gettimeofday(&t, NULL);
97
0
  buf[sizeof(buf) - 1] = '\0';
98
0
  snprintf(buf, sizeof(buf), "[%4d.%06d] %s",
99
0
    (int)(t.tv_sec % 1000), (int)(t.tv_usec), s);
100
0
  return buf;
101
0
}
Unexecuted instantiation: ogs-ipfw.c:xyz
Unexecuted instantiation: ipfw2.c:xyz
Unexecuted instantiation: dummynet.c:xyz
Unexecuted instantiation: ipv6.c:xyz
Unexecuted instantiation: tables.c:xyz
Unexecuted instantiation: expand_number.c:xyz
Unexecuted instantiation: humanize_number.c:xyz
Unexecuted instantiation: glue.c:xyz
102
103
0
#define ND(fmt, ...) do {} while (0)
104
#define D1(fmt, ...) do {} while (0)
105
0
#define D(fmt, ...) fprintf(stderr, "%s:%-10s [%d] " fmt "\n",        \
106
0
          xyz(__FILE__), __FUNCTION__, __LINE__,  ## __VA_ARGS__)
107
108
/* Rate limited version of "D", lps indicates how many per second */
109
#define RD(lps, format, ...)                                    \
110
    do {                                                        \
111
        static int t0, __cnt;                                   \
112
        struct timeval __xxts;                                  \
113
        gettimeofday(&__xxts, NULL);                            \
114
        if (t0 != __xxts.tv_sec) {                              \
115
            t0 = __xxts.tv_sec;                                 \
116
            __cnt = 0;                                          \
117
        }                                                       \
118
        if (__cnt++ < lps) {                                    \
119
            D(format, ##__VA_ARGS__);                           \
120
        }                                                       \
121
    } while (0)
122
123
#define DX(lev, fmt, ...) do {              \
124
        if (dn_cfg.debug > lev) D(fmt, ## __VA_ARGS__); } while (0)
125
/* end debugging macros */
126
127
128
/*
129
 * sbin/ipfw on non-freebsd platform
130
 */
131
#ifdef NEED_STRTONUM
132
/* prototypes from libutil */
133
/* humanize_number(3) */
134
0
#define HN_DECIMAL              0x01
135
0
#define HN_NOSPACE              0x02
136
0
#define HN_B                    0x04
137
0
#define HN_DIVISOR_1000         0x08
138
0
#define HN_IEC_PREFIXES         0x10
139
140
0
#define HN_GETSCALE             0x10
141
0
#define HN_AUTOSCALE            0x20
142
143
144
int humanize_number(char *_buf, size_t _len, int64_t _number,
145
            const char *_suffix, int _scale, int _flags);
146
int expand_number(const char *buf, uint64_t *num);
147
148
149
long long
150
strtonum(const char *nptr, long long minval, long long maxval,
151
 const char **errstr);
152
#ifndef __APPLE__
153
int ishexnumber(int c);
154
#endif
155
#endif /* NEED_STRTONUM */
156
157
#ifdef NEED_SYSCTLBYNAME /* and other linux calls */
158
int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
159
        void *newp, size_t newlen);
160
#define setprogname(x)  /* not present in linux */
161
 
162
extern int optreset;    /* not present in linux */
163
 
164
long long int strtonum(const char *nptr, long long minval,
165
        long long maxval, const char **errstr);
166
167
168
struct ether_addr;
169
struct ether_addr * ether_aton(const char *a);
170
171
0
#define ICMP6_MAXTYPE   201
172
#define __u6_addr       in6_u
173
#define in6_u __in6_u   /* missing type for ipv6 (linux 2.6.28) */
174
175
176
#define __u6_addr32     u6_addr32
177
/* on freebsd sys/socket.h pf specific */
178
#define NET_RT_IFLIST   3               /* survey interface list */
179
180
#define RTM_VERSION     5       /* Up the ante and ignore older versions */
181
182
#endif // NEED_SYSCTLBYNAME
183
184
#ifdef NEED_SIN_LEN
185
/*
186
 * linux at least does not have sin_len and sin6_len, so we remap
187
 * to some safe fields (check use of sin6_flowinfo XXX)
188
 */
189
0
#define sin_len sin_zero[0]
190
0
#define sin6_len sin6_flowinfo
191
#endif /* NEED_SIN_LEN */
192
193
#ifdef NEED_ROUNDUP2 /* in freensd is in sys/param.h */
194
/* round up to the next power of 2 (y) */
195
0
#define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
196
#endif // NEED_ROUNDUP2
197
198
/* possibly redundant, does not harm */
199
size_t strlcpy(char * dst, const char * src, size_t siz);
200
201
/*
202
 * Part 2: common userland and kernel definitions
203
 */
204
205
#define ICMP6_DST_UNREACH_NOROUTE       0       /* no route to destination */
206
#define ICMP6_DST_UNREACH_ADMIN         1       /* administratively prohibited */
207
#define ICMP6_DST_UNREACH_ADDR          3       /* address unreachable */
208
#define ICMP6_DST_UNREACH_NOPORT        4       /* port unreachable */
209
210
/*
211
 * linux: sysctl are mapped into /sys/module/ipfw_mod parameters
212
 * windows: they are emulated via get/setsockopt
213
 */
214
#define CTLFLAG_RD  1
215
#define CTLFLAG_RDTUN 1
216
#define CTLFLAG_RW  2
217
#define CTLFLAG_SECURE3 0 /* unsupported */
218
#define CTLFLAG_VNET    0 /* unsupported */
219
220
/* if needed, queue.h must be included here after list.h */
221
222
/*
223
 * our own struct thread
224
 */
225
struct thread { /* ip_fw_sockopt */
226
        void *sopt_td;
227
        void *td_ucred;
228
};
229
230
enum sopt_dir { SOPT_GET, SOPT_SET };
231
232
struct  sockopt {
233
        enum    sopt_dir sopt_dir; /* is this a get or a set? */
234
        int     sopt_level;     /* second arg of [gs]etsockopt */
235
        int     sopt_name;      /* third arg of [gs]etsockopt */
236
  void   *sopt_val;       /* fourth arg of [gs]etsockopt */
237
  size_t  sopt_valsize;   /* (almost) fifth arg of [gs]etsockopt */
238
  struct  thread *sopt_td; /* calling thread or null if kernel */
239
};
240
241
242
/*
243
 * List of values used for set/getsockopt options.
244
 * The base value on FreeBSD is defined as a macro,
245
 * if not available we will use our own enum.
246
 * The TABLE_BASE value is used in the kernel.
247
 */
248
0
#define _IPFW_SOCKOPT_BASE  100  /* 40 on freebsd */
249
#define IP_FW_TABLE_ADD   (_IPFW_SOCKOPT_BASE +   0)
250
#define IP_FW_TABLE_DEL   (_IPFW_SOCKOPT_BASE +   1)
251
#define IP_FW_TABLE_FLUSH (_IPFW_SOCKOPT_BASE +   2)
252
#define IP_FW_TABLE_GETSIZE (_IPFW_SOCKOPT_BASE +   3)
253
#define IP_FW_TABLE_LIST  (_IPFW_SOCKOPT_BASE +   4)
254
#define IP_FW_DYN_GET   (_IPFW_SOCKOPT_BASE +   5)
255
256
0
#define IP_FW3      (_IPFW_SOCKOPT_BASE +   8)
257
0
#define IP_DUMMYNET3    (_IPFW_SOCKOPT_BASE +   9)
258
259
0
#define IP_FW_ADD   (_IPFW_SOCKOPT_BASE +  10)
260
#define IP_FW_DEL   (_IPFW_SOCKOPT_BASE +  11)
261
#define IP_FW_FLUSH   (_IPFW_SOCKOPT_BASE +  12)
262
#define IP_FW_ZERO    (_IPFW_SOCKOPT_BASE +  13)
263
0
#define IP_FW_GET   (_IPFW_SOCKOPT_BASE +  14)
264
#define IP_FW_RESETLOG    (_IPFW_SOCKOPT_BASE +  15)
265
266
#define IP_FW_NAT_CFG   (_IPFW_SOCKOPT_BASE +  16)
267
0
#define IP_FW_NAT_DEL   (_IPFW_SOCKOPT_BASE +  17)
268
0
#define IP_FW_NAT_GET_CONFIG  (_IPFW_SOCKOPT_BASE +  18)
269
0
#define IP_FW_NAT_GET_LOG (_IPFW_SOCKOPT_BASE +  19)
270
271
#define IP_DUMMYNET_CONFIGURE (_IPFW_SOCKOPT_BASE +  20)
272
#define IP_DUMMYNET_DEL   (_IPFW_SOCKOPT_BASE +  21)
273
#define IP_DUMMYNET_FLUSH (_IPFW_SOCKOPT_BASE +  22)
274
        /* 63 is missing */
275
0
#define IP_DUMMYNET_GET         (_IPFW_SOCKOPT_BASE + 24)
276
#define _IPFW_SOCKOPT_END (_IPFW_SOCKOPT_BASE + 25)
277
278
/*
279
 * Part 3: userland stuff for linux/windows
280
 */
281
282
283
/*
284
 * now remap functions for userland or linux kernel etc.
285
 */
286
#ifdef USERSPACE
287
/*
288
 * definitions used when the programs communicate through userspace.
289
 * We need to define the socket and addresses used to talk, and
290
 * the userland side must also remap socket() and [gs]etsockopt()
291
 * to appropriate wrappers.
292
 */
293
294
0
#define LOCALADDR       "127.0.0.1"
295
0
#define IPFW_PORT       5555
296
297
#ifndef KERNEL_SIDE
298
#ifdef _KERNEL
299
#error _KERNEL defined in user space
300
#endif
301
int do_connect(const char *addr, int port);
302
#include <sys/socket.h> /* for socklen_t */
303
304
0
#define socket(a, b, c) do_connect(LOCALADDR, IPFW_PORT)
305
0
#define setsockopt      setsockopt2
306
0
#define getsockopt      getsockopt2
307
int getsockopt2(int s, int lev, int optname, void *optval, socklen_t *optlen);
308
int setsockopt2(int s, int lev, int optname, void *optval, socklen_t optlen);
309
#endif /* KERNEL_SIDE */
310
311
#endif  /* USERSPACE */
312
313
/*
314
 * Part 5: windows specific stuff and sysctl emulation
315
 */
316
317
/*******************
318
* SYSCTL emulation *
319
********************/
320
#ifdef EMULATE_SYSCTL
321
322
/* this needs to be here, as it is part of the user-kernel messages */
323
/* flag is set with the last 2 bits for access, as defined in glue.h
324
 * and the rest for type
325
 */
326
enum {
327
  SYSCTLTYPE_INT    = 0,
328
  SYSCTLTYPE_UINT   = 1,
329
  SYSCTLTYPE_SHORT  = 2,
330
  SYSCTLTYPE_USHORT = 3,
331
  SYSCTLTYPE_LONG   = 4,
332
  SYSCTLTYPE_ULONG  = 5,
333
  SYSCTLTYPE_STRING = 6,
334
335
  /* the following are SYSCTL_PROC equivalents of the above,
336
   * where the SYSCTLTYPE is shifted 2 bits,
337
   * and SYSCTLTYPE_PROC is set
338
   */
339
  SYSCTLTYPE_PROC   = 0x100,
340
  CTLTYPE_INT   = (0x100 | (0<<2)),
341
  CTLTYPE_UINT    = (0x100 | (1<<2)),
342
  CTLTYPE_LONG    = (0x100 | (4<<2)),
343
  CTLTYPE_ULONG   = (0x100 | (5<<2))
344
};
345
346
struct sysctlhead {
347
  uint32_t blocklen; //total size of the entry
348
  uint32_t namelen; //strlen(name) + '\0'
349
  uint32_t flags; //type and access
350
  uint32_t datalen;
351
};
352
353
354
#endif /* EMULATE_SYSCTL */
355
356
#ifndef __FreeBSD__
357
int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
358
         size_t newlen);
359
360
#define test_bit(ix, pData)     ((*pData) & (1<<(ix)))
361
#define __set_bit(ix, pData)    (*pData) |= (1<<(ix))
362
#define __clear_bit(ix, pData)  (*pData) &= ~(1<<(ix))
363
364
static inline int fls(int _n)
365
0
{
366
0
  unsigned int n = _n;
367
0
        int i = 0;
368
0
        for (i = 0; n > 0; n >>= 1, i++)
369
0
                ;
370
0
        return i;
371
0
}
Unexecuted instantiation: ogs-ipfw.c:fls
Unexecuted instantiation: ipfw2.c:fls
Unexecuted instantiation: dummynet.c:fls
Unexecuted instantiation: ipv6.c:fls
Unexecuted instantiation: tables.c:fls
Unexecuted instantiation: expand_number.c:fls
Unexecuted instantiation: humanize_number.c:fls
Unexecuted instantiation: glue.c:fls
372
373
static inline unsigned long __fls(unsigned long word)
374
0
{
375
0
        return fls(word) - 1;
376
0
}
Unexecuted instantiation: ogs-ipfw.c:__fls
Unexecuted instantiation: ipfw2.c:__fls
Unexecuted instantiation: dummynet.c:__fls
Unexecuted instantiation: ipv6.c:__fls
Unexecuted instantiation: tables.c:__fls
Unexecuted instantiation: expand_number.c:__fls
Unexecuted instantiation: humanize_number.c:__fls
Unexecuted instantiation: glue.c:__fls
377
378
379
#endif /* !FreeBSD */
380
381
#ifdef KERNEL_SIDE
382
/* sys/counter.h , to be moved to a file */
383
typedef uint64_t *counter_u64_t; // XXX kernel
384
static inline void counter_u64_add(counter_u64_t c, int64_t v)
385
{
386
  *c += v;
387
}
388
static inline void counter_u64_zero(counter_u64_t c)
389
{
390
  *c = 0;
391
}
392
static inline uint64_t counter_u64_fetch(counter_u64_t c)
393
{
394
  return *c;
395
}
396
397
struct rm_priotracker {
398
};
399
400
#define vslock(_a, _b)  (0)
401
#define vsunlock(_a, _b)
402
403
typedef uint64_t  u_register_t; // XXX not on osx ?
404
405
typedef uintptr_t eventhandler_tag;
406
#define EVENTHANDLER_REGISTER(_a, _b, ...)  (uintptr_t)_b;
407
#define EVENTHANDLER_DEREGISTER(_a, _b, ...)  (void)_b;
408
409
// XXX this needs to be completed
410
#define if_name(_ifp) (_ifp->if_xname)
411
#define ifunit_ref(_n)  NULL  // XXX
412
#define if_rele(_n)
413
414
#define rtalloc1_fib(_a, ...) NULL
415
#define rt_key(_a)  NULL
416
#define rt_mask(_a) NULL
417
#define RTFREE_LOCKED(_a) ((void)NULL)
418
struct rtentry {
419
};
420
#define rt_tables_get_rnh(_a, _b) NULL
421
422
#endif /* KERNEL_SIDE */
423
424
#ifdef _KERNEL
425
/* XXX kernel support */
426
/* on freebsd net/if.h XXX used */
427
#ifdef linux
428
#define div64(a,b) (((int64_t)a)/((int64_t)b))
429
#define LINUX_VERSION_CODE  30003
430
#define KERNEL_VERSION(a,b,c) (a*10000+b*100 + c)
431
#define __printflike(a,b)
432
#endif /* linux */
433
434
#endif /* _KERNEL */
435
436
#ifndef __FreeBSD__
437
#ifndef IFNAMSIZ
438
#define IFNAMSIZ  16
439
#endif
440
#include "missing.h"
441
442
struct if_data {
443
        /* ... */
444
        u_long ifi_mtu; /* maximum transmission unit */
445
};
446
447
#endif
448
449
#ifdef __APPLE__
450
#include <sys/socketvar.h>  // need in kernel
451
452
/* needed both in kernel and userspace */
453
struct if_data64 {  // XXX Darwin version
454
        /* ... */
455
        u_long ifi_mtu; /* maximum transmission unit */
456
};
457
458
struct net_event_data {
459
};
460
461
struct in_addr;
462
#endif /* __APPLE__ */
463
464
0
#define __PAST_END(v, idx)  v[idx]
465
466
/*
467
 * a fast copy routine
468
 */
469
#include <strings.h>
470
// XXX only for multiples of 64 bytes, non overlapped.
471
static inline void
472
_pkt_copy(const void *_src, void *_dst, int l)
473
0
{
474
0
        const uint64_t *src = _src;
475
0
        uint64_t *dst = _dst;
476
0
#define likely(x)       __builtin_expect(!!(x), 1)
477
0
#define unlikely(x)       __builtin_expect(!!(x), 0)
478
0
        if (unlikely(l >= 1024)) {
479
0
                bcopy(src, dst, l);
480
0
                return;
481
0
        }
482
0
        for (; l > 0; l-=64) {
483
0
                *dst++ = *src++;
484
0
                *dst++ = *src++;
485
0
                *dst++ = *src++;
486
0
                *dst++ = *src++;
487
0
                *dst++ = *src++;
488
0
                *dst++ = *src++;
489
0
                *dst++ = *src++;
490
0
                *dst++ = *src++;
491
0
        }
492
0
}
Unexecuted instantiation: ogs-ipfw.c:_pkt_copy
Unexecuted instantiation: ipfw2.c:_pkt_copy
Unexecuted instantiation: dummynet.c:_pkt_copy
Unexecuted instantiation: ipv6.c:_pkt_copy
Unexecuted instantiation: tables.c:_pkt_copy
Unexecuted instantiation: expand_number.c:_pkt_copy
Unexecuted instantiation: humanize_number.c:_pkt_copy
Unexecuted instantiation: glue.c:_pkt_copy
493
494
#endif /* !_GLUE_H */