1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
/* $Id: network.c,v 1.12 2003/09/23 19:55:52 jfontain Exp $ */
/* to create the loadable library, use: cc -shared -o libnetwork.so.1.20 -O2 -fPIC -Wall network.c */
/* with stubs: cc -shared -o libnetwork.so.1.20 -O2 -fPIC -Wall -DUSE_TCL_STUBS network.c /usr/lib/libtclstub8.3.a */
/* pkgIndex.tcl: package ifneeded network 1.20 [list load [file join $dir libnetwork.so.1.20]] */
#include <tcl.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/route.h>
static int hostFromAddress(ClientData clientData, Tcl_Interp *interpreter, int numberOfArguments, Tcl_Obj * CONST arguments[])
{
struct hostent *hostEntry;
struct in_addr address;
if(numberOfArguments != 2){
Tcl_WrongNumArgs(interpreter, 1, arguments, "address");
return TCL_ERROR;
}
if(inet_aton(Tcl_GetStringFromObj(arguments[1], 0), &address) == 0){
Tcl_SetObjResult(interpreter, Tcl_NewStringObj("invalid address", -1));
return TCL_ERROR;
}
hostEntry = gethostbyaddr((char *)&address, sizeof(address), AF_INET);
if(hostEntry == 0){
Tcl_SetObjResult(interpreter, Tcl_NewStringObj((char *)hstrerror(h_errno), -1)); /* core takes care of freeing object */
return TCL_ERROR;
}
Tcl_SetObjResult(interpreter, Tcl_NewStringObj(hostEntry->h_name, -1)); /* core takes care of freeing object */
return TCL_OK;
}
static int addressFromHost(ClientData clientData, Tcl_Interp *interpreter, int numberOfArguments, Tcl_Obj * CONST arguments[])
{
struct hostent *hostEntry;
struct in_addr address;
if(numberOfArguments != 2){
Tcl_WrongNumArgs(interpreter, 1, arguments, "host");
return TCL_ERROR;
}
hostEntry = gethostbyname(Tcl_GetStringFromObj(arguments[1], 0));
if(hostEntry == 0){
Tcl_SetObjResult(interpreter, Tcl_NewStringObj((char *)hstrerror(h_errno), -1)); /* core takes care of freeing object */
return TCL_ERROR;
}
memcpy(&address, hostEntry->h_addr, sizeof address);
Tcl_SetObjResult(interpreter, Tcl_NewStringObj(inet_ntoa(address), -1)); /* core takes care of freeing object */
return TCL_OK;
}
static int networkFromAddress(ClientData clientData, Tcl_Interp *interpreter, int numberOfArguments, Tcl_Obj * CONST arguments[])
{
unsigned long network;
struct netent *networkEntry;
if(numberOfArguments != 2){
Tcl_WrongNumArgs(interpreter, 1, arguments, "address");
return TCL_ERROR;
}
network = inet_network(Tcl_GetStringFromObj(arguments[1], 0));
if(network < 0) {
Tcl_SetObjResult(interpreter, Tcl_NewStringObj("invalid address", -1));
return TCL_ERROR;
}
networkEntry = getnetbyaddr(network, AF_INET);
if(networkEntry == 0){
Tcl_SetObjResult(interpreter, Tcl_NewStringObj((char *)hstrerror(h_errno), -1)); /* core takes care of freeing object */
return TCL_ERROR;
}
Tcl_SetObjResult(interpreter, Tcl_NewStringObj(networkEntry->n_name, -1)); /* core takes care of freeing object */
return TCL_OK;
}
static int routeLetterFlags(ClientData clientData, Tcl_Interp *interpreter, int numberOfArguments, Tcl_Obj * CONST arguments[])
{ /* sole argument is bit encoded value from /proc/net/route, as documented in /usr/include/linux/route.h */
unsigned bits;
char letters[33]; /* 32 bits plus zero terminator */
char *letter;
if(numberOfArguments != 2){
Tcl_WrongNumArgs(interpreter, 1, arguments, "integer");
return TCL_ERROR;
}
if(Tcl_GetIntFromObj(interpreter, arguments[1], &bits) == TCL_ERROR)
return TCL_ERROR;
letter = letters; /* return flags in alphabetical order: */
if(bits & RTF_DYNAMIC){*(letter++) = 'D';}
if(bits & RTF_GATEWAY){*(letter++) = 'G';}
if(bits & RTF_HOST){*(letter++) = 'H';}
if(bits & RTF_MODIFIED){*(letter++) = 'M';}
#ifdef RTF_REINSTATE
if(bits & RTF_REINSTATE){*(letter++) = 'R';}
#endif
if(bits & RTF_UP){*(letter++) = 'U';}
if(bits & RTF_REJECT){*(letter++) = '!';}
Tcl_SetObjResult(interpreter, Tcl_NewStringObj(letters, letter - letters)); /* core takes care of freeing object */
return TCL_OK;
}
EXTERN int Network_Init(Tcl_Interp *interpreter) /* create all commands in network namespace */
{
#ifdef USE_TCL_STUBS
if (Tcl_InitStubs(interpreter, "8.1", 0) == NULL) {
return TCL_ERROR;
}
#endif
Tcl_CreateObjCommand(interpreter, "::network::hostfromaddress", hostFromAddress, 0, 0);
Tcl_CreateObjCommand(interpreter, "::network::addressfromhost", addressFromHost, 0, 0);
Tcl_CreateObjCommand(interpreter, "::network::networkfromaddress", networkFromAddress, 0, 0);
Tcl_CreateObjCommand(interpreter, "::network::routeletterflags", routeLetterFlags, 0, 0);
return TCL_OK; /* the package provide command is invoked in the related network.tcl file */
}
EXTERN int Network_SafeInit(Tcl_Interp *interpreter)
{
return Network_Init(interpreter); /* all commands are safe */
}
|