PostgreSQL Source Code git master
Loading...
Searching...
No Matches
mac8.c File Reference
#include "postgres.h"
#include "common/hashfn.h"
#include "libpq/pqformat.h"
#include "nodes/nodes.h"
#include "utils/fmgrprotos.h"
#include "utils/inet.h"
Include dependency graph for mac8.c:

Go to the source code of this file.

Macros

#define hibits(addr)    ((unsigned long)(((addr)->a<<24) | ((addr)->b<<16) | ((addr)->c<<8) | ((addr)->d)))
 
#define lobits(addr)    ((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))
 

Functions

static unsigned char hex2_to_uchar (const unsigned char *ptr, bool *badhex)
 
Datum macaddr8_in (PG_FUNCTION_ARGS)
 
Datum macaddr8_out (PG_FUNCTION_ARGS)
 
Datum macaddr8_recv (PG_FUNCTION_ARGS)
 
Datum macaddr8_send (PG_FUNCTION_ARGS)
 
static int32 macaddr8_cmp_internal (macaddr8 *a1, macaddr8 *a2)
 
Datum macaddr8_cmp (PG_FUNCTION_ARGS)
 
Datum macaddr8_lt (PG_FUNCTION_ARGS)
 
Datum macaddr8_le (PG_FUNCTION_ARGS)
 
Datum macaddr8_eq (PG_FUNCTION_ARGS)
 
Datum macaddr8_ge (PG_FUNCTION_ARGS)
 
Datum macaddr8_gt (PG_FUNCTION_ARGS)
 
Datum macaddr8_ne (PG_FUNCTION_ARGS)
 
Datum hashmacaddr8 (PG_FUNCTION_ARGS)
 
Datum hashmacaddr8extended (PG_FUNCTION_ARGS)
 
Datum macaddr8_not (PG_FUNCTION_ARGS)
 
Datum macaddr8_and (PG_FUNCTION_ARGS)
 
Datum macaddr8_or (PG_FUNCTION_ARGS)
 
Datum macaddr8_trunc (PG_FUNCTION_ARGS)
 
Datum macaddr8_set7bit (PG_FUNCTION_ARGS)
 
Datum macaddrtomacaddr8 (PG_FUNCTION_ARGS)
 
Datum macaddr8tomacaddr (PG_FUNCTION_ARGS)
 

Variables

static const signed char hexlookup [128]
 

Macro Definition Documentation

◆ hibits

#define hibits (   addr)     ((unsigned long)(((addr)->a<<24) | ((addr)->b<<16) | ((addr)->c<<8) | ((addr)->d)))

Definition at line 33 of file mac8.c.

