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 21129 게시물 읽기
 News | Q&A | Columns | Tutorials | Devel | Files | Links
No. 21129
MySQL UDF -- ip lookup
작성자
정재익(advance)
작성일
2004-02-24 14:13
조회수
10,830

Functions for doing DNS lookups. First, lookup() - get the IP address for a given host. Secondly, reverse_lookup() - get the hostname for a given IP address.

 

====================

/* Copyright Abandoned 1998 TCX DataKonsult AB & Monty Program KB & Detron HB &
   Alexis Mikhailov <root@medinf.chuvashia.su>
   This file is public domain and comes with NO WARRANTY of any kind */

/*
** example file of UDF (user definable functions) that are dynamicly loaded
** into the standard mysqld core.
**
** The functions name, type and shared library is saved in the new system
** table 'func'.  To be able to create new functions one must have write
** privilege for the database 'mysql'. If one starts MySQL with
** --skip-grant, then UDF initialization will also be skipped.
**
** Syntax for the new commands are:
** create function <function_name> returns {string|real|integer}
**    soname <name_of_shared_library>
** drop function <function_name>
**
** Each defined function may have a xxxx_init function and a xxxx_deinit
** function.  The init function should alloc memory for the function
** and tell the main function about the max length of the result
** (for string functions), number of decimals (for double functions) and
** if the result may be a null value.
**
** If a function sets the 'error' argument to 1 the function will not be
** called anymore and mysqld will return NULL for all calls to this copy
** of the function.
**
** All strings arguments to functions are given as string pointer + length
** to allow handling of binary data.
** Remember that all functions must be thread safe. This means that one is not
** allowed to alloc any global or static variables that changes!
** If one needs memory one should alloc this in the init function and free
** this on the __deinit function.
**
**
** Function 'metaphon' returns a metaphon string of the string argument.
** This is something like a soundex string, but it's more tuned for English.
**
** Function 'myfunc_double' returns summary of codes of all letters
** of arguments divided by summary length of all its arguments.
**
** Function 'myfunc_int' returns summary length of all its arguments.
**
** On the end is a couple of functions that converts hostnames to ip and
** vice versa.
**
** A dynamicly loadable file should be compiled sharable
** (something like: gcc -shared -o udf_example.so myfunc.cc).
** You can easily get all switches right by doing:
** cd sql ; make udf_example.o
** Take the compile line that make writes, remove the '-c' near the end of
** the line and add -o udf_example.so to the end of the compile line.
** The resulting library (udf_example.so) should be copied to some dir
** searched by ld. (/usr/lib ?)
**
** After the library is made one must notify mysqld about the new
** functions with the commands:
**
** CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
** CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
**
** After this the functions will work exactly like native MySQL functions.
** Functions should be created only once.
**
** The functions can be deleted by:
**
** DROP FUNCTION lookup;
** DROP FUNCTION reverse_lookup;
**
** The CREATE FUNCTION and DROP FUNCTION update the func@mysql table. All
** Active function will be reloaded on every restart of server
** (if --skip-grant-tables is not given)
**
*/

#ifdef STANDARD
#include <stdio.h>
#include <string.h>
#else
#include <global.h>
#include <my_sys.h>
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>  // To get strmov()

#ifdef HAVE_DLOPEN

/****************************************************************************
** Some functions that handles IP and hostname conversions
** The orignal function was from Zeev Suraski.
**
** CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
** CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
**
****************************************************************************/

#if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

extern "C" {
my_bool lookup_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *lookup(UDF_INIT *initid, UDF_ARGS *args, char *result,
      unsigned long *length, char *null_value, char *error);
my_bool reverse_lookup_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result,
       unsigned long *length, char *null_value, char *error);
}


/****************************************************************************
** lookup IP for an hostname.
**
** This code assumes that gethostbyname_r exists and inet_ntoa() is thread
** safe (As it is in Solaris)
****************************************************************************/


my_bool lookup_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
  if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT)
  {
    strmov(message,"Wrong arguments to lookup;  Use the source");
    return 1;
  }
  initid->max_length=11;
  initid->maybe_null=1;
  return 0;
}

