source: rtems-libbsd/freebsd/contrib/pf/pfctl/pfctl_radix.c @ 709fbfa

4.11
Last change on this file since 709fbfa was 4831944, checked in by Christian Mauderer <Christian.Mauderer@…>, on 07/05/16 at 14:31:43

pfctl: Adapt for RTEMS.

  • Property mode set to 100644
File size: 12.8 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*      $OpenBSD: pfctl_radix.c,v 1.27 2005/05/21 21:03:58 henning Exp $ */
4
5/*
6 * Copyright (c) 2002 Cedric Berger
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 *    - Redistributions of source code must retain the above copyright
14 *      notice, this list of conditions and the following disclaimer.
15 *    - Redistributions in binary form must reproduce the above
16 *      copyright notice, this list of conditions and the following
17 *      disclaimer in the documentation and/or other materials provided
18 *      with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifdef __rtems__
36#include <machine/rtems-bsd-program.h>
37#endif /* __rtems__ */
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD$");
40
41#include <rtems/bsd/sys/types.h>
42#include <sys/ioctl.h>
43#include <sys/socket.h>
44
45#include <net/if.h>
46#include <net/pfvar.h>
47
48#include <errno.h>
49#include <string.h>
50#include <ctype.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <limits.h>
54#ifdef __rtems__
55#define SIZE_T_MAX SIZE_MAX
56#endif /* __rtems__ */
57#include <err.h>
58
59#include "pfctl.h"
60
61#define BUF_SIZE 256
62
63extern int dev;
64
65static int       pfr_next_token(char buf[], FILE *);
66
67
68int
69pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
70{
71        struct pfioc_table io;
72
73        bzero(&io, sizeof io);
74        io.pfrio_flags = flags;
75        if (filter != NULL)
76                io.pfrio_table = *filter;
77        if (ioctl(dev, DIOCRCLRTABLES, &io))
78                return (-1);
79        if (ndel != NULL)
80                *ndel = io.pfrio_ndel;
81        return (0);
82}
83
84int
85pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
86{
87        struct pfioc_table io;
88
89        if (size < 0 || (size && tbl == NULL)) {
90                errno = EINVAL;
91                return (-1);
92        }
93        bzero(&io, sizeof io);
94        io.pfrio_flags = flags;
95        io.pfrio_buffer = tbl;
96        io.pfrio_esize = sizeof(*tbl);
97        io.pfrio_size = size;
98        if (ioctl(dev, DIOCRADDTABLES, &io))
99                return (-1);
100        if (nadd != NULL)
101                *nadd = io.pfrio_nadd;
102        return (0);
103}
104
105int
106pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
107{
108        struct pfioc_table io;
109
110        if (size < 0 || (size && tbl == NULL)) {
111                errno = EINVAL;
112                return (-1);
113        }
114        bzero(&io, sizeof io);
115        io.pfrio_flags = flags;
116        io.pfrio_buffer = tbl;
117        io.pfrio_esize = sizeof(*tbl);
118        io.pfrio_size = size;
119        if (ioctl(dev, DIOCRDELTABLES, &io))
120                return (-1);
121        if (ndel != NULL)
122                *ndel = io.pfrio_ndel;
123        return (0);
124}
125
126int
127pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
128        int flags)
129{
130        struct pfioc_table io;
131
132        if (size == NULL || *size < 0 || (*size && tbl == NULL)) {
133                errno = EINVAL;
134                return (-1);
135        }
136        bzero(&io, sizeof io);
137        io.pfrio_flags = flags;
138        if (filter != NULL)
139                io.pfrio_table = *filter;
140        io.pfrio_buffer = tbl;
141        io.pfrio_esize = sizeof(*tbl);
142        io.pfrio_size = *size;
143        if (ioctl(dev, DIOCRGETTABLES, &io))
144                return (-1);
145        *size = io.pfrio_size;
146        return (0);
147}
148
149int
150pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
151        int flags)
152{
153        struct pfioc_table io;
154
155        if (size == NULL || *size < 0 || (*size && tbl == NULL)) {
156                errno = EINVAL;
157                return (-1);
158        }
159        bzero(&io, sizeof io);
160        io.pfrio_flags = flags;
161        if (filter != NULL)
162                io.pfrio_table = *filter;
163        io.pfrio_buffer = tbl;
164        io.pfrio_esize = sizeof(*tbl);
165        io.pfrio_size = *size;
166        if (ioctl(dev, DIOCRGETTSTATS, &io))
167                return (-1);
168        *size = io.pfrio_size;
169        return (0);
170}
171
172int
173pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
174{
175        struct pfioc_table io;
176
177        if (tbl == NULL) {
178                errno = EINVAL;
179                return (-1);
180        }
181        bzero(&io, sizeof io);
182        io.pfrio_flags = flags;
183        io.pfrio_table = *tbl;
184        if (ioctl(dev, DIOCRCLRADDRS, &io))
185                return (-1);
186        if (ndel != NULL)
187                *ndel = io.pfrio_ndel;
188        return (0);
189}
190
191int
192pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
193    int *nadd, int flags)
194{
195        struct pfioc_table io;
196
197        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
198                errno = EINVAL;
199                return (-1);
200        }
201        bzero(&io, sizeof io);
202        io.pfrio_flags = flags;
203        io.pfrio_table = *tbl;
204        io.pfrio_buffer = addr;
205        io.pfrio_esize = sizeof(*addr);
206        io.pfrio_size = size;
207        if (ioctl(dev, DIOCRADDADDRS, &io))
208                return (-1);
209        if (nadd != NULL)
210                *nadd = io.pfrio_nadd;
211        return (0);
212}
213
214int
215pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
216    int *ndel, int flags)
217{
218        struct pfioc_table io;
219
220        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
221                errno = EINVAL;
222                return (-1);
223        }
224        bzero(&io, sizeof io);
225        io.pfrio_flags = flags;
226        io.pfrio_table = *tbl;
227        io.pfrio_buffer = addr;
228        io.pfrio_esize = sizeof(*addr);
229        io.pfrio_size = size;
230        if (ioctl(dev, DIOCRDELADDRS, &io))
231                return (-1);
232        if (ndel != NULL)
233                *ndel = io.pfrio_ndel;
234        return (0);
235}
236
237int
238pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
239    int *size2, int *nadd, int *ndel, int *nchange, int flags)
240{
241        struct pfioc_table io;
242
243        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
244                errno = EINVAL;
245                return (-1);
246        }
247        bzero(&io, sizeof io);
248        io.pfrio_flags = flags;
249        io.pfrio_table = *tbl;
250        io.pfrio_buffer = addr;
251        io.pfrio_esize = sizeof(*addr);
252        io.pfrio_size = size;
253        io.pfrio_size2 = (size2 != NULL) ? *size2 : 0;
254        if (ioctl(dev, DIOCRSETADDRS, &io))
255                return (-1);
256        if (nadd != NULL)
257                *nadd = io.pfrio_nadd;
258        if (ndel != NULL)
259                *ndel = io.pfrio_ndel;
260        if (nchange != NULL)
261                *nchange = io.pfrio_nchange;
262        if (size2 != NULL)
263                *size2 = io.pfrio_size2;
264        return (0);
265}
266
267int
268pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
269    int flags)
270{
271        struct pfioc_table io;
272
273        if (tbl == NULL || size == NULL || *size < 0 ||
274            (*size && addr == NULL)) {
275                errno = EINVAL;
276                return (-1);
277        }
278        bzero(&io, sizeof io);
279        io.pfrio_flags = flags;
280        io.pfrio_table = *tbl;
281        io.pfrio_buffer = addr;
282        io.pfrio_esize = sizeof(*addr);
283        io.pfrio_size = *size;
284        if (ioctl(dev, DIOCRGETADDRS, &io))
285                return (-1);
286        *size = io.pfrio_size;
287        return (0);
288}
289
290int
291pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
292    int flags)
293{
294        struct pfioc_table io;
295
296        if (tbl == NULL || size == NULL || *size < 0 ||
297            (*size && addr == NULL)) {
298                errno = EINVAL;
299                return (-1);
300        }
301        bzero(&io, sizeof io);
302        io.pfrio_flags = flags;
303        io.pfrio_table = *tbl;
304        io.pfrio_buffer = addr;
305        io.pfrio_esize = sizeof(*addr);
306        io.pfrio_size = *size;
307        if (ioctl(dev, DIOCRGETASTATS, &io))
308                return (-1);
309        *size = io.pfrio_size;
310        return (0);
311}
312
313int
314pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
315{
316        struct pfioc_table io;
317
318        if (size < 0 || (size && !tbl)) {
319                errno = EINVAL;
320                return (-1);
321        }
322        bzero(&io, sizeof io);
323        io.pfrio_flags = flags;
324        io.pfrio_buffer = tbl;
325        io.pfrio_esize = sizeof(*tbl);
326        io.pfrio_size = size;
327        if (ioctl(dev, DIOCRCLRTSTATS, &io))
328                return (-1);
329        if (nzero)
330                *nzero = io.pfrio_nzero;
331        return (0);
332}
333
334int
335pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
336    int *nmatch, int flags)
337{
338        struct pfioc_table io;
339
340        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
341                errno = EINVAL;
342                return (-1);
343        }
344        bzero(&io, sizeof io);
345        io.pfrio_flags = flags;
346        io.pfrio_table = *tbl;
347        io.pfrio_buffer = addr;
348        io.pfrio_esize = sizeof(*addr);
349        io.pfrio_size = size;
350        if (ioctl(dev, DIOCRTSTADDRS, &io))
351                return (-1);
352        if (nmatch)
353                *nmatch = io.pfrio_nmatch;
354        return (0);
355}
356
357int
358pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
359    int *nadd, int *naddr, int ticket, int flags)
360{
361        struct pfioc_table io;
362
363        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
364                errno = EINVAL;
365                return (-1);
366        }
367        bzero(&io, sizeof io);
368        io.pfrio_flags = flags;
369        io.pfrio_table = *tbl;
370        io.pfrio_buffer = addr;
371        io.pfrio_esize = sizeof(*addr);
372        io.pfrio_size = size;
373        io.pfrio_ticket = ticket;
374        if (ioctl(dev, DIOCRINADEFINE, &io))
375                return (-1);
376        if (nadd != NULL)
377                *nadd = io.pfrio_nadd;
378        if (naddr != NULL)
379                *naddr = io.pfrio_naddr;
380        return (0);
381}
382
383/* interface management code */
384
385int
386pfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size)
387{
388        struct pfioc_iface io;
389
390        if (size == NULL || *size < 0 || (*size && buf == NULL)) {
391                errno = EINVAL;
392                return (-1);
393        }
394        bzero(&io, sizeof io);
395        if (filter != NULL)
396                if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >=
397                    sizeof(io.pfiio_name)) {
398                        errno = EINVAL;
399                        return (-1);
400                }
401        io.pfiio_buffer = buf;
402        io.pfiio_esize = sizeof(*buf);
403        io.pfiio_size = *size;
404        if (ioctl(dev, DIOCIGETIFACES, &io))
405                return (-1);
406        *size = io.pfiio_size;
407        return (0);
408}
409
410/* buffer management code */
411
412#ifndef __rtems__
413size_t buf_esize[PFRB_MAX] = { 0,
414#else /* __rtems__ */
415const size_t buf_esize[PFRB_MAX] = { 0,
416#endif /* __rtems__ */
417        sizeof(struct pfr_table), sizeof(struct pfr_tstats),
418        sizeof(struct pfr_addr), sizeof(struct pfr_astats),
419        sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e)
420};
421
422/*
423 * add one element to the buffer
424 */
425int
426pfr_buf_add(struct pfr_buffer *b, const void *e)
427{
428        size_t bs;
429
430        if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX ||
431            e == NULL) {
432                errno = EINVAL;
433                return (-1);
434        }
435        bs = buf_esize[b->pfrb_type];
436        if (b->pfrb_size == b->pfrb_msize)
437                if (pfr_buf_grow(b, 0))
438                        return (-1);
439        memcpy(((caddr_t)b->pfrb_caddr) + bs * b->pfrb_size, e, bs);
440        b->pfrb_size++;
441        return (0);
442}
443
444/*
445 * return next element of the buffer (or first one if prev is NULL)
446 * see PFRB_FOREACH macro
447 */
448void *
449pfr_buf_next(struct pfr_buffer *b, const void *prev)
450{
451        size_t bs;
452
453        if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX)
454                return (NULL);
455        if (b->pfrb_size == 0)
456                return (NULL);
457        if (prev == NULL)
458                return (b->pfrb_caddr);
459        bs = buf_esize[b->pfrb_type];
460        if ((((caddr_t)prev)-((caddr_t)b->pfrb_caddr)) / bs >= b->pfrb_size-1)
461                return (NULL);
462        return (((caddr_t)prev) + bs);
463}
464
465/*
466 * minsize:
467 *    0: make the buffer somewhat bigger
468 *    n: make room for "n" entries in the buffer
469 */
470int
471pfr_buf_grow(struct pfr_buffer *b, int minsize)
472{
473        caddr_t p;
474        size_t bs;
475
476        if (b == NULL || b->pfrb_type <= 0 || b->pfrb_type >= PFRB_MAX) {
477                errno = EINVAL;
478                return (-1);
479        }
480        if (minsize != 0 && minsize <= b->pfrb_msize)
481                return (0);
482        bs = buf_esize[b->pfrb_type];
483        if (!b->pfrb_msize) {
484                if (minsize < 64)
485                        minsize = 64;
486                b->pfrb_caddr = calloc(bs, minsize);
487                if (b->pfrb_caddr == NULL)
488                        return (-1);
489                b->pfrb_msize = minsize;
490        } else {
491                if (minsize == 0)
492                        minsize = b->pfrb_msize * 2;
493                if (minsize < 0 || minsize >= SIZE_T_MAX / bs) {
494                        /* msize overflow */
495                        errno = ENOMEM;
496                        return (-1);
497                }
498                p = realloc(b->pfrb_caddr, minsize * bs);
499                if (p == NULL)
500                        return (-1);
501                bzero(p + b->pfrb_msize * bs, (minsize - b->pfrb_msize) * bs);
502                b->pfrb_caddr = p;
503                b->pfrb_msize = minsize;
504        }
505        return (0);
506}
507
508/*
509 * reset buffer and free memory.
510 */
511void
512pfr_buf_clear(struct pfr_buffer *b)
513{
514        if (b == NULL)
515                return;
516        if (b->pfrb_caddr != NULL)
517                free(b->pfrb_caddr);
518        b->pfrb_caddr = NULL;
519        b->pfrb_size = b->pfrb_msize = 0;
520}
521
522int
523pfr_buf_load(struct pfr_buffer *b, char *file, int nonetwork,
524    int (*append_addr)(struct pfr_buffer *, char *, int))
525{
526        FILE    *fp;
527        char     buf[BUF_SIZE];
528        int      rv;
529
530        if (file == NULL)
531                return (0);
532        if (!strcmp(file, "-"))
533                fp = stdin;
534        else {
535                fp = pfctl_fopen(file, "r");
536                if (fp == NULL)
537                        return (-1);
538        }
539        while ((rv = pfr_next_token(buf, fp)) == 1)
540                if (append_addr(b, buf, nonetwork)) {
541                        rv = -1;
542                        break;
543                }
544        if (fp != stdin)
545                fclose(fp);
546        return (rv);
547}
548
549#ifdef __rtems__
550static char     next_ch = ' ';
551#endif /* __rtems__ */
552int
553pfr_next_token(char buf[BUF_SIZE], FILE *fp)
554{
555#ifndef __rtems__
556        static char     next_ch = ' ';
557#endif /* __rtems__ */
558        int             i = 0;
559
560        for (;;) {
561                /* skip spaces */
562                while (isspace(next_ch) && !feof(fp))
563                        next_ch = fgetc(fp);
564                /* remove from '#' until end of line */
565                if (next_ch == '#')
566                        while (!feof(fp)) {
567                                next_ch = fgetc(fp);
568                                if (next_ch == '\n')
569                                        break;
570                        }
571                else
572                        break;
573        }
574        if (feof(fp)) {
575                next_ch = ' ';
576                return (0);
577        }
578        do {
579                if (i < BUF_SIZE)
580                        buf[i++] = next_ch;
581                next_ch = fgetc(fp);
582        } while (!feof(fp) && !isspace(next_ch));
583        if (i >= BUF_SIZE) {
584                errno = EINVAL;
585                return (-1);
586        }
587        buf[i] = '\0';
588        return (1);
589}
590
591char *
592pfr_strerror(int errnum)
593{
594        switch (errnum) {
595        case ESRCH:
596                return "Table does not exist";
597        case ENOENT:
598                return "Anchor or Ruleset does not exist";
599        default:
600                return strerror(errnum);
601        }
602}
603#ifdef __rtems__
604#include "pfctl_radix-data.h"
605#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.