40 {
41 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
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 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
45 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
48 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49};
50
51/*
52 * hex2_to_uchar - convert 2 hex digits to a byte (unsigned char)
53 *
54 * Sets *badhex to true if the end of the string is reached ('\0' found), or if
55 * either character is not a valid hex digit.
56 */
57static inline unsigned char
58hex2_to_uchar(const unsigned char *ptr, bool *badhex)
59{
60 unsigned char ret;
61 signed char lookup;
62
63 /* Handle the first character */
64 if (*ptr > 127)
65 goto invalid_input;
66
67 lookup = hexlookup[*ptr];
68 if (lookup < 0)
69 goto invalid_input;
70
71 ret = lookup << 4;
72
73 /* Move to the second character */
74 ptr++;
75
76 if (*ptr > 127)
77 goto invalid_input;
78
79 lookup = hexlookup[*ptr];
80 if (lookup < 0)
81 goto invalid_input;
82
83 ret += lookup;
84
85 return ret;
86
88 *badhex = true;
89 return 0;
90}
91
92/*
93 * MAC address (EUI-48 and EUI-64) reader. Accepts several common notations.
94 */
97{
98 const unsigned char *str = (unsigned char *) PG_GETARG_CSTRING(0);
99 Node *escontext = fcinfo->context;
100 const unsigned char *ptr = str;
101 bool badhex = false;
102 macaddr8 *result;
103 unsigned char a = 0,
104 b = 0,
105 c = 0,
106 d = 0,
107 e = 0,
108 f = 0,
109 g = 0,
110 h = 0;
111 int count = 0;
112 unsigned char spacer = '\0';
113
114 /* skip leading spaces */
115 while (*ptr && isspace(*ptr))
116 ptr++;
117
118 /* digits must always come in pairs */
119 while (*ptr && *(ptr + 1))
120 {
121 /*
122 * Attempt to decode each byte, which must be 2 hex digits in a row.
123 * If either digit is not hex, hex2_to_uchar will throw ereport() for
124 * us. Either 6 or 8 byte MAC addresses are supported.
125 */
126
127 /* Attempt to collect a byte */
128 count++;
129
130 switch (count)
131 {
132 case 1:
133 a = hex2_to_uchar(ptr, &badhex);
134 break;
135 case 2:
136 b = hex2_to_uchar(ptr, &badhex);
137 break;
138 case 3:
139 c = hex2_to_uchar(ptr, &badhex);
140 break;
141 case 4:
142 d = hex2_to_uchar(ptr, &badhex);
143 break;
144 case 5:
145 e = hex2_to_uchar(ptr, &badhex);
146 break;
147 case 6:
148 f = hex2_to_uchar(ptr, &badhex);
149 break;
150 case 7:
151 g = hex2_to_uchar(ptr, &badhex);
152 break;
153 case 8:
154 h = hex2_to_uchar(ptr, &badhex);
155 break;
156 default:
157 /* must be trailing garbage... */
158 goto fail;
159 }
160
161 if (badhex)
162 goto fail;
163
164 /* Move forward to where the next byte should be */
165 ptr += 2;
166
167 /* Check for a spacer, these are valid, anything else is not */
168 if (*ptr == ':' || *ptr == '-' || *ptr == '.')
169 {
170 /* remember the spacer used, if it changes then it isn't valid */
171 if (spacer == '\0')
172 spacer = *ptr;
173
174 /* Have to use the same spacer throughout */
175 else if (spacer != *ptr)
176 goto fail;
177
178 /* move past the spacer */
179 ptr++;
180 }
181
182 /* allow trailing whitespace after if we have 6 or 8 bytes */
183 if (count == 6 || count == 8)
184 {
185 if (isspace(*ptr))
186 {
187 while (*++ptr && isspace(*ptr));
188
189 /* If we found a space and then non-space, it's invalid */
190 if (*ptr)
191 goto fail;
192 }
193 }
194 }
195
196 /* Convert a 6 byte MAC address to macaddr8 */
197 if (count == 6)
198 {
199 h = f;
200 g = e;
201 f = d;
202
203 d = 0xFF;
204 e = 0xFE;
205 }
206 else if (count != 8)
207 goto fail;
208
209 result = palloc0_object(macaddr8);
210
211 result->a = a;
212 result->b = b;
213 result->c = c;
214 result->d = d;
215 result->e = e;
216 result->f = f;
217 result->g = g;
218 result->h = h;
219
220 PG_RETURN_MACADDR8_P(result);
221
222fail:
223 ereturn(escontext, (Datum) 0,
225 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
226 str)));
227}
228
229/*
230 * MAC8 address (EUI-64) output function. Fixed format.
231 */
232Datum
234{
236 char *result;
237
238 result = (char *) palloc(32);
239
240 snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
241 addr->a, addr->b, addr->c, addr->d,
242 addr->e, addr->f, addr->g, addr->h);
243
244 PG_RETURN_CSTRING(result);
245}
246
247/*
248 * macaddr8_recv - converts external binary format(EUI-48 and EUI-64) to macaddr8
249 *
250 * The external representation is just the eight bytes, MSB first.
251 */
252Datum
254{
256 macaddr8 *addr;
257
258 addr = palloc0_object(macaddr8);
259
260 addr->a = pq_getmsgbyte(buf);
261 addr->b = pq_getmsgbyte(buf);
262 addr->c = pq_getmsgbyte(buf);
263
264 if (buf->len == 6)
265 {
266 addr->d = 0xFF;
267 addr->e = 0xFE;
268 }
269 else
270 {
271 addr->d = pq_getmsgbyte(buf);
272 addr->e = pq_getmsgbyte(buf);
273 }
274
275 addr->f = pq_getmsgbyte(buf);
276 addr->g = pq_getmsgbyte(buf);
277 addr->h = pq_getmsgbyte(buf);
278
280}
281
282/*
283 * macaddr8_send - converts macaddr8(EUI-64) to binary format
284 */
285Datum
287{
290
292 pq_sendbyte(&buf, addr->a);
293 pq_sendbyte(&buf, addr->b);
294 pq_sendbyte(&buf, addr->c);
295 pq_sendbyte(&buf, addr->d);
296 pq_sendbyte(&buf, addr->e);
297 pq_sendbyte(&buf, addr->f);
298 pq_sendbyte(&buf, addr->g);
299 pq_sendbyte(&buf, addr->h);
300
302}
303
304
305/*
306 * macaddr8_cmp_internal - comparison function for sorting:
307 */
308static int32
310{
311 if (hibits(a1) < hibits(a2))
312 return -1;
313 else if (hibits(a1) > hibits(a2))
314 return 1;
315 else if (lobits(a1) < lobits(a2))
316 return -1;
317 else if (lobits(a1) > lobits(a2))
318 return 1;
319 else
320 return 0;
321}
322
323Datum
325{
328
330}
331
332/*
333 * Boolean comparison functions.
334 */
335
336Datum
338{
341
343}
344
345Datum
347{
350
352}
353
354Datum
356{
359
361}
362
363Datum
365{
368
370}
371
372Datum
374{
377
379}
380
381Datum
383{
386
388}
389
390/*
391 * Support function for hash indexes on macaddr8.
392 */
393Datum
395{
397
398 return hash_any((unsigned char *) key, sizeof(macaddr8));
399}
400
401Datum
403{
405
406 return hash_any_extended((unsigned char *) key, sizeof(macaddr8),
407 PG_GETARG_INT64(1));
408}
409
410/*
411 * Arithmetic functions: bitwise NOT, AND, OR.
412 */
413Datum
415{
417 macaddr8 *result;
418
419 result = palloc0_object(macaddr8);
420 result->a = ~addr->a;
421 result->b = ~addr->b;
422 result->c = ~addr->c;
423 result->d = ~addr->d;
424 result->e = ~addr->e;
425 result->f = ~addr->f;
426 result->g = ~addr->g;
427 result->h = ~addr->h;
428
429 PG_RETURN_MACADDR8_P(result);
430}
431
432Datum
434{
437 macaddr8 *result;
438
439 result = palloc0_object(macaddr8);
440 result->a = addr1->a & addr2->a;
441 result->b = addr1->b & addr2->b;
442 result->c = addr1->c & addr2->c;
443 result->d = addr1->d & addr2->d;
444 result->e = addr1->e & addr2->e;
445 result->f = addr1->f & addr2->f;
446 result->g = addr1->g & addr2->g;
447 result->h = addr1->h & addr2->h;
448
449 PG_RETURN_MACADDR8_P(result);
450}
451
452Datum
454{
457 macaddr8 *result;
458
459 result = palloc0_object(macaddr8);
460 result->a = addr1->a | addr2->a;
461 result->b = addr1->b | addr2->b;
462 result->c = addr1->c | addr2->c;
463 result->d = addr1->d | addr2->d;
464 result->e = addr1->e | addr2->e;
465 result->f = addr1->f | addr2->f;
466 result->g = addr1->g | addr2->g;
467 result->h = addr1->h | addr2->h;
468
469 PG_RETURN_MACADDR8_P(result);
470}
471
472/*
473 * Truncation function to allow comparing macaddr8 manufacturers.
474 */
475Datum
477{
479 macaddr8 *result;
480
481 result = palloc0_object(macaddr8);
482
483 result->a = addr->a;
484 result->b = addr->b;
485 result->c = addr->c;
486 result->d = 0;
487 result->e = 0;
488 result->f = 0;
489 result->g = 0;
490 result->h = 0;
491
492 PG_RETURN_MACADDR8_P(result);
493}
494
495/*
496 * Set 7th bit for modified EUI-64 as used in IPv6.
497 */
498Datum
500{
502 macaddr8 *result;
503
504 result = palloc0_object(macaddr8);
505
506 result->a = addr->a | 0x02;
507 result->b = addr->b;
508 result->c = addr->c;
509 result->d = addr->d;
510 result->e = addr->e;
511 result->f = addr->f;
512 result->g = addr->g;
513 result->h = addr->h;
514
515 PG_RETURN_MACADDR8_P(result);
516}
517
518/*----------------------------------------------------------
519 * Conversion operators.
520 *---------------------------------------------------------*/
521
522Datum
524{
526 macaddr8 *result;
527
528 result = palloc0_object(macaddr8);
529
530 result->a = addr6->a;
531 result->b = addr6->b;
532 result->c = addr6->c;
533 result->d = 0xFF;
534 result->e = 0xFE;
535 result->f = addr6->d;
536 result->g = addr6->e;
537 result->h = addr6->f;
538
539
540 PG_RETURN_MACADDR8_P(result);
541}
542
543Datum
545{
547 macaddr *result;
548
549 result = palloc0_object(macaddr);
550
551 if ((addr->d != 0xFF) || (addr->e != 0xFE))
554 errmsg("macaddr8 data out of range to convert to macaddr"),
555 errhint("Only addresses that have FF and FE as values in the "
556 "4th and 5th bytes from the left, for example "
557 "xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted "
558 "from macaddr8 to macaddr.")));
559
560 result->a = addr->a;
561 result->b = addr->b;
562 result->c = addr->c;
563 result->d = addr->f;
564 result->e = addr->g;
565 result->f = addr->h;
566
567 PG_RETURN_MACADDR_P(result);
568}
int32_t int32
Definition c.h:542
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ereturn(context, dummy_value,...)
Definition elog.h:278
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
#define palloc0_object(type)
Definition fe_memutils.h:75
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition hashfn.h:37
static Datum hash_any(const unsigned char *k, int keylen)
Definition hashfn.h:31
const char * str
static const FormData_pg_attribute a1
Definition heap.c:144
static const FormData_pg_attribute a2
Definition heap.c:157
int b
Definition isn.c:74
int a
Definition isn.c:73
static unsigned char hex2_to_uchar(const unsigned char *ptr, bool *badhex)
Definition mac8.c:59
Datum macaddr8_or(PG_FUNCTION_ARGS)
Definition mac8.c:454
Datum macaddrtomacaddr8(PG_FUNCTION_ARGS)
Definition mac8.c:524
Datum macaddr8_out(PG_FUNCTION_ARGS)
Definition mac8.c:234
static const signed char hexlookup[128]
Definition mac8.c:41
#define hibits(addr)
Definition mac8.c:33
Datum macaddr8_set7bit(PG_FUNCTION_ARGS)
Definition mac8.c:500
Datum macaddr8_cmp(PG_FUNCTION_ARGS)
Definition mac8.c:325
Datum macaddr8tomacaddr(PG_FUNCTION_ARGS)
Definition mac8.c:545
Datum macaddr8_eq(PG_FUNCTION_ARGS)
Definition mac8.c:356
static int32 macaddr8_cmp_internal(macaddr8 *a1, macaddr8 *a2)
Definition mac8.c:310
Datum macaddr8_and(PG_FUNCTION_ARGS)
Definition mac8.c:434
Datum macaddr8_gt(PG_FUNCTION_ARGS)
Definition mac8.c:374
Datum macaddr8_recv(PG_FUNCTION_ARGS)
Definition mac8.c:254
Datum macaddr8_in(PG_FUNCTION_ARGS)
Definition mac8.c:97
Datum macaddr8_trunc(PG_FUNCTION_ARGS)
Definition mac8.c:477
Datum macaddr8_ge(PG_FUNCTION_ARGS)
Definition mac8.c:365
Datum hashmacaddr8(PG_FUNCTION_ARGS)
Definition mac8.c:395
Datum macaddr8_send(PG_FUNCTION_ARGS)
Definition mac8.c:287
Datum macaddr8_not(PG_FUNCTION_ARGS)
Definition mac8.c:415
Datum macaddr8_ne(PG_FUNCTION_ARGS)
Definition mac8.c:383
Datum macaddr8_lt(PG_FUNCTION_ARGS)
Definition mac8.c:338
#define lobits(addr)
Definition mac8.c:36
Datum hashmacaddr8extended(PG_FUNCTION_ARGS)
Definition mac8.c:403
Datum macaddr8_le(PG_FUNCTION_ARGS)
Definition mac8.c:347
void * palloc(Size size)
Definition mcxt.c:1387
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define snprintf
Definition port.h:260
uint64_t Datum
Definition postgres.h:70
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
int pq_getmsgbyte(StringInfo msg)
Definition pqformat.c:398
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition pqformat.h:160
char * c
e
static int fb(int x)
struct StringInfoData * StringInfo
Definition string.h:15
Definition nodes.h:135
Definition zic.c:307
unsigned char c
Definition inet.h:111
unsigned char b
Definition inet.h:110
unsigned char d
Definition inet.h:112
unsigned char e
Definition inet.h:113
unsigned char g
Definition inet.h:115
unsigned char h
Definition inet.h:116
unsigned char a
Definition inet.h:109
unsigned char f
Definition inet.h:114
Definition inet.h:95
unsigned char e
Definition inet.h:100
unsigned char b
Definition inet.h:97
unsigned char f
Definition inet.h:101
unsigned char c
Definition inet.h:98
unsigned char a
Definition inet.h:96
unsigned char d
Definition inet.h:99
#define PG_GETARG_MACADDR_P(n)
Definition inet.h:158
#define PG_GETARG_MACADDR8_P(n)
Definition inet.h:174
#define PG_RETURN_MACADDR8_P(x)
Definition inet.h:175
#define PG_RETURN_MACADDR_P(x)
Definition inet.h:159

