PostgreSQL Source Code: src/backend/utils/adt/mac8.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
23
27#include "utils/fmgrprotos.h"
29
30
31
32
33#define hibits(addr) \
34 ((unsigned long)(((addr)->a<<24) | ((addr)->b<<16) | ((addr)->c<<8) | ((addr)->d)))
35
36#define lobits(addr) \
37 ((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))
38
39static unsigned char hex2_to_uchar(const unsigned char *ptr, bool *badhex);
40
41static const signed char hexlookup[128] = {
42 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
46 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
48 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
50};
51
52
53
54
55
56
57
58static inline unsigned char
60{
61 unsigned char ret;
63
64
65 if (*ptr > 127)
66 goto invalid_input;
67
70 goto invalid_input;
71
73
74
75 ptr++;
76
77 if (*ptr > 127)
78 goto invalid_input;
79
82 goto invalid_input;
83
85
86 return ret;
87
88invalid_input:
89 *badhex = true;
90 return 0;
91}
92
93
94
95
98{
100 Node *escontext = fcinfo->context;
101 const unsigned char *ptr = str;
102 bool badhex = false;
104 unsigned char a = 0,
105 b = 0,
106 c = 0,
107 d = 0,
108 e = 0,
109 f = 0,
110 g = 0,
111 h = 0;
112 int count = 0;
113 unsigned char spacer = '\0';
114
115
116 while (*ptr && isspace(*ptr))
117 ptr++;
118
119
120 while (*ptr && *(ptr + 1))
121 {
122
123
124
125
126
127
128
129 count++;
130
131 switch (count)
132 {
133 case 1:
135 break;
136 case 2:
138 break;
139 case 3:
141 break;
142 case 4:
144 break;
145 case 5:
147 break;
148 case 6:
150 break;
151 case 7:
153 break;
154 case 8:
156 break;
157 default:
158
159 goto fail;
160 }
161
162 if (badhex)
163 goto fail;
164
165
166 ptr += 2;
167
168
169 if (*ptr == ':' || *ptr == '-' || *ptr == '.')
170 {
171
172 if (spacer == '\0')
173 spacer = *ptr;
174
175
176 else if (spacer != *ptr)
177 goto fail;
178
179
180 ptr++;
181 }
182
183
184 if (count == 6 || count == 8)
185 {
186 if (isspace(*ptr))
187 {
188 while (*++ptr && isspace(*ptr));
189
190
191 if (*ptr)
192 goto fail;
193 }
194 }
195 }
196
197
198 if (count == 6)
199 {
200 h = f;
201 g = e;
202 f = d;
203
204 d = 0xFF;
205 e = 0xFE;
206 }
207 else if (count != 8)
208 goto fail;
209
211
215 result->d = d;
217 result->f = f;
218 result->g = g;
219 result->h = h;
220
222
223fail:
225 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
226 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
228}
229
230
231
232
235{
237 char *result;
238
239 result = (char *) palloc(32);
240
241 snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
242 addr->a, addr->b, addr->c, addr->d,
243 addr->e, addr->f, addr->g, addr->h);
244
246}
247
248
249
250
251
252
255{
258
260
264
265 if (buf->len == 6)
266 {
267 addr->d = 0xFF;
268 addr->e = 0xFE;
269 }
270 else
271 {
274 }
275
279
281}
282
283
284
285
288{
291
301
303}
304
305
306
307
308
311{
313 return -1;
315 return 1;
317 return -1;
319 return 1;
320 else
321 return 0;
322}
323
326{
329
331}
332
333
334
335
336
339{
342
344}
345
348{
351
353}
354
357{
360
362}
363
366{
369
371}
372
375{
378
380}
381
384{
387
389}
390
391
392
393
396{
398
400}
401
404{
406
409}
410
411
412
413
416{
419
421 result->a = ~addr->a;
422 result->b = ~addr->b;
423 result->c = ~addr->c;
424 result->d = ~addr->d;
425 result->e = ~addr->e;
426 result->f = ~addr->f;
427 result->g = ~addr->g;
428 result->h = ~addr->h;
429
431}
432
435{
439
441 result->a = addr1->a & addr2->a;
442 result->b = addr1->b & addr2->b;
443 result->c = addr1->c & addr2->c;
444 result->d = addr1->d & addr2->d;
445 result->e = addr1->e & addr2->e;
446 result->f = addr1->f & addr2->f;
447 result->g = addr1->g & addr2->g;
448 result->h = addr1->h & addr2->h;
449
451}
452
455{
459
461 result->a = addr1->a | addr2->a;
462 result->b = addr1->b | addr2->b;
463 result->c = addr1->c | addr2->c;
464 result->d = addr1->d | addr2->d;
465 result->e = addr1->e | addr2->e;
466 result->f = addr1->f | addr2->f;
467 result->g = addr1->g | addr2->g;
468 result->h = addr1->h | addr2->h;
469
471}
472
473
474
475
478{
481
483
487 result->d = 0;
488 result->e = 0;
489 result->f = 0;
490 result->g = 0;
491 result->h = 0;
492
494}
495
496
497
498
501{
504
506
507 result->a = addr->a | 0x02;
515
517}
518
519
520
521
522
525{
528
530
534 result->d = 0xFF;
535 result->e = 0xFE;
539
540
542}
543
546{
549
551
552 if ((addr->d != 0xFF) || (addr->e != 0xFE))
554 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
555 errmsg("macaddr8 data out of range to convert to macaddr"),
556 errhint("Only addresses that have FF and FE as values in the "
557 "4th and 5th bytes from the left, for example "
558 "xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted "
559 "from macaddr8 to macaddr.")));
560
567
569}
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
#define ereport(elevel,...)
#define PG_RETURN_BYTEA_P(x)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_CSTRING(n)
#define PG_GETARG_INT64(n)
#define PG_RETURN_INT32(x)
#define PG_RETURN_BOOL(x)
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
static Datum hash_any(const unsigned char *k, int keylen)
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
static unsigned char hex2_to_uchar(const unsigned char *ptr, bool *badhex)
Datum macaddr8_or(PG_FUNCTION_ARGS)
Datum macaddrtomacaddr8(PG_FUNCTION_ARGS)
Datum macaddr8_out(PG_FUNCTION_ARGS)
static const signed char hexlookup[128]
Datum macaddr8_set7bit(PG_FUNCTION_ARGS)
Datum macaddr8_cmp(PG_FUNCTION_ARGS)
Datum macaddr8tomacaddr(PG_FUNCTION_ARGS)
Datum macaddr8_eq(PG_FUNCTION_ARGS)
static int32 macaddr8_cmp_internal(macaddr8 *a1, macaddr8 *a2)
Datum macaddr8_and(PG_FUNCTION_ARGS)
Datum macaddr8_gt(PG_FUNCTION_ARGS)
Datum macaddr8_recv(PG_FUNCTION_ARGS)
Datum macaddr8_in(PG_FUNCTION_ARGS)
Datum macaddr8_trunc(PG_FUNCTION_ARGS)
Datum macaddr8_ge(PG_FUNCTION_ARGS)
Datum hashmacaddr8(PG_FUNCTION_ARGS)
Datum macaddr8_send(PG_FUNCTION_ARGS)
Datum macaddr8_not(PG_FUNCTION_ARGS)
Datum macaddr8_ne(PG_FUNCTION_ARGS)
Datum macaddr8_lt(PG_FUNCTION_ARGS)
Datum hashmacaddr8extended(PG_FUNCTION_ARGS)
Datum macaddr8_le(PG_FUNCTION_ARGS)
void * palloc0(Size size)
void pq_begintypsend(StringInfo buf)
int pq_getmsgbyte(StringInfo msg)
bytea * pq_endtypsend(StringInfo buf)
static void pq_sendbyte(StringInfo buf, uint8 byt)
StringInfoData * StringInfo
#define PG_GETARG_MACADDR_P(n)
#define PG_GETARG_MACADDR8_P(n)
#define PG_RETURN_MACADDR8_P(x)
#define PG_RETURN_MACADDR_P(x)