char *lookup(UDF_INIT *initid, UDF_ARGS *args, char *result,
      unsigned long *res_length, char *null_value, char *error)
{
  uint length;
  int tmp_errno;
  char name_buff[256],hostname_buff[2048];
  struct hostent tmp_hostent,*hostent;

  if (!args->args[0] || !(length=args->lengths[0]))
  {
    *null_value=1;
    return 0;
  }
  if (length >= sizeof(name_buff))
    length=sizeof(name_buff)-1;
  memcpy(name_buff,args->args[0],length);
  name_buff[length]=0;

  if (!(hostent=gethostbyname_r(name_buff,&tmp_hostent,hostname_buff,
    sizeof(hostname_buff), &tmp_errno)))
  {
    *null_value=1;
    return 0;
  }
  struct in_addr in;
  memcpy((char*) &in,(char*) *hostent->h_addr_list, sizeof(in.s_addr));
  *res_length= (ulong) (strmov(result, inet_ntoa(in)) - result);
  return result;
}


/****************************************************************************
** return hostname for an IP number.
** The functions can take as arguments a string "xxx.xxx.xxx.xxx" or
** four numbers.
****************************************************************************/

my_bool reverse_lookup_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
  if (args->arg_count == 1)
    args->arg_type[0]= STRING_RESULT;
  else if (args->arg_count == 4)
    args->arg_type[0]=args->arg_type[1]=args->arg_type[2]=args->arg_type[3]=
      INT_RESULT;
  else
  {
    strmov(message,
    "Wrong number of arguments to reverse_lookup;  Use the source");
    return 1;
  }
  initid->max_length=32;
  initid->maybe_null=1;
  return 0;
}


char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result,
       unsigned long *res_length, char *null_value, char *error)
{
  char name_buff[256];
  struct hostent tmp_hostent;
  uint length;

  if (args->arg_count == 4)
  {
    if (!args->args[0] || !args->args[1] ||!args->args[2] ||!args->args[3])
    {
      *null_value=1;
      return 0;
    }
    sprintf(result,"%d.%d.%d.%d",
     (int) *((long long*) args->args[0]),
     (int) *((long long*) args->args[1]),
     (int) *((long long*) args->args[2]),
     (int) *((long long*) args->args[3]));
  }
  else
  {      // string argument
    if (!args->args[0])    // Return NULL for NULL values
    {
      *null_value=1;
      return 0;
    }
    length=args->lengths[0];
    if (length >= (uint) *res_length-1)
      length=(uint) *res_length;
    memcpy(result,args->args[0],length);
    result[length]=0;
  }

  unsigned long taddr = inet_addr(result);
  if (taddr == (unsigned long) -1L)
  {
    *null_value=1;
    return 0;
  }
  struct hostent *hp;
  int tmp_errno;
  if (!(hp=gethostbyaddr_r((char*) &taddr,sizeof(taddr), AF_INET,
      &tmp_hostent, name_buff,sizeof(name_buff),
      &tmp_errno)))
  {
    *null_value=1;
    return 0;
  }
  *res_length=(ulong) (strmov(result,hp->h_name) - result);
  return result;
}

#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)
#endif /* HAVE_DLOPEN */

[Top]
No.
제목
작성자
작성일
조회
21136MySQL UDF -- Unix user interface
정재익
2004-02-24
12220
21133MySQL UDF -- square()
정재익
2004-02-24
11411
21132MySQL UDF -- soundex
정재익
2004-02-24
10516
21129MySQL UDF -- ip lookup
정재익
2004-02-24
10830
21128MySQL UDF -- unprefix
정재익
2004-02-24
10210
21125MySQL UDF -- ip address manipulation
정재익
2004-02-24
8966
21119MySQL UDF -- corba_string
정재익
2004-02-24
8409
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2023 DSN, All rights reserved.
작업시간: 0.054초, 이곳 서비스는
	PostgreSQL v16.1로 자료를 관리합니다