From 8a35cbe1db808126b5285bdfbc115b6f0e393541 Mon Sep 17 00:00:00 2001 From: "Thomas G. Lockhart" Date: Wed, 23 Aug 2000 06:04:49 +0000 Subject: [PATCH] Add functions to convert to and from text, and to truncate to MAC OUI. Remove hardcoded macaddr_manuf(), which had really old, obsolete info. Replace this with some contrib/mac/ code to maniag OUI info from IEEE. --- src/backend/utils/adt/mac.c | 225 ++++++++++--------------------- src/include/catalog/catversion.h | 4 +- src/include/catalog/pg_proc.h | 67 ++++----- src/include/utils/builtins.h | 6 +- 4 files changed, 111 insertions(+), 191 deletions(-) diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c index e8d502b87d..5e949ea2e6 100644 --- a/src/backend/utils/adt/mac.c +++ b/src/backend/utils/adt/mac.c @@ -1,7 +1,7 @@ /* * PostgreSQL type definitions for MAC addresses. * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.17 2000/08/03 23:07:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.18 2000/08/23 06:04:33 thomas Exp $ */ #include "postgres.h" @@ -9,135 +9,6 @@ #include "utils/builtins.h" #include "utils/inet.h" -/* - * XXX this table of manufacturers is long out of date, and should never - * have been wired into the code in the first place. - */ - -typedef struct manufacturer -{ - unsigned char a; - unsigned char b; - unsigned char c; - char *name; -} manufacturer; - -static manufacturer manufacturers[] = { - {0x00, 0x00, 0x0C, "Cisco"}, - {0x00, 0x00, 0x0E, "Fujitsu"}, - {0x00, 0x00, 0x0F, "NeXT"}, - {0x00, 0x00, 0x10, "Sytek"}, - {0x00, 0x00, 0x1D, "Cabletron"}, - {0x00, 0x00, 0x20, "DIAB"}, - {0x00, 0x00, 0x22, "Visual Technology"}, - {0x00, 0x00, 0x2A, "TRW"}, - {0x00, 0x00, 0x32, "GPT Limited"}, - {0x00, 0x00, 0x5A, "S & Koch"}, - {0x00, 0x00, 0x5E, "IANA"}, - {0x00, 0x00, 0x65, "Network General"}, - {0x00, 0x00, 0x6B, "MIPS"}, - {0x00, 0x00, 0x77, "MIPS"}, - {0x00, 0x00, 0x7A, "Ardent"}, - {0x00, 0x00, 0x89, "Cayman Systems"}, - {0x00, 0x00, 0x93, "Proteon"}, - {0x00, 0x00, 0x9F, "Ameristar Technology"}, - {0x00, 0x00, 0xA2, "Wellfleet"}, - {0x00, 0x00, 0xA3, "Network Application Technology"}, - {0x00, 0x00, 0xA6, "Network General"}, - {0x00, 0x00, 0xA7, "NCD"}, - {0x00, 0x00, 0xA9, "Network Systems"}, - {0x00, 0x00, 0xAA, "Xerox"}, - {0x00, 0x00, 0xB3, "CIMLinc"}, - {0x00, 0x00, 0xB7, "Dove Fastnet"}, - {0x00, 0x00, 0xBC, "Allen-Bradley"}, - {0x00, 0x00, 0xC0, "Western Digital"}, - {0x00, 0x00, 0xC5, "Farallon"}, - {0x00, 0x00, 0xC6, "Hewlett-Packard"}, - {0x00, 0x00, 0xC8, "Altos"}, - {0x00, 0x00, 0xC9, "Emulex"}, - {0x00, 0x00, 0xD7, "Dartmouth College"}, - {0x00, 0x00, 0xD8, "3Com (?)"}, - {0x00, 0x00, 0xDD, "Gould"}, - {0x00, 0x00, 0xDE, "Unigraph"}, - {0x00, 0x00, 0xE2, "Acer Counterpoint"}, - {0x00, 0x00, 0xEF, "Alantec"}, - {0x00, 0x00, 0xFD, "High Level Hardware"}, - {0x00, 0x01, 0x02, "BBN internal usage"}, - {0x00, 0x20, 0xAF, "3Com"}, - {0x00, 0x17, 0x00, "Kabel"}, - {0x00, 0x80, 0x64, "Wyse Technology"}, - {0x00, 0x80, 0x2B, "IMAC (?)"}, - {0x00, 0x80, 0x2D, "Xylogics, Inc."}, - {0x00, 0x80, 0x8C, "Frontier Software Development"}, - {0x00, 0x80, 0xC2, "IEEE 802.1 Committee"}, - {0x00, 0x80, 0xD3, "Shiva"}, - {0x00, 0xAA, 0x00, "Intel"}, - {0x00, 0xDD, 0x00, "Ungermann-Bass"}, - {0x00, 0xDD, 0x01, "Ungermann-Bass"}, - {0x02, 0x07, 0x01, "Racal InterLan"}, - {0x02, 0x04, 0x06, "BBN internal usage"}, - {0x02, 0x60, 0x86, "Satelcom MegaPac"}, - {0x02, 0x60, 0x8C, "3Com"}, - {0x02, 0xCF, 0x1F, "CMC"}, - {0x08, 0x00, 0x02, "3Com"}, - {0x08, 0x00, 0x03, "ACC"}, - {0x08, 0x00, 0x05, "Symbolics"}, - {0x08, 0x00, 0x08, "BBN"}, - {0x08, 0x00, 0x09, "Hewlett-Packard"}, - {0x08, 0x00, 0x0A, "Nestar Systems"}, - {0x08, 0x00, 0x0B, "Unisys"}, - {0x08, 0x00, 0x11, "Tektronix"}, - {0x08, 0x00, 0x14, "Excelan"}, - {0x08, 0x00, 0x17, "NSC"}, - {0x08, 0x00, 0x1A, "Data General"}, - {0x08, 0x00, 0x1B, "Data General"}, - {0x08, 0x00, 0x1E, "Apollo"}, - {0x08, 0x00, 0x20, "Sun"}, - {0x08, 0x00, 0x22, "NBI"}, - {0x08, 0x00, 0x25, "CDC"}, - {0x08, 0x00, 0x26, "Norsk Data"}, - {0x08, 0x00, 0x27, "PCS Computer Systems GmbH"}, - {0x08, 0x00, 0x28, "Texas Instruments"}, - {0x08, 0x00, 0x2B, "DEC"}, - {0x08, 0x00, 0x2E, "Metaphor"}, - {0x08, 0x00, 0x2F, "Prime Computer"}, - {0x08, 0x00, 0x36, "Intergraph"}, - {0x08, 0x00, 0x37, "Fujitsu-Xerox"}, - {0x08, 0x00, 0x38, "Bull"}, - {0x08, 0x00, 0x39, "Spider Systems"}, - {0x08, 0x00, 0x41, "DCA Digital Comm. Assoc."}, - {0x08, 0x00, 0x45, "Xylogics (?)"}, - {0x08, 0x00, 0x46, "Sony"}, - {0x08, 0x00, 0x47, "Sequent"}, - {0x08, 0x00, 0x49, "Univation"}, - {0x08, 0x00, 0x4C, "Encore"}, - {0x08, 0x00, 0x4E, "BICC"}, - {0x08, 0x00, 0x56, "Stanford University"}, - {0x08, 0x00, 0x58, "DECsystem 20 (?)"}, - {0x08, 0x00, 0x5A, "IBM"}, - {0x08, 0x00, 0x67, "Comdesign"}, - {0x08, 0x00, 0x68, "Ridge"}, - {0x08, 0x00, 0x69, "Silicon Graphics"}, - {0x08, 0x00, 0x6E, "Concurrent"}, - {0x08, 0x00, 0x75, "DDE"}, - {0x08, 0x00, 0x7C, "Vitalink"}, - {0x08, 0x00, 0x80, "XIOS"}, - {0x08, 0x00, 0x86, "Imagen/QMS"}, - {0x08, 0x00, 0x87, "Xyplex"}, - {0x08, 0x00, 0x89, "Kinetics"}, - {0x08, 0x00, 0x8B, "Pyramid"}, - {0x08, 0x00, 0x8D, "XyVision"}, - {0x08, 0x00, 0x90, "Retix Inc"}, - {0x48, 0x44, 0x53, "HDS (?)"}, - {0x80, 0x00, 0x10, "AT&T"}, - {0xAA, 0x00, 0x00, "DEC"}, - {0xAA, 0x00, 0x01, "DEC"}, - {0xAA, 0x00, 0x02, "DEC"}, - {0xAA, 0x00, 0x03, "DEC"}, - {0xAA, 0x00, 0x04, "DEC"}, - {0x00, 0x00, 0x00, NULL} -}; - /* * Utility macros used for sorting and comparing: */ @@ -151,6 +22,7 @@ static manufacturer manufacturers[] = { /* * MAC address reader. Accepts several common notations. */ + Datum macaddr_in(PG_FUNCTION_ARGS) { @@ -205,6 +77,7 @@ macaddr_in(PG_FUNCTION_ARGS) /* * MAC address output function. Fixed format. */ + Datum macaddr_out(PG_FUNCTION_ARGS) { @@ -226,6 +99,57 @@ macaddr_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(result); } +/* macaddr_text() + * Convert macaddr to text data type. + */ + +Datum +macaddr_text(PG_FUNCTION_ARGS) +{ + /* Input is a macaddr, but may as well leave it in Datum form */ + Datum addr = PG_GETARG_DATUM(0); + text *result; + char *str; + int len; + + str = DatumGetCString(DirectFunctionCall1(macaddr_out, addr)); + + len = (strlen(str) + VARHDRSZ); + + result = palloc(len); + + VARATT_SIZEP(result) = len; + memmove(VARDATA(result), str, (len - VARHDRSZ)); + + pfree(str); + + PG_RETURN_TEXT_P(result); +} + +/* text_macaddr() + * Convert text to macaddr data type. + */ + +Datum +text_macaddr(PG_FUNCTION_ARGS) +{ + Datum result; + text *addr = PG_GETARG_TEXT_P(0); + char str[18]; + int len; + + len = (VARSIZE(addr)-VARHDRSZ); + if (len >= 18) + elog(ERROR, "Text is too long to convert to MAC address"); + + memmove(str, VARDATA(addr), len); + *(str+len) = '\0'; + + result = DirectFunctionCall1(macaddr_in, CStringGetDatum(str)); + + return(result); +} + /* * Comparison function for sorting: */ @@ -257,6 +181,7 @@ macaddr_cmp(PG_FUNCTION_ARGS) /* * Boolean comparisons. */ + Datum macaddr_lt(PG_FUNCTION_ARGS) { @@ -312,36 +237,24 @@ macaddr_ne(PG_FUNCTION_ARGS) } /* - * The special manufacturer fetching function. + * Truncation function to allow comparing mac manufacturers. + * From suggestion by Alex Pilosov */ Datum -macaddr_manuf(PG_FUNCTION_ARGS) +macaddr_trunc(PG_FUNCTION_ARGS) { + macaddr *result; macaddr *addr = PG_GETARG_MACADDR_P(0); - manufacturer *manuf; - int length; - text *result; - for (manuf = manufacturers; manuf->name != NULL; manuf++) - { - if ((manuf->a == addr->a) && - (manuf->b == addr->b) && - (manuf->c == addr->c)) - break; - } - if (manuf->name == NULL) - { - /* Not known, so return empty string */ - result = palloc(VARHDRSZ); - VARATT_SIZEP(result) = VARHDRSZ; - } - else - { - length = strlen(manuf->name); - result = palloc(length + VARHDRSZ); - VARATT_SIZEP(result) = length + VARHDRSZ; - memcpy(VARDATA(result), manuf->name, length); - } - PG_RETURN_TEXT_P(result); + result = (macaddr *) palloc(sizeof(macaddr)); + + result->a = addr->a; + result->b = addr->b; + result->c = addr->c; + result->d = 0; + result->e = 0; + result->f = 0; + + PG_RETURN_MACADDR_P(result); } diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 62c1c837e1..22b3cb7354 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.42 2000/08/21 04:48:51 tgl Exp $ + * $Id: catversion.h,v 1.43 2000/08/23 06:04:43 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200008201 +#define CATALOG_VERSION_NO 200008221 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 1af007d748..b50f74fdf4 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.162 2000/08/21 04:48:51 tgl Exp $ + * $Id: pg_proc.h,v 1.163 2000/08/23 06:04:44 thomas Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2204,22 +2204,27 @@ DESCR("(internal)"); DATA(insert OID = 437 ( macaddr_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 macaddr_out - )); DESCR("(internal)"); -DATA(insert OID = 830 ( macaddr_eq PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_eq - )); +DATA(insert OID = 752 ( text PGUID 12 f t t t 1 f 25 "829" 100 0 0 100 macaddr_text - )); +DESCR("MAC address to text"); +DATA(insert OID = 753 ( trunc PGUID 12 f t t t 1 f 829 "829" 100 0 0 100 macaddr_trunc - )); +DESCR("MAC manufacturer fields"); +DATA(insert OID = 767 ( macaddr PGUID 12 f t t t 1 f 829 "25" 100 0 0 100 text_macaddr - )); +DESCR("text to MAC address"); + +DATA(insert OID = 830 ( macaddr_eq PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_eq - )); DESCR("equal"); -DATA(insert OID = 831 ( macaddr_lt PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_lt - )); +DATA(insert OID = 831 ( macaddr_lt PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_lt - )); DESCR("less-than"); -DATA(insert OID = 832 ( macaddr_le PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_le - )); +DATA(insert OID = 832 ( macaddr_le PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_le - )); DESCR("less-than-or-equal"); -DATA(insert OID = 833 ( macaddr_gt PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_gt - )); +DATA(insert OID = 833 ( macaddr_gt PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_gt - )); DESCR("greater-than"); -DATA(insert OID = 834 ( macaddr_ge PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ge - )); +DATA(insert OID = 834 ( macaddr_ge PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ge - )); DESCR("greater-than-or-equal"); -DATA(insert OID = 835 ( macaddr_ne PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ne - )); +DATA(insert OID = 835 ( macaddr_ne PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ne - )); DESCR("not equal"); -DATA(insert OID = 836 ( macaddr_cmp PGUID 12 f t t t 2 f 23 "829 829" 100 0 0 100 macaddr_cmp - )); +DATA(insert OID = 836 ( macaddr_cmp PGUID 12 f t t t 2 f 23 "829 829" 100 0 0 100 macaddr_cmp - )); DESCR("less-equal-greater"); -DATA(insert OID = 837 ( macaddr_manuf PGUID 12 f t t t 1 f 25 "829" 100 0 0 100 macaddr_manuf - )); -DESCR("MAC manufacturer"); /* for inet type support */ DATA(insert OID = 910 ( inet_in PGUID 12 f t t t 1 f 869 "0" 100 0 0 100 inet_in - )); @@ -2234,51 +2239,51 @@ DATA(insert OID = 1427 ( cidr_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 ci DESCR("(internal)"); /* these are used for both inet and cidr */ -DATA(insert OID = 920 ( network_eq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_eq - )); +DATA(insert OID = 920 ( network_eq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_eq - )); DESCR("equal"); -DATA(insert OID = 921 ( network_lt PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_lt - )); +DATA(insert OID = 921 ( network_lt PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_lt - )); DESCR("less-than"); -DATA(insert OID = 922 ( network_le PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_le - )); +DATA(insert OID = 922 ( network_le PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_le - )); DESCR("less-than-or-equal"); -DATA(insert OID = 923 ( network_gt PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_gt - )); +DATA(insert OID = 923 ( network_gt PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_gt - )); DESCR("greater-than"); -DATA(insert OID = 924 ( network_ge PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_ge - )); +DATA(insert OID = 924 ( network_ge PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_ge - )); DESCR("greater-than-or-equal"); -DATA(insert OID = 925 ( network_ne PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_ne - )); +DATA(insert OID = 925 ( network_ne PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_ne - )); DESCR("not equal"); -DATA(insert OID = 926 ( network_cmp PGUID 12 f t t t 2 f 23 "869 869" 100 0 0 100 network_cmp - )); +DATA(insert OID = 926 ( network_cmp PGUID 12 f t t t 2 f 23 "869 869" 100 0 0 100 network_cmp - )); DESCR("less-equal-greater"); -DATA(insert OID = 927 ( network_sub PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_sub - )); +DATA(insert OID = 927 ( network_sub PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_sub - )); DESCR("is-subnet"); -DATA(insert OID = 928 ( network_subeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_subeq - )); +DATA(insert OID = 928 ( network_subeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_subeq - )); DESCR("is-subnet-or-equal"); -DATA(insert OID = 929 ( network_sup PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_sup - )); +DATA(insert OID = 929 ( network_sup PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_sup - )); DESCR("is-supernet"); -DATA(insert OID = 930 ( network_supeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_supeq - )); +DATA(insert OID = 930 ( network_supeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_supeq - )); DESCR("is-supernet-or-equal"); /* inet/cidr versions */ -DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_netmask - )); +DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_netmask - )); DESCR("netmask of address"); -DATA(insert OID = 697 ( masklen PGUID 12 f t t t 1 f 23 "869" 100 0 0 100 network_masklen - )); +DATA(insert OID = 697 ( masklen PGUID 12 f t t t 1 f 23 "869" 100 0 0 100 network_masklen - )); DESCR("netmask length"); -DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_broadcast - )); +DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_broadcast - )); DESCR("broadcast address"); -DATA(insert OID = 699 ( host PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_host - )); +DATA(insert OID = 699 ( host PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_host - )); DESCR("host address"); -DATA(insert OID = 683 ( network PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_network - )); +DATA(insert OID = 683 ( network PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_network - )); DESCR("network address"); -DATA(insert OID = 1691 ( boolle PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolle - )); +DATA(insert OID = 1691 ( boolle PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolle - )); DESCR("less-than-or-equal"); -DATA(insert OID = 1692 ( boolge PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolge - )); +DATA(insert OID = 1692 ( boolge PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolge - )); DESCR("greater-than-or-equal"); -DATA(insert OID = 1693 ( btboolcmp PGUID 12 f t t t 2 f 23 "16 16" 100 0 0 100 btboolcmp - )); +DATA(insert OID = 1693 ( btboolcmp PGUID 12 f t t t 2 f 23 "16 16" 100 0 0 100 btboolcmp - )); DESCR("btree less-equal-greater"); -DATA(insert OID = 1696 ( timetz_hash PGUID 12 f t t t 1 f 23 "1266" 100 0 0 100 timetz_hash - )); +DATA(insert OID = 1696 ( timetz_hash PGUID 12 f t t t 1 f 23 "1266" 100 0 0 100 timetz_hash - )); DESCR("hash"); -DATA(insert OID = 1697 ( interval_hash PGUID 12 f t t t 1 f 23 "1186" 100 0 0 100 interval_hash - )); +DATA(insert OID = 1697 ( interval_hash PGUID 12 f t t t 1 f 23 "1186" 100 0 0 100 interval_hash - )); DESCR("hash"); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 95f94fe93f..1e16af6874 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.132 2000/08/07 01:43:35 thomas Exp $ + * $Id: builtins.h,v 1.133 2000/08/23 06:04:49 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -502,7 +502,9 @@ extern Datum macaddr_eq(PG_FUNCTION_ARGS); extern Datum macaddr_ge(PG_FUNCTION_ARGS); extern Datum macaddr_gt(PG_FUNCTION_ARGS); extern Datum macaddr_ne(PG_FUNCTION_ARGS); -extern Datum macaddr_manuf(PG_FUNCTION_ARGS); +extern Datum macaddr_trunc(PG_FUNCTION_ARGS); +extern Datum macaddr_text(PG_FUNCTION_ARGS); +extern Datum text_macaddr(PG_FUNCTION_ARGS); /* numeric.c */ extern Datum numeric_in(PG_FUNCTION_ARGS);