67636f71f827c2458f563c2e673ba2058c70a303
[metze/wireshark/wip.git] / epan / ftypes / ftype-ipv4.c
1 /*
2  * $Id: ftype-ipv4.c,v 1.8 2002/02/05 22:50:17 guy Exp $
3  *
4  * Ethereal - Network traffic analyzer
5  * By Gerald Combs <gerald@ethereal.com>
6  * Copyright 2001 Gerald Combs
7  * 
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <string.h>
28
29 #include <ftypes-int.h>
30 #include <epan/ipv4.h>
31 #include <epan/resolv.h>
32
33
34 static void
35 set_integer(fvalue_t *fv, guint32 value)
36 {
37         ipv4_addr_set_net_order_addr(&(fv->value.ipv4), value);
38         ipv4_addr_set_netmask_bits(&(fv->value.ipv4), 32);
39 }
40
41 static gpointer
42 value_get(fvalue_t *fv)
43 {
44         return &(fv->value.ipv4);
45 }
46
47 static gboolean
48 val_from_string(fvalue_t *fv, char *s, LogFunc logfunc)
49 {
50         guint32 addr;
51         unsigned int nmask_bits;
52
53         char *has_slash, *s_copy = NULL;
54         char *net_str, *addr_str;
55         fvalue_t *nmask_fvalue;
56
57         /* Look for CIDR: Is there a single slash in the string? */
58         has_slash = strchr(s, '/');
59         if (has_slash) {
60                 /* Make a copy of the string and use strtok() to
61                  * get the address portion. */
62                 s_copy = g_strdup(s);
63                 addr_str = strtok(s_copy, "/");
64
65                 /* I just checked for slash! I shouldn't get NULL here.
66                  * Double check just in case. */
67                 if (!addr_str) {
68                         logfunc("Unexpected strtok() error parsing IP address: %s",
69                             s_copy);
70                         g_free(s_copy);
71                         return FALSE;
72                 }
73         }
74         else {
75                 addr_str = s;
76         }
77
78         if (!get_host_ipaddr(addr_str, &addr)) {
79                 logfunc("\"%s\" is not a valid hostname or IPv4 address.",
80                     addr_str);
81                 if (has_slash) {
82                         g_free(s_copy);
83                 }
84                 return FALSE;
85         }
86
87         ipv4_addr_set_host_order_addr(&(fv->value.ipv4), addr);
88
89         /* If CIDR, get netmask bits. */
90         if (has_slash) {
91                 net_str = strtok(NULL, "/");
92                 /* I checked for slash! I shouldn't get NULL here.
93                  * Double check just in case. */
94                 if (!net_str) {
95                         logfunc("Unexpected strtok() error parsing netmask: %s",
96                             s_copy);
97                         g_free(s_copy);
98                         return FALSE;
99                 }
100
101                 nmask_fvalue = fvalue_from_string(FT_UINT32, net_str, logfunc);
102                 g_free(s_copy);
103                 if (!nmask_fvalue) {
104                         return FALSE;
105                 }
106                 nmask_bits = fvalue_get_integer(nmask_fvalue);
107                 fvalue_free(nmask_fvalue);
108
109                 if (nmask_bits > 32) {
110                         logfunc("Netmask bits in a CIDR IPv4 address should be <= 32, not %u",
111                                         nmask_bits);
112                         return FALSE;
113                 }
114                 ipv4_addr_set_netmask_bits(&fv->value.ipv4, nmask_bits);
115         }
116         else {
117                 /* Not CIDR; mask covers entire address. */
118                 ipv4_addr_set_netmask_bits(&(fv->value.ipv4), 32);
119         }
120
121         return TRUE;
122 }
123
124 static gboolean
125 cmp_eq(fvalue_t *a, fvalue_t *b)
126 {
127         return ipv4_addr_eq(&a->value.ipv4, &b->value.ipv4);
128 }
129
130 static gboolean
131 cmp_ne(fvalue_t *a, fvalue_t *b)
132 {
133         return ipv4_addr_ne(&a->value.ipv4, &b->value.ipv4);
134 }
135
136 static gboolean
137 cmp_gt(fvalue_t *a, fvalue_t *b)
138 {
139         return ipv4_addr_gt(&a->value.ipv4, &b->value.ipv4);
140 }
141
142 static gboolean
143 cmp_ge(fvalue_t *a, fvalue_t *b)
144 {
145         return ipv4_addr_ge(&a->value.ipv4, &b->value.ipv4);
146 }
147
148 static gboolean
149 cmp_lt(fvalue_t *a, fvalue_t *b)
150 {
151         return ipv4_addr_lt(&a->value.ipv4, &b->value.ipv4);
152 }
153
154 static gboolean
155 cmp_le(fvalue_t *a, fvalue_t *b)
156 {
157         return ipv4_addr_le(&a->value.ipv4, &b->value.ipv4);
158 }
159
160 void
161 ftype_register_ipv4(void)
162 {
163
164         static ftype_t ipv4_type = {
165                 "FT_IPv4",
166                 "IPv4 address",
167                 4,
168                 NULL,
169                 NULL,
170                 val_from_string,
171
172                 NULL,
173                 set_integer,
174                 NULL,
175
176                 value_get,
177                 NULL,
178                 NULL,
179
180                 cmp_eq,
181                 cmp_ne,
182                 cmp_gt,
183                 cmp_ge,
184                 cmp_lt,
185                 cmp_le,
186
187                 NULL,
188                 NULL,
189         };
190
191         ftype_register(FT_IPv4, &ipv4_type);
192 }