File: network.c

package info (click to toggle)
moodss 19.7-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 6,136 kB
  • ctags: 3,149
  • sloc: tcl: 49,048; ansic: 187; perl: 178; makefile: 166; sh: 109; python: 65
file content (123 lines) | stat: -rw-r--r-- 5,412 bytes parent folder | download
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 */
}