◆ lobits

#define lobits (   addr)     ((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))

Definition at line 36 of file mac8.c.

Function Documentation

◆ hashmacaddr8()

Datum hashmacaddr8 ( PG_FUNCTION_ARGS  )

Definition at line 395 of file mac8.c.

396{
398
399 return hash_any((unsigned char *) key, sizeof(macaddr8));
400}

References hash_any(), and PG_GETARG_MACADDR8_P.

◆ hashmacaddr8extended()

Datum hashmacaddr8extended ( PG_FUNCTION_ARGS  )

Definition at line 403 of file mac8.c.

404{
406
407 return hash_any_extended((unsigned char *) key, sizeof(macaddr8),
408 PG_GETARG_INT64(1));
409}

References hash_any_extended(), PG_GETARG_INT64, and PG_GETARG_MACADDR8_P.

◆ hex2_to_uchar()

static unsigned char hex2_to_uchar ( const unsigned char ptr,
bool badhex 
)
inlinestatic

Definition at line 59 of file mac8.c.

60{
61 unsigned char ret;
62 signed char lookup;
63
64 /* Handle the first character */
65 if (*ptr > 127)
66 goto invalid_input;
67
68 lookup = hexlookup[*ptr];
69 if (lookup < 0)
70 goto invalid_input;
71
72 ret = lookup << 4;
73
74 /* Move to the second character */
75 ptr++;
76
77 if (*ptr > 127)
78 goto invalid_input;
79
80 lookup = hexlookup[*ptr];
81 if (lookup < 0)
82 goto invalid_input;
83
84 ret += lookup;
85
86 return ret;
87
89 *badhex = true;
90 return 0;
91}

