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
|
/* $Id: network.c,v 1.5 1998/12/26 11:07:02 jfontain Exp $ */
/* to create the loadable library, use: cc -shared -o libnetwork.so.1.0 -O2 -fPIC -Wall network.c */
/* pkgIndex.tcl: package ifneeded network 1.0 "load [file join $dir libnetwork.so.1.0]" */
#include <tcl.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/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 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';}
if(bits & RTF_REINSTATE){*(letter++) = 'R';}
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;
}
int Network_Init(Tcl_Interp *interpreter) /* create all commands in network namespace */
{
Tcl_CreateObjCommand(interpreter, "::network::hostfromaddress", hostFromAddress, 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 */
}
int Network_SafeInit(Tcl_Interp *interpreter)
{
return Network_Init(interpreter); /* all commands are safe */
}
|