database.sarang.net
UserID
Passwd
Database
DBMS
ㆍMySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MySQL Devel 21040 게시물 읽기
 News | Q&A | Columns | Tutorials | Devel | Files | Links
No. 21040
Converts Ethernet MAC Address string to uint64 and backwards
작성자
정재익(advance)
작성일
2004-02-16 09:56
조회수
6,754

다음은 Ethernet MAC address 문자열을 unit64 로 변환해 주는 MySQL 용 UDF (user-defined function) 이다. MySQL 에서 UDF 작성의 좋은 예가 될것으로 판단되어 올려 둔다.

 

/*
** $Id: udf_eth.cc,v 1.0 2003/09/25 16:27:33 tkubinski Stable $
*/

/*
** UDF eth_aton, eth_ntoa for MySQL server
*/

/*
** int eth_aton(char*)
**
** Converts MAC Address (string) to unsigned long long representation.
** Accepted MAC formats:
**
**    a1b2c3d4e5f6
**    a1b2.c3d4.e5f6
**    a1:b2:c3:d4:e5:f6
**
** Letter can be small or capital.
**
**
** char* eth_ntoa(unsigned long long)
**
** Converts unsigned long long to string representation.
** MAC Address is presented in a1:b2:c3:d4:e5:f6 format.
**
**
** A dynamicly loadable file should be compiled sharable
** (like: gcc -I /usr/include/mysql -shared -o udf_eth.so udf_eth.cc).
*/

/*
** Author: Tomasz Kubinski <tomasz@kubinski.info> 2003-08-20
**
** Copyright (c)2003 by Tomasz Kubinski. All rights reserved.
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
** Changelog:
**
** $Log: udf_eth.cc,v $
** Revision 1.0  2003/09/25 16:27:33  tkubinski
** Initial revision
**
*/

#ifdef STANDARD
#include <stdio.h>
#include <string.h>
#else
#include <my_global.h>
#include <my_sys.h>
#endif

#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>    /* To get strmov() */

#include <sys/types.h>
#include <netinet/ether.h>


#ifdef HAVE_DLOPEN

/* These must be right or mysqld will not find the symbol! */

extern "C" {
    my_ulonglong eth_aton( UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error );
    my_bool eth_aton_init( UDF_INIT *initid, UDF_ARGS *args, char *message );
    void    eth_aton_deinit( UDF_INIT *initid );

    char    *eth_ntoa( UDF_INIT *initid, UDF_ARGS *args, char *result,
         unsigned long *length, char *null_value, char *error );
    my_bool eth_ntoa_init( UDF_INIT *initid, UDF_ARGS *args, char *message );
    void    eth_ntoa_deinit( UDF_INIT *initid );
}


/*
 *  Fastest way to check and convert hex digit to decimal
 */
const int8_t hex2dec[256] = {
/*       00  01  02  03  04  05  06  07  08  09  0a  0b  0c  0d  0e  0f */
/* 00 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 20 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 30 */  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
/* 40 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 50 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 60 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 70 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* 90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* a0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* b0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* c0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* d0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* e0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
/* f0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};


my_ulonglong eth_aton( UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error )
{
    my_ulonglong n = (my_ulonglong)0;
    int8_t i, j, c;

    if ( args->args[0] == NULL || args->lengths[0] < 12 || args->lengths[0] > 17 )
    {
 *is_null = 1;
 *error = 1;
 return 0;
    }

    for ( i = j = 0; i < args->lengths[0]; i++ )
    {
 c = hex2dec[ (u_int8_t)args->args[0][i] ];
 if ( c >= 0 )
 {
     n = ( n << 4 ) + (my_ulonglong)c;
     j++;
 }
    }

    if ( j != ETH_ALEN * 2 )
    {
 strcpy( error, "Incorrect macaddr format" );
 *is_null = 1;
 *error = 1;
 return 0;
    }

    *is_null = 0;
    *error = 0;
    return n;
}


my_bool eth_aton_init( UDF_INIT *initid, UDF_ARGS *args, char *message )
{
    if ( args->arg_count != 1 || args->arg_type[0] != STRING_RESULT )
    {
 strcpy( message, "Usage: eth_aton(\"macaddr\"), where macaddr = xxxxxxxxxxxx or xx:xx:xx:xx:xx:xx or xxxx.xxxx.xxxx" );
 return 1;
    }

    initid->maybe_null = 0;
    return 0;
}


void eth_aton_deinit( UDF_INIT *initid )
{
}


char *eth_ntoa( UDF_INIT *initid, UDF_ARGS *args, char *result,
                unsigned long *reslen, char *is_null, char *error )
{
    my_ulonglong n;

    if ( args->args[0] == NULL )
    {
 *is_null = 0;
 *error = 0;
 return 0;
    }

    n = *((my_ulonglong *)args->args[0]);

    sprintf( result, "%02x:%02x:%02x:%02x:%02x:%02x",
 (u_int8_t)( n >> 40 ), (u_int8_t)( n >> 32 ), (u_int8_t)( n >> 24 ),
 (u_int8_t)( n >> 16 ), (u_int8_t)( n >>  8 ), (u_int8_t)n );

    *reslen = 17;
    *is_null = 0;
    *error = 0;
    return result;
}


my_bool eth_ntoa_init( UDF_INIT *initid, UDF_ARGS *args, char *message )
{
    if ( args->arg_count != 1 || args->arg_type[0] != INT_RESULT )
    {
 strcpy( message, "Usage: eth_ntoa(1234567890)" );
 return 1;
    }

    initid->maybe_null = 0;
    initid->max_length = 17+1;
    return 0;
}


void eth_ntoa_deinit( UDF_INIT *initid )
{
}

#endif /* HAVE_DLOPEN */

[Top]
No.
제목
작성자
작성일
조회
21062MySQL UDF - pg_age
정재익
2004-02-18
7869
21042MySQL UDF - Fast realtime compressor
정재익
2004-02-16
6519
21041MySQL UDF - substr_count
정재익
2004-02-16
7641
21040Converts Ethernet MAC Address string to uint64 and backwards
정재익
2004-02-16
6754
20896MySQL CAPI [1]
정재익
2004-01-26
14008
20895MySQL ADO 사용 [1]
정재익
2004-01-26
12598
17897MySQL2006에러(..gone away)
김태훈
2002-11-22
7572
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.029초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다