References fb(), and hexlookup.

Referenced by macaddr8_in().

◆ macaddr8_and()

Datum macaddr8_and ( PG_FUNCTION_ARGS  )

Definition at line 434 of file mac8.c.

435{
438 macaddr8 *result;
439
440 result = palloc0_object(macaddr8);
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
450 PG_RETURN_MACADDR8_P(result);
451}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, fb(), macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR8_P, and PG_RETURN_MACADDR8_P.

◆ macaddr8_cmp()

◆ macaddr8_cmp_internal()

static int32 macaddr8_cmp_internal ( macaddr8 a1,
macaddr8 a2 
)
static

Definition at line 310 of file mac8.c.

311{
312 if (hibits(a1) < hibits(a2))
313 return -1;
314 else if (hibits(a1) > hibits(a2))
315 return 1;
316 else if (lobits(a1) < lobits(a2))
317 return -1;
318 else if (lobits(a1) > lobits(a2))
319 return 1;
320 else
321 return 0;
322}

References a1, a2, hibits, and lobits.

Referenced by macaddr8_cmp(), macaddr8_eq(), macaddr8_ge(), macaddr8_gt(), macaddr8_le(), macaddr8_lt(), and macaddr8_ne().

◆ macaddr8_eq()

Datum macaddr8_eq ( PG_FUNCTION_ARGS  )

