LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - mac8.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 84.0 % 263 221 6 21 15 2 93 20 106 25 93 16
Current Date: 2023-04-08 17:13:01 Functions: 86.4 % 22 19 3 18 1 3 17 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 100.0 % 20 20 20
Legend: Lines: hit not hit (240..) days: 82.7 % 243 201 6 21 15 2 93 106 25 93
Function coverage date bins:
(60,120] days: 100.0 % 1 1 1
(240..) days: 43.9 % 41 18 3 18 3 17

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * mac8.c
                                  4                 :  *    PostgreSQL type definitions for 8 byte (EUI-64) MAC addresses.
                                  5                 :  *
                                  6                 :  * EUI-48 (6 byte) MAC addresses are accepted as input and are stored in
                                  7                 :  * EUI-64 format, with the 4th and 5th bytes set to FF and FE, respectively.
                                  8                 :  *
                                  9                 :  * Output is always in 8 byte (EUI-64) format.
                                 10                 :  *
                                 11                 :  * The following code is written with the assumption that the OUI field
                                 12                 :  * size is 24 bits.
                                 13                 :  *
                                 14                 :  * Portions Copyright (c) 1998-2023, PostgreSQL Global Development Group
                                 15                 :  *
                                 16                 :  * IDENTIFICATION
                                 17                 :  *        src/backend/utils/adt/mac8.c
                                 18                 :  *
                                 19                 :  *-------------------------------------------------------------------------
                                 20                 :  */
                                 21                 : 
                                 22                 : #include "postgres.h"
                                 23                 : 
                                 24                 : #include "common/hashfn.h"
                                 25                 : #include "libpq/pqformat.h"
                                 26                 : #include "utils/builtins.h"
                                 27                 : #include "utils/inet.h"
                                 28                 : 
                                 29                 : /*
                                 30                 :  *  Utility macros used for sorting and comparing:
                                 31                 :  */
                                 32                 : #define hibits(addr) \
                                 33                 :   ((unsigned long)(((addr)->a<<24) | ((addr)->b<<16) | ((addr)->c<<8) | ((addr)->d)))
                                 34                 : 
                                 35                 : #define lobits(addr) \
                                 36                 :   ((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))
                                 37                 : 
                                 38                 : static unsigned char hex2_to_uchar(const unsigned char *ptr, bool *badhex);
                                 39                 : 
                                 40                 : static const signed char hexlookup[128] = {
                                 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                 :  */
                                 57                 : static inline unsigned char
  116 tgl                        58 GNC        8179 : hex2_to_uchar(const unsigned char *ptr, bool *badhex)
                                 59                 : {
                                 60                 :     unsigned char ret;
 2215 sfrost                     61 ECB             :     signed char lookup;
 2216 sfrost                     62 EUB             : 
                                 63                 :     /* Handle the first character */
 2215 sfrost                     64 CBC        8179 :     if (*ptr > 127)
 2216 sfrost                     65 LBC           0 :         goto invalid_input;
 2216 sfrost                     66 ECB             : 
 2215 sfrost                     67 GIC        8179 :     lookup = hexlookup[*ptr];
 2216 sfrost                     68 CBC        8179 :     if (lookup < 0)
 2216 sfrost                     69 GIC          12 :         goto invalid_input;
                                 70                 : 
 2216 sfrost                     71 CBC        8167 :     ret = lookup << 4;
                                 72                 : 
 2216 sfrost                     73 ECB             :     /* Move to the second character */
 2216 sfrost                     74 GBC        8167 :     ptr++;
                                 75                 : 
 2215 sfrost                     76 CBC        8167 :     if (*ptr > 127)
 2216 sfrost                     77 LBC           0 :         goto invalid_input;
 2216 sfrost                     78 ECB             : 
 2215 sfrost                     79 GIC        8167 :     lookup = hexlookup[*ptr];
 2216 sfrost                     80 CBC        8167 :     if (lookup < 0)
 2216 sfrost                     81 GIC           9 :         goto invalid_input;
 2216 sfrost                     82 ECB             : 
 2216 sfrost                     83 GIC        8158 :     ret += lookup;
 2216 sfrost                     84 ECB             : 
 2216 sfrost                     85 CBC        8158 :     return ret;
 2216 sfrost                     86 ECB             : 
 2216 sfrost                     87 GIC          21 : invalid_input:
  116 tgl                        88 GNC          21 :     *badhex = true;
 2216 sfrost                     89 GIC          21 :     return 0;
 2216 sfrost                     90 ECB             : }
                                 91                 : 
                                 92                 : /*
                                 93                 :  * MAC address (EUI-48 and EUI-64) reader. Accepts several common notations.
                                 94                 :  */
                                 95                 : Datum
 2216 sfrost                     96 CBC        1211 : macaddr8_in(PG_FUNCTION_ARGS)
 2216 sfrost                     97 ECB             : {
 2153 bruce                      98 CBC        1211 :     const unsigned char *str = (unsigned char *) PG_GETARG_CSTRING(0);
  116 tgl                        99 GNC        1211 :     Node       *escontext = fcinfo->context;
 2215 sfrost                    100 CBC        1211 :     const unsigned char *ptr = str;
  116 tgl                       101 GNC        1211 :     bool        badhex = false;
 2216 sfrost                    102 ECB             :     macaddr8   *result;
 2216 sfrost                    103 CBC        1211 :     unsigned char a = 0,
                                104            1211 :                 b = 0,
                                105            1211 :                 c = 0,
                                106            1211 :                 d = 0,
 2216 sfrost                    107 GIC        1211 :                 e = 0,
                                108            1211 :                 f = 0,
 2216 sfrost                    109 CBC        1211 :                 g = 0,
                                110            1211 :                 h = 0;
 2216 sfrost                    111 GIC        1211 :     int         count = 0;
 2215                           112            1211 :     unsigned char spacer = '\0';
 2216 sfrost                    113 ECB             : 
                                114                 :     /* skip leading spaces */
 2215 sfrost                    115 GIC        1259 :     while (*ptr && isspace(*ptr))
 2216                           116              48 :         ptr++;
                                117                 : 
                                118                 :     /* digits must always come in pairs */
                                119            9351 :     while (*ptr && *(ptr + 1))
                                120                 :     {
                                121                 :         /*
 2216 sfrost                    122 ECB             :          * 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 */
 2216 sfrost                    128 CBC        8191 :         count++;
 2216 sfrost                    129 ECB             : 
 2216 sfrost                    130 CBC        8191 :         switch (count)
 2216 sfrost                    131 ECB             :         {
 2216 sfrost                    132 CBC        1211 :             case 1:
  116 tgl                       133 GNC        1211 :                 a = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    134 CBC        1211 :                 break;
                                135            1205 :             case 2:
  116 tgl                       136 GNC        1205 :                 b = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    137 CBC        1205 :                 break;
                                138            1193 :             case 3:
  116 tgl                       139 GNC        1193 :                 c = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    140 CBC        1193 :                 break;
                                141            1193 :             case 4:
  116 tgl                       142 GNC        1193 :                 d = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    143 CBC        1193 :                 break;
                                144            1187 :             case 5:
  116 tgl                       145 GNC        1187 :                 e = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    146 CBC        1187 :                 break;
                                147            1187 :             case 6:
  116 tgl                       148 GNC        1187 :                 f = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    149 CBC        1187 :                 break;
                                150             506 :             case 7:
  116 tgl                       151 GNC         506 :                 g = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    152 CBC         506 :                 break;
 2216 sfrost                    153 GIC         497 :             case 8:
  116 tgl                       154 GNC         497 :                 h = hex2_to_uchar(ptr, &badhex);
 2216 sfrost                    155 CBC         497 :                 break;
                                156              12 :             default:
                                157                 :                 /* must be trailing garbage... */
  116 tgl                       158 GNC          12 :                 goto fail;
 2216 sfrost                    159 ECB             :         }
                                160                 : 
  116 tgl                       161 GNC        8179 :         if (badhex)
                                162              21 :             goto fail;
                                163                 : 
                                164                 :         /* Move forward to where the next byte should be */
 2216 sfrost                    165 CBC        8158 :         ptr += 2;
 2216 sfrost                    166 ECB             : 
                                167                 :         /* Check for a spacer, these are valid, anything else is not */
 2216 sfrost                    168 GIC        8158 :         if (*ptr == ':' || *ptr == '-' || *ptr == '.')
 2216 sfrost                    169 ECB             :         {
                                170                 :             /* remember the spacer used, if it changes then it isn't valid */
 2216 sfrost                    171 GIC        4466 :             if (spacer == '\0')
                                172             857 :                 spacer = *ptr;
 2216 sfrost                    173 ECB             : 
                                174                 :             /* Have to use the same spacer throughout */
 2216 sfrost                    175 GIC        3609 :             else if (spacer != *ptr)
  116 tgl                       176 GNC          12 :                 goto fail;
                                177                 : 
 2216 sfrost                    178 ECB             :             /* move past the spacer */
 2216 sfrost                    179 GIC        4454 :             ptr++;
                                180                 :         }
 2216 sfrost                    181 ECB             : 
                                182                 :         /* allow trailing whitespace after if we have 6 or 8 bytes */
 2216 sfrost                    183 GIC        8146 :         if (count == 6 || count == 8)
                                184                 :         {
 2215                           185            1678 :             if (isspace(*ptr))
                                186                 :             {
                                187              72 :                 while (*++ptr && isspace(*ptr));
 2216 sfrost                    188 ECB             : 
                                189                 :                 /* If we found a space and then non-space, it's invalid */
 2216 sfrost                    190 CBC          18 :                 if (*ptr)
  116 tgl                       191 GNC           6 :                     goto fail;
 2216 sfrost                    192 ECB             :             }
                                193                 :         }
                                194                 :     }
                                195                 : 
                                196                 :     /* Convert a 6 byte MAC address to macaddr8 */
 2216 sfrost                    197 CBC        1160 :     if (count == 6)
                                198                 :     {
                                199             678 :         h = f;
                                200             678 :         g = e;
                                201             678 :         f = d;
 2216 sfrost                    202 ECB             : 
 2216 sfrost                    203 CBC         678 :         d = 0xFF;
                                204             678 :         e = 0xFE;
 2216 sfrost                    205 ECB             :     }
 2216 sfrost                    206 CBC         482 :     else if (count != 8)
  116 tgl                       207 GNC           6 :         goto fail;
 2216 sfrost                    208 ECB             : 
 2216 sfrost                    209 GIC        1154 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
                                210                 : 
                                211            1154 :     result->a = a;
                                212            1154 :     result->b = b;
                                213            1154 :     result->c = c;
                                214            1154 :     result->d = d;
                                215            1154 :     result->e = e;
                                216            1154 :     result->f = f;
                                217            1154 :     result->g = g;
 2216 sfrost                    218 CBC        1154 :     result->h = h;
                                219                 : 
                                220            1154 :     PG_RETURN_MACADDR8_P(result);
                                221                 : 
  116 tgl                       222 GNC          57 : fail:
                                223              57 :     ereturn(escontext, (Datum) 0,
                                224                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                225                 :              errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
                                226                 :                     str)));
                                227                 : }
                                228                 : 
 2216 sfrost                    229 ECB             : /*
                                230                 :  * MAC8 address (EUI-64) output function. Fixed format.
                                231                 :  */
                                232                 : Datum
 2216 sfrost                    233 CBC         872 : macaddr8_out(PG_FUNCTION_ARGS)
                                234                 : {
                                235             872 :     macaddr8   *addr = PG_GETARG_MACADDR8_P(0);
                                236                 :     char       *result;
                                237                 : 
 2216 sfrost                    238 GIC         872 :     result = (char *) palloc(32);
                                239                 : 
                                240             872 :     snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
                                241             872 :              addr->a, addr->b, addr->c, addr->d,
                                242             872 :              addr->e, addr->f, addr->g, addr->h);
                                243                 : 
 2216 sfrost                    244 GBC         872 :     PG_RETURN_CSTRING(result);
                                245                 : }
 2216 sfrost                    246 EUB             : 
                                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                 :  */
                                252                 : Datum
 2216 sfrost                    253 UBC           0 : macaddr8_recv(PG_FUNCTION_ARGS)
                                254                 : {
                                255               0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
                                256                 :     macaddr8   *addr;
 2216 sfrost                    257 EUB             : 
 2216 sfrost                    258 UBC           0 :     addr = (macaddr8 *) palloc0(sizeof(macaddr8));
                                259                 : 
 2216 sfrost                    260 UIC           0 :     addr->a = pq_getmsgbyte(buf);
                                261               0 :     addr->b = pq_getmsgbyte(buf);
 2216 sfrost                    262 UBC           0 :     addr->c = pq_getmsgbyte(buf);
 2216 sfrost                    263 EUB             : 
 2216 sfrost                    264 UIC           0 :     if (buf->len == 6)
                                265                 :     {
 2216 sfrost                    266 UBC           0 :         addr->d = 0xFF;
                                267               0 :         addr->e = 0xFE;
 2216 sfrost                    268 EUB             :     }
                                269                 :     else
                                270                 :     {
 2216 sfrost                    271 UIC           0 :         addr->d = pq_getmsgbyte(buf);
                                272               0 :         addr->e = pq_getmsgbyte(buf);
                                273                 :     }
                                274                 : 
                                275               0 :     addr->f = pq_getmsgbyte(buf);
                                276               0 :     addr->g = pq_getmsgbyte(buf);
 2216 sfrost                    277 UBC           0 :     addr->h = pq_getmsgbyte(buf);
                                278                 : 
                                279               0 :     PG_RETURN_MACADDR8_P(addr);
                                280                 : }
                                281                 : 
 2216 sfrost                    282 EUB             : /*
                                283                 :  * macaddr8_send - converts macaddr8(EUI-64) to binary format
                                284                 :  */
                                285                 : Datum
 2216 sfrost                    286 UBC           0 : macaddr8_send(PG_FUNCTION_ARGS)
 2216 sfrost                    287 EUB             : {
 2216 sfrost                    288 UBC           0 :     macaddr8   *addr = PG_GETARG_MACADDR8_P(0);
 2216 sfrost                    289 EUB             :     StringInfoData buf;
                                290                 : 
 2216 sfrost                    291 UIC           0 :     pq_begintypsend(&buf);
 2216 sfrost                    292 UBC           0 :     pq_sendbyte(&buf, addr->a);
 2216 sfrost                    293 UIC           0 :     pq_sendbyte(&buf, addr->b);
                                294               0 :     pq_sendbyte(&buf, addr->c);
                                295               0 :     pq_sendbyte(&buf, addr->d);
                                296               0 :     pq_sendbyte(&buf, addr->e);
                                297               0 :     pq_sendbyte(&buf, addr->f);
                                298               0 :     pq_sendbyte(&buf, addr->g);
                                299               0 :     pq_sendbyte(&buf, addr->h);
 2216 sfrost                    300 ECB             : 
 2216 sfrost                    301 UIC           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
 2216 sfrost                    302 ECB             : }
                                303                 : 
                                304                 : 
                                305                 : /*
                                306                 :  * macaddr8_cmp_internal - comparison function for sorting:
                                307                 :  */
                                308                 : static int32
 2216 sfrost                    309 CBC       89347 : macaddr8_cmp_internal(macaddr8 *a1, macaddr8 *a2)
                                310                 : {
                                311           89347 :     if (hibits(a1) < hibits(a2))
 2216 sfrost                    312 GIC       49408 :         return -1;
                                313           39939 :     else if (hibits(a1) > hibits(a2))
                                314           35846 :         return 1;
 2216 sfrost                    315 CBC        4093 :     else if (lobits(a1) < lobits(a2))
 2216 sfrost                    316 GIC         111 :         return -1;
 2216 sfrost                    317 CBC        3982 :     else if (lobits(a1) > lobits(a2))
                                318              12 :         return 1;
                                319                 :     else
                                320            3970 :         return 0;
                                321                 : }
                                322                 : 
                                323                 : Datum
 2216 sfrost                    324 GIC        7253 : macaddr8_cmp(PG_FUNCTION_ARGS)
                                325                 : {
                                326            7253 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
                                327            7253 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
 2216 sfrost                    328 ECB             : 
 2216 sfrost                    329 GIC        7253 :     PG_RETURN_INT32(macaddr8_cmp_internal(a1, a2));
 2216 sfrost                    330 ECB             : }
                                331                 : 
                                332                 : /*
                                333                 :  * Boolean comparison functions.
                                334                 :  */
                                335                 : 
                                336                 : Datum
 2216 sfrost                    337 CBC       56675 : macaddr8_lt(PG_FUNCTION_ARGS)
                                338                 : {
                                339           56675 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
                                340           56675 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
                                341                 : 
                                342           56675 :     PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) < 0);
                                343                 : }
                                344                 : 
                                345                 : Datum
                                346            1846 : macaddr8_le(PG_FUNCTION_ARGS)
                                347                 : {
                                348            1846 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
                                349            1846 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
                                350                 : 
                                351            1846 :     PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) <= 0);
                                352                 : }
                                353                 : 
                                354                 : Datum
                                355           19005 : macaddr8_eq(PG_FUNCTION_ARGS)
                                356                 : {
                                357           19005 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
                                358           19005 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
                                359                 : 
                                360           19005 :     PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) == 0);
                                361                 : }
                                362                 : 
                                363                 : Datum
                                364            1497 : macaddr8_ge(PG_FUNCTION_ARGS)
                                365                 : {
                                366            1497 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
                                367            1497 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
                                368                 : 
                                369            1497 :     PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) >= 0);
                                370                 : }
                                371                 : 
                                372                 : Datum
                                373            3065 : macaddr8_gt(PG_FUNCTION_ARGS)
                                374                 : {
                                375            3065 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
                                376            3065 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
                                377                 : 
                                378            3065 :     PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) > 0);
                                379                 : }
                                380                 : 
                                381                 : Datum
 2216 sfrost                    382 GIC           6 : macaddr8_ne(PG_FUNCTION_ARGS)
                                383                 : {
                                384               6 :     macaddr8   *a1 = PG_GETARG_MACADDR8_P(0);
 2216 sfrost                    385 CBC           6 :     macaddr8   *a2 = PG_GETARG_MACADDR8_P(1);
                                386                 : 
                                387               6 :     PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) != 0);
                                388                 : }
 2216 sfrost                    389 ECB             : 
                                390                 : /*
                                391                 :  * Support function for hash indexes on macaddr8.
                                392                 :  */
                                393                 : Datum
 2216 sfrost                    394 GIC          90 : hashmacaddr8(PG_FUNCTION_ARGS)
 2216 sfrost                    395 ECB             : {
 2216 sfrost                    396 GIC          90 :     macaddr8   *key = PG_GETARG_MACADDR8_P(0);
 2216 sfrost                    397 ECB             : 
 2216 sfrost                    398 CBC          90 :     return hash_any((unsigned char *) key, sizeof(macaddr8));
                                399                 : }
                                400                 : 
                                401                 : Datum
 2047 rhaas                     402 GIC          30 : hashmacaddr8extended(PG_FUNCTION_ARGS)
                                403                 : {
                                404              30 :     macaddr8   *key = PG_GETARG_MACADDR8_P(0);
 2047 rhaas                     405 ECB             : 
 2047 rhaas                     406 GIC          30 :     return hash_any_extended((unsigned char *) key, sizeof(macaddr8),
 2047 rhaas                     407 CBC          30 :                              PG_GETARG_INT64(1));
                                408                 : }
                                409                 : 
 2216 sfrost                    410 ECB             : /*
                                411                 :  * Arithmetic functions: bitwise NOT, AND, OR.
                                412                 :  */
                                413                 : Datum
 2216 sfrost                    414 CBC          60 : macaddr8_not(PG_FUNCTION_ARGS)
 2216 sfrost                    415 ECB             : {
 2216 sfrost                    416 CBC          60 :     macaddr8   *addr = PG_GETARG_MACADDR8_P(0);
 2216 sfrost                    417 ECB             :     macaddr8   *result;
                                418                 : 
 2216 sfrost                    419 GIC          60 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
 2216 sfrost                    420 CBC          60 :     result->a = ~addr->a;
 2216 sfrost                    421 GIC          60 :     result->b = ~addr->b;
                                422              60 :     result->c = ~addr->c;
                                423              60 :     result->d = ~addr->d;
 2216 sfrost                    424 CBC          60 :     result->e = ~addr->e;
 2216 sfrost                    425 GIC          60 :     result->f = ~addr->f;
 2216 sfrost                    426 CBC          60 :     result->g = ~addr->g;
                                427              60 :     result->h = ~addr->h;
                                428                 : 
 2216 sfrost                    429 GIC          60 :     PG_RETURN_MACADDR8_P(result);
 2216 sfrost                    430 ECB             : }
                                431                 : 
                                432                 : Datum
 2216 sfrost                    433 CBC          60 : macaddr8_and(PG_FUNCTION_ARGS)
 2216 sfrost                    434 ECB             : {
 2216 sfrost                    435 CBC          60 :     macaddr8   *addr1 = PG_GETARG_MACADDR8_P(0);
                                436              60 :     macaddr8   *addr2 = PG_GETARG_MACADDR8_P(1);
 2216 sfrost                    437 ECB             :     macaddr8   *result;
                                438                 : 
 2216 sfrost                    439 GIC          60 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
 2216 sfrost                    440 CBC          60 :     result->a = addr1->a & addr2->a;
 2216 sfrost                    441 GIC          60 :     result->b = addr1->b & addr2->b;
                                442              60 :     result->c = addr1->c & addr2->c;
                                443              60 :     result->d = addr1->d & addr2->d;
 2216 sfrost                    444 CBC          60 :     result->e = addr1->e & addr2->e;
 2216 sfrost                    445 GIC          60 :     result->f = addr1->f & addr2->f;
 2216 sfrost                    446 CBC          60 :     result->g = addr1->g & addr2->g;
                                447              60 :     result->h = addr1->h & addr2->h;
                                448                 : 
 2216 sfrost                    449 GIC          60 :     PG_RETURN_MACADDR8_P(result);
 2216 sfrost                    450 ECB             : }
                                451                 : 
                                452                 : Datum
 2216 sfrost                    453 CBC          60 : macaddr8_or(PG_FUNCTION_ARGS)
 2216 sfrost                    454 ECB             : {
 2216 sfrost                    455 CBC          60 :     macaddr8   *addr1 = PG_GETARG_MACADDR8_P(0);
                                456              60 :     macaddr8   *addr2 = PG_GETARG_MACADDR8_P(1);
 2216 sfrost                    457 ECB             :     macaddr8   *result;
                                458                 : 
 2216 sfrost                    459 GIC          60 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
 2216 sfrost                    460 CBC          60 :     result->a = addr1->a | addr2->a;
 2216 sfrost                    461 GIC          60 :     result->b = addr1->b | addr2->b;
                                462              60 :     result->c = addr1->c | addr2->c;
                                463              60 :     result->d = addr1->d | addr2->d;
                                464              60 :     result->e = addr1->e | addr2->e;
                                465              60 :     result->f = addr1->f | addr2->f;
                                466              60 :     result->g = addr1->g | addr2->g;
 2216 sfrost                    467 CBC          60 :     result->h = addr1->h | addr2->h;
                                468                 : 
                                469              60 :     PG_RETURN_MACADDR8_P(result);
                                470                 : }
                                471                 : 
 2216 sfrost                    472 ECB             : /*
                                473                 :  * Truncation function to allow comparing macaddr8 manufacturers.
                                474                 :  */
                                475                 : Datum
 2216 sfrost                    476 CBC          60 : macaddr8_trunc(PG_FUNCTION_ARGS)
 2216 sfrost                    477 ECB             : {
 2216 sfrost                    478 CBC          60 :     macaddr8   *addr = PG_GETARG_MACADDR8_P(0);
 2216 sfrost                    479 ECB             :     macaddr8   *result;
                                480                 : 
 2216 sfrost                    481 CBC          60 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
                                482                 : 
                                483              60 :     result->a = addr->a;
 2216 sfrost                    484 GIC          60 :     result->b = addr->b;
                                485              60 :     result->c = addr->c;
                                486              60 :     result->d = 0;
                                487              60 :     result->e = 0;
                                488              60 :     result->f = 0;
                                489              60 :     result->g = 0;
 2216 sfrost                    490 CBC          60 :     result->h = 0;
                                491                 : 
                                492              60 :     PG_RETURN_MACADDR8_P(result);
                                493                 : }
                                494                 : 
 2216 sfrost                    495 ECB             : /*
                                496                 :  * Set 7th bit for modified EUI-64 as used in IPv6.
                                497                 :  */
                                498                 : Datum
 2216 sfrost                    499 CBC           3 : macaddr8_set7bit(PG_FUNCTION_ARGS)
 2216 sfrost                    500 ECB             : {
 2216 sfrost                    501 CBC           3 :     macaddr8   *addr = PG_GETARG_MACADDR8_P(0);
 2216 sfrost                    502 ECB             :     macaddr8   *result;
                                503                 : 
 2216 sfrost                    504 CBC           3 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
                                505                 : 
                                506               3 :     result->a = addr->a | 0x02;
 2216 sfrost                    507 GIC           3 :     result->b = addr->b;
                                508               3 :     result->c = addr->c;
                                509               3 :     result->d = addr->d;
                                510               3 :     result->e = addr->e;
                                511               3 :     result->f = addr->f;
                                512               3 :     result->g = addr->g;
                                513               3 :     result->h = addr->h;
 2216 sfrost                    514 EUB             : 
 2216 sfrost                    515 GIC           3 :     PG_RETURN_MACADDR8_P(result);
 2216 sfrost                    516 EUB             : }
                                517                 : 
                                518                 : /*----------------------------------------------------------
                                519                 :  *  Conversion operators.
                                520                 :  *---------------------------------------------------------*/
                                521                 : 
                                522                 : Datum
 2216 sfrost                    523 UBC           0 : macaddrtomacaddr8(PG_FUNCTION_ARGS)
 2216 sfrost                    524 EUB             : {
 2216 sfrost                    525 UBC           0 :     macaddr    *addr6 = PG_GETARG_MACADDR_P(0);
 2216 sfrost                    526 EUB             :     macaddr8   *result;
                                527                 : 
 2216 sfrost                    528 UBC           0 :     result = (macaddr8 *) palloc0(sizeof(macaddr8));
                                529                 : 
 2216 sfrost                    530 UIC           0 :     result->a = addr6->a;
 2216 sfrost                    531 UBC           0 :     result->b = addr6->b;
 2216 sfrost                    532 UIC           0 :     result->c = addr6->c;
                                533               0 :     result->d = 0xFF;
                                534               0 :     result->e = 0xFE;
 2216 sfrost                    535 LBC           0 :     result->f = addr6->d;
 2216 sfrost                    536 UIC           0 :     result->g = addr6->e;
 2216 sfrost                    537 LBC           0 :     result->h = addr6->f;
                                538                 : 
                                539                 : 
                                540               0 :     PG_RETURN_MACADDR8_P(result);
                                541                 : }
 2216 sfrost                    542 ECB             : 
 2216 sfrost                    543 EUB             : Datum
 2216 sfrost                    544 GIC          12 : macaddr8tomacaddr(PG_FUNCTION_ARGS)
                                545                 : {
                                546              12 :     macaddr8   *addr = PG_GETARG_MACADDR8_P(0);
                                547                 :     macaddr    *result;
                                548                 : 
                                549              12 :     result = (macaddr *) palloc0(sizeof(macaddr));
                                550                 : 
 2216 sfrost                    551 CBC          12 :     if ((addr->d != 0xFF) || (addr->e != 0xFE))
 2216 sfrost                    552 LBC           0 :         ereport(ERROR,
 2216 sfrost                    553 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                554                 :                  errmsg("macaddr8 data out of range to convert to macaddr"),
 2118 tgl                       555                 :                  errhint("Only addresses that have FF and FE as values in the "
 2036 peter_e                   556                 :                          "4th and 5th bytes from the left, for example "
                                557                 :                          "xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted "
 2118 tgl                       558                 :                          "from macaddr8 to macaddr.")));
                                559                 : 
 2216 sfrost                    560 GIC          12 :     result->a = addr->a;
                                561              12 :     result->b = addr->b;
                                562              12 :     result->c = addr->c;
                                563              12 :     result->d = addr->f;
                                564              12 :     result->e = addr->g;
                                565              12 :     result->f = addr->h;
                                566                 : 
                                567              12 :     PG_RETURN_MACADDR_P(result);
                                568                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a