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