Definition at line 356 of file mac8.c.

References a1, a2, macaddr8_cmp_internal(), PG_GETARG_MACADDR8_P, and PG_RETURN_BOOL.

Referenced by gbt_macad8eq().

◆ macaddr8_ge()

Datum macaddr8_ge ( PG_FUNCTION_ARGS  )

Definition at line 365 of file mac8.c.

References a1, a2, macaddr8_cmp_internal(), PG_GETARG_MACADDR8_P, and PG_RETURN_BOOL.

Referenced by gbt_macad8ge().

◆ macaddr8_gt()

Datum macaddr8_gt ( PG_FUNCTION_ARGS  )

Definition at line 374 of file mac8.c.

References a1, a2, macaddr8_cmp_internal(), PG_GETARG_MACADDR8_P, and PG_RETURN_BOOL.

Referenced by gbt_macad8gt().

◆ macaddr8_in()

Datum macaddr8_in ( PG_FUNCTION_ARGS  )

Definition at line 97 of file mac8.c.

98{
99 const unsigned char *str = (unsigned char *) PG_GETARG_CSTRING(0);
100 Node *escontext = fcinfo->context;
101 const unsigned char *ptr = str;
102 bool badhex = false;
103 macaddr8 *result;
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 /* skip leading spaces */
116 while (*ptr && isspace(*ptr))
117 ptr++;
118
119 /* digits must always come in pairs */
120 while (*ptr && *(ptr + 1))
121 {
122 /*
123 * Attempt to decode each byte, which must be 2 hex digits in a row.
124 * If either digit is not hex, hex2_to_uchar will throw ereport() for
125 * us. Either 6 or 8 byte MAC addresses are supported.
126 */
127
128 /* Attempt to collect a byte */
129 count++;
130
131 switch (count)
132 {
133 case 1:
134 a = hex2_to_uchar(ptr, &badhex);
135 break;
136 case 2:
137 b = hex2_to_uchar(ptr, &badhex);
138 break;
139 case 3:
140 c = hex2_to_uchar(ptr, &badhex);
141 break;
142 case 4:
143 d = hex2_to_uchar(ptr, &badhex);
144 break;
145 case 5:
146 e = hex2_to_uchar(ptr, &badhex);
147 break;
148 case 6:
149 f = hex2_to_uchar(ptr, &badhex);
150 break;
151 case 7:
152 g = hex2_to_uchar(ptr, &badhex);
153 break;
154 case 8:
155 h = hex2_to_uchar(ptr, &badhex);
156 break;
157 default:
158 /* must be trailing garbage... */
159 goto fail;
160 }
161
162 if (badhex)
163 goto fail;
164
165 /* Move forward to where the next byte should be */
166 ptr += 2;
167
168 /* Check for a spacer, these are valid, anything else is not */
169 if (*ptr == ':' || *ptr == '-' || *ptr == '.')
170 {
171 /* remember the spacer used, if it changes then it isn't valid */
172 if (spacer == '\0')
173 spacer = *ptr;
174
175 /* Have to use the same spacer throughout */
176 else if (spacer != *ptr)
177 goto fail;
178
179 /* move past the spacer */
180 ptr++;
181 }
182
183 /* allow trailing whitespace after if we have 6 or 8 bytes */
184 if (count == 6 || count == 8)
185 {
186 if (isspace(*ptr))
187 {
188 while (*++ptr && isspace(*ptr));
189
190 /* If we found a space and then non-space, it's invalid */
191 if (*ptr)
192 goto fail;
193 }
194 }
195 }
196
197 /* Convert a 6 byte MAC address to macaddr8 */
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
210 result = palloc0_object(macaddr8);
211
212 result->a = a;
213 result->b = b;
214 result->c = c;
215 result->d = d;
216 result->e = e;
217 result->f = f;
218 result->g = g;
219 result->h = h;
220
221 PG_RETURN_MACADDR8_P(result);
222
223fail:
224 ereturn(escontext, (Datum) 0,
226 errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
227 str)));
228}

