1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

Add support for EUI-64 MAC addresses as macaddr8

This adds in support for EUI-64 MAC addresses by adding a new data type
called 'macaddr8' (using our usual convention of indicating the number
of bytes stored).

This was largely a copy-and-paste from the macaddr data type, with
appropriate adjustments for having 8 bytes instead of 6 and adding
support for converting a provided EUI-48 (6 byte format) to the EUI-64
format.  Conversion from EUI-48 to EUI-64 inserts FFFE as the 4th and
5th bytes but does not perform the IPv6 modified EUI-64 action of
flipping the 7th bit, but we add a function to perform that specific
action for the user as it may be commonly done by users who wish to
calculate their IPv6 address based on their network prefix and 48-bit
MAC address.

Author: Haribabu Kommi, with a good bit of rework of macaddr8_in by me.
Reviewed by: Vitaly Burovoy, Kuntal Ghosh

Discussion: https://postgr.es/m/CAJrrPGcUi8ZH+KkK+=TctNQ+EfkeCEHtMU_yo1mvX8hsk_ghNQ@mail.gmail.com
This commit is contained in:
Stephen Frost
2017-03-15 11:16:25 -04:00
parent 42bdaebf16
commit c7a9fa399d
37 changed files with 1826 additions and 20 deletions

View File

@ -281,6 +281,17 @@
<literal>&gt;</literal>
</entry>
</row>
<row>
<entry><literal>macaddr8_minmax_ops</literal></entry>
<entry><type>macaddr8</type></entry>
<entry>
<literal>&lt;</literal>
<literal>&lt;=</literal>
<literal>=</literal>
<literal>&gt;=</literal>
<literal>&gt;</literal>
</entry>
</row>
<row>
<entry><literal>name_minmax_ops</literal></entry>
<entry><type>name</type></entry>

View File

@ -16,7 +16,8 @@
<type>time without time zone</>, <type>date</>, <type>interval</>,
<type>oid</>, <type>money</>, <type>"char"</>,
<type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
<type>varbit</>, <type>macaddr</>, <type>inet</>, and <type>cidr</>.
<type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>,
and <type>cidr</>.
</para>
<para>

View File

@ -16,8 +16,8 @@
<type>time without time zone</>, <type>date</>, <type>interval</>,
<type>oid</>, <type>money</>, <type>char</>,
<type>varchar</>, <type>text</>, <type>bytea</>, <type>bit</>,
<type>varbit</>, <type>macaddr</>, <type>inet</>, <type>cidr</>,
and <type>uuid</>.
<type>varbit</>, <type>macaddr</>, <type>macaddr8</>, <type>inet</>,
<type>cidr</> and <type>uuid</>.
</para>
<para>

View File

@ -166,6 +166,12 @@
<entry>MAC (Media Access Control) address</entry>
</row>
<row>
<entry><type>macaddr8</type></entry>
<entry></entry>
<entry>MAC (Media Access Control) address (EUI-64 format)</entry>
</row>
<row>
<entry><type>money</type></entry>
<entry></entry>
@ -3428,6 +3434,12 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
<entry>MAC addresses</entry>
</row>
<row>
<entry><type>macaddr8</type></entry>
<entry>8 bytes</entry>
<entry>MAC addresses (EUI-64 format)</entry>
</row>
</tbody>
</tgroup>
</table>
@ -3668,6 +3680,77 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
</para>
</sect2>
<sect2 id="datatype-macaddr8">
<title><type>macaddr8</type></title>
<indexterm>
<primary>macaddr8 (data type)</primary>
</indexterm>
<indexterm>
<primary>MAC address (EUI-64 format)</primary>
<see>macaddr</see>
</indexterm>
<para>
The <type>macaddr8</> type stores MAC addresses in EUI-64
format, known for example from Ethernet card hardware addresses
(although MAC addresses are used for other purposes as well).
This type can accept both 6 and 8 byte length MAC addresses
and stores them in 8 byte length format. MAC addresses given
in 6 byte format will be stored in 8 byte length format with the
4th and 5th bytes set to FF and FE, respectively.
Note that IPv6 uses a modified EUI-64 format where the 7th bit
should be set to one after the conversion from EUI-48. The
function <function>macaddr8_set7bit</> is provided to make this
change.
Generally speaking, any input which is comprised of pairs of hex
digits (on byte boundaries), optionally separated consistently by
one of <literal>':'</>, <literal>'-'</> or <literal>'.'</>, is
accepted. The number of hex digits must be either 16 (8 bytes) or
12 (6 bytes). Leading and trailing whitespace is ignored.
The following are examples of input formats that are accepted:
<simplelist>
<member><literal>'08:00:2b:01:02:03:04:05'</></member>
<member><literal>'08-00-2b-01-02-03-04-05'</></member>
<member><literal>'08002b:0102030405'</></member>
<member><literal>'08002b-0102030405'</></member>
<member><literal>'0800.2b01.0203.0405'</></member>
<member><literal>'0800-2b01-0203-0405'</></member>
<member><literal>'08002b01:02030405'</></member>
<member><literal>'08002b0102030405'</></member>
</simplelist>
These examples would all specify the same address. Upper and
lower case is accepted for the digits
<literal>a</> through <literal>f</>. Output is always in the
first of the forms shown.
The last six input formats that are mentioned above are not part
of any standard.
To convert a traditional 48 bit MAC address in EUI-48 format to
modified EUI-64 format to be included as the host portion of an
IPv6 address, use <function>macaddr8_set7bit</> as shown:
<programlisting>
SELECT macaddr8_set7bit('08:00:2b:01:02:03');
<computeroutput>
macaddr8_set7bit
-------------------------
0a:00:2b:ff:fe:01:02:03
(1 row)
</computeroutput>
</programlisting>
</para>
</sect2>
</sect1>
<sect1 id="datatype-bit">

View File

@ -9228,6 +9228,62 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
for NOT, AND and OR.
</para>
<para>
<xref linkend="macaddr8-functions-table"> shows the functions
available for use with the <type>macaddr8</type> type. The function
<literal><function>trunc(<type>macaddr8</type>)</function></literal> returns a MAC
address with the last 5 bytes set to zero. This can be used to
associate the remaining prefix with a manufacturer.
</para>
<table id="macaddr8-functions-table">
<title><type>macaddr8</type> Functions</title>
<tgroup cols="5">
<thead>
<row>
<entry>Function</entry>
<entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>Result</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<indexterm>
<primary>trunc</primary>
</indexterm>
<literal><function>trunc(<type>macaddr8</type>)</function></literal>
</entry>
<entry><type>macaddr8</type></entry>
<entry>set last 5 bytes to zero</entry>
<entry><literal>trunc(macaddr8 '12:34:56:78:90:ab:cd:ef')</literal></entry>
<entry><literal>12:34:56:00:00:00:00:00</literal></entry>
</row>
<row>
<entry>
<indexterm>
<primary>macaddr8_set7bit</primary>
</indexterm>
<literal><function>macaddr8_set7bit(<type>macaddr8</type>)</function></literal>
</entry>
<entry><type>macaddr8</type></entry>
<entry>set 7th bit to one, also known as modified EUI-64, for inclusion in an IPv6 address</entry>
<entry><literal>macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef')</literal></entry>
<entry><literal>02:34:56:ff:fe:ab:cd:ef</literal></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
The <type>macaddr8</type> type also supports the standard relational
operators (<literal>&gt;</literal>, <literal>&lt;=</literal>, etc.) for
ordering, and the bitwise arithmetic operators (<literal>~</literal>,
<literal>&amp;</literal> and <literal>|</literal>) for NOT, AND and OR.
</para>
</sect1>