References a, macaddr8::a, b, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, ereturn, errcode(), errmsg(), macaddr8::f, fb(), macaddr8::g, macaddr8::h, hex2_to_uchar(), palloc0_object, PG_GETARG_CSTRING, PG_RETURN_MACADDR8_P, and str.

◆ macaddr8_le()

Datum macaddr8_le ( PG_FUNCTION_ARGS  )

Definition at line 347 of file mac8.c.

References a1, a2, macaddr8_cmp_internal(), PG_GETARG_MACADDR8_P, and PG_RETURN_BOOL.

Referenced by gbt_macad8le().

◆ macaddr8_lt()

Datum macaddr8_lt ( PG_FUNCTION_ARGS  )

Definition at line 338 of file mac8.c.

References a1, a2, macaddr8_cmp_internal(), PG_GETARG_MACADDR8_P, and PG_RETURN_BOOL.

Referenced by gbt_macad8lt().

◆ macaddr8_ne()

Datum macaddr8_ne ( PG_FUNCTION_ARGS  )

Definition at line 383 of file mac8.c.

References a1, a2, macaddr8_cmp_internal(), PG_GETARG_MACADDR8_P, and PG_RETURN_BOOL.

◆ macaddr8_not()

Datum macaddr8_not ( PG_FUNCTION_ARGS  )

Definition at line 415 of file mac8.c.

416{
418 macaddr8 *result;
419
420 result = palloc0_object(macaddr8);
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
430 PG_RETURN_MACADDR8_P(result);
431}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, fb(), macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR8_P, and PG_RETURN_MACADDR8_P.

◆ macaddr8_or()

Datum macaddr8_or ( PG_FUNCTION_ARGS  )

Definition at line 454 of file mac8.c.

455{
458 macaddr8 *result;
459
460 result = palloc0_object(macaddr8);
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
470 PG_RETURN_MACADDR8_P(result);
471}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, fb(), macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR8_P, and PG_RETURN_MACADDR8_P.

◆ macaddr8_out()

Datum macaddr8_out ( PG_FUNCTION_ARGS  )

Definition at line 234 of file mac8.c.

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
245 PG_RETURN_CSTRING(result);
246}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, macaddr8::g, macaddr8::h, palloc(), PG_GETARG_MACADDR8_P, PG_RETURN_CSTRING, and snprintf.

◆ macaddr8_recv()

Datum macaddr8_recv ( PG_FUNCTION_ARGS  )

Definition at line 254 of file mac8.c.

255{
257 macaddr8 *addr;
258
259 addr = palloc0_object(macaddr8);
260
261 addr->a = pq_getmsgbyte(buf);
262 addr->b = pq_getmsgbyte(buf);
263 addr->c = pq_getmsgbyte(buf);
264
265 if (buf->len == 6)
266 {
267 addr->d = 0xFF;
268 addr->e = 0xFE;
269 }
270 else
271 {
272 addr->d = pq_getmsgbyte(buf);
273 addr->e = pq_getmsgbyte(buf);
274 }
275
276 addr->f = pq_getmsgbyte(buf);
277 addr->g = pq_getmsgbyte(buf);
278 addr->h = pq_getmsgbyte(buf);
279
281}

References macaddr8::a, macaddr8::b, buf, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_POINTER, PG_RETURN_MACADDR8_P, and pq_getmsgbyte().

◆ macaddr8_send()

Datum macaddr8_send ( PG_FUNCTION_ARGS  )

Definition at line 287 of file mac8.c.

288{
291
293 pq_sendbyte(&buf, addr->a);
294 pq_sendbyte(&buf, addr->b);
295 pq_sendbyte(&buf, addr->c);
296 pq_sendbyte(&buf, addr->d);
297 pq_sendbyte(&buf, addr->e);
298 pq_sendbyte(&buf, addr->f);
299 pq_sendbyte(&buf, addr->g);
300 pq_sendbyte(&buf, addr->h);
301
303}

References macaddr8::a, macaddr8::b, buf, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, macaddr8::g, macaddr8::h, PG_GETARG_MACADDR8_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendbyte().

◆ macaddr8_set7bit()

Datum macaddr8_set7bit ( PG_FUNCTION_ARGS  )

Definition at line 500 of file mac8.c.

501{
503 macaddr8 *result;
504
505 result = palloc0_object(macaddr8);
506
507 result->a = addr->a | 0x02;
508 result->b = addr->b;
509 result->c = addr->c;
510 result->d = addr->d;
511 result->e = addr->e;
512 result->f = addr->f;
513 result->g = addr->g;
514 result->h = addr->h;
515
516 PG_RETURN_MACADDR8_P(result);
517}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR8_P, and PG_RETURN_MACADDR8_P.

◆ macaddr8_trunc()

Datum macaddr8_trunc ( PG_FUNCTION_ARGS  )

Definition at line 477 of file mac8.c.

478{
480 macaddr8 *result;
481
482 result = palloc0_object(macaddr8);
483
484 result->a = addr->a;
485 result->b = addr->b;
486 result->c = addr->c;
487 result->d = 0;
488 result->e = 0;
489 result->f = 0;
490 result->g = 0;
491 result->h = 0;
492
493 PG_RETURN_MACADDR8_P(result);
494}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR8_P, and PG_RETURN_MACADDR8_P.

◆ macaddr8tomacaddr()

Datum macaddr8tomacaddr ( PG_FUNCTION_ARGS  )

Definition at line 545 of file mac8.c.

546{
548 macaddr *result;
549
550 result = palloc0_object(macaddr);
551
552 if ((addr->d != 0xFF) || (addr->e != 0xFE))
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
561 result->a = addr->a;
562 result->b = addr->b;
563 result->c = addr->c;
564 result->d = addr->f;
565 result->e = addr->g;
566 result->f = addr->h;
567
568 PG_RETURN_MACADDR_P(result);
569}

References macaddr::a, macaddr8::a, macaddr::b, macaddr8::b, macaddr::c, macaddr8::c, macaddr::d, macaddr8::d, macaddr::e, macaddr8::e, ereport, errcode(), errhint(), errmsg(), ERROR, macaddr::f, macaddr8::f, fb(), macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR8_P, and PG_RETURN_MACADDR_P.

◆ macaddrtomacaddr8()

Datum macaddrtomacaddr8 ( PG_FUNCTION_ARGS  )

Definition at line 524 of file mac8.c.

525{
527 macaddr8 *result;
528
529 result = palloc0_object(macaddr8);
530
531 result->a = addr6->a;
532 result->b = addr6->b;
533 result->c = addr6->c;
534 result->d = 0xFF;
535 result->e = 0xFE;
536 result->f = addr6->d;
537 result->g = addr6->e;
538 result->h = addr6->f;
539
540
541 PG_RETURN_MACADDR8_P(result);
542}

References macaddr8::a, macaddr8::b, macaddr8::c, macaddr8::d, macaddr8::e, macaddr8::f, fb(), macaddr8::g, macaddr8::h, palloc0_object, PG_GETARG_MACADDR_P, and PG_RETURN_MACADDR8_P.

Variable Documentation

◆ hexlookup

const signed char hexlookup[128]
static
Initial value:
= {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
}

Definition at line 41 of file mac8.c.

41 {
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};

Referenced by hex2_to_uchar().