ipMoreC.tcl

Go to the documentation of this file.
00001 /*  Skip this for window and a specific version of Solaris*/
00002 /*  */
00003 /*  This could do with an explanation -- why are we avoiding these platforms*/
00004 /*  and perhaps using critcl's platform::platform command might be better?*/
00005 /* */
00006 if {[string equal $::tcl_platform(platform) windows] ||
00007     ([string equal $::tcl_platform(os)      SunOS] &&
00008      [string equal $::tcl_platform(osVersion) 5.6])
00009 } {
00010     /*  avoid warnings about nothing to compile*/
00011     critcl::ccode {
00012         /* nothing to do */
00013     }
00014     return
00015 }
00016 
00017 package require critcl;
00018 
00019 namespace ::ip {
00020 
00021 critcl::ccode {
00022 /* include <stdlib.h>*/
00023 /* include <stdio.h>*/
00024 /* include <tcl.h>*/
00025 /* include <inttypes.h>*/
00026 /* include <arpa/inet.h>*/
00027 /* include <string.h>*/
00028 /* include <sys/socket.h>*/
00029 }
00030 
00031 critcl::ccommand prefixToNativec {clientData interp objc objv} { 
00032     int elemLen, maskLen, ipLen, mask;
00033     int rval,convertListc,i;
00034     Tcl_Obj **convertListv;
00035     Tcl_Obj *listPtr,*returnPtr, *addrList;
00036     char *stringIP, *slashPos, *stringMask;
00037     char v4HEX[11];
00038     
00039     uint32_t inaddr;
00040     listPtr = NULL;
00041 
00042     /* printf ("\n in prefixToNativeC"); */
00043     /* printf ("\n objc = %d",objc); */
00044 
00045     if (objc != 2) {
00046         Tcl_WrongNumArgs(interp, 1, objv, "<ipaddress>/<mask>");
00047         return TCL_ERROR;
00048     }
00049 
00050 
00051     if (Tcl_ListObjGetElements (interp, objv[1], 
00052                                 &convertListc, &convertListv) != TCL_OK) {
00053         return TCL_ERROR;
00054     }
00055     returnPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
00056     for (i = 0; i < convertListc; i++) {
00057         /*  need to create a duplicate here because when we modify */
00058         /*  the stringIP it'll mess up the original in the calling */
00059         /*  context */
00060         addrList = Tcl_DuplicateObj(convertListv[i]);
00061         stringIP = Tcl_GetStringFromObj(addrList, &elemLen);
00062         listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
00063         /* printf ("\n  /*  %s ### string \n", stringIP); */*/
00064         /*  split the ip address and mask */
00065         slashPos = strchr(stringIP, (int) '/');
00066         if (slashPos == NULL) {
00067             /*  straight ip address without mask */
00068             mask = 0xffffffff;
00069             ipLen = strlen(stringIP);
00070         } else {
00071             /* ipaddress has the mask, handle the mask and seperate out the  */
00072             /*  ip address */
00073             /* printf ("\n ** %d ",(uintptr_t)slashPos); */
00074             stringMask = slashPos +1;
00075             maskLen =strlen(stringMask);
00076             /* put mask in hex form */
00077             if (maskLen < 3) {
00078                 mask = atoi(stringMask);
00079                 mask = (0xFFFFFFFF << (32 - mask)) & 0xFFFFFFFF;
00080             } else {
00081                 /* mask is in dotted form */
00082                 if ((rval = inet_pton(AF_INET,stringMask,&mask)) < 1 ) {
00083                     Tcl_AddErrorInfo(interp, "\n    bad format encountered in mask conversion");
00084                     return TCL_ERROR;   
00085                 }
00086                 mask = htonl(mask);
00087             }
00088             ipLen = (uintptr_t)slashPos  - (uintptr_t)stringIP;
00089             /* divide the string into ip and mask portion */
00090             *slashPos = '\0';
00091             /* printf("\n %d %d %d %d", (uintptr_t)stringMask, maskLen, (uintptr_t)stringIP, ipLen); */
00092         }
00093         if ( (rval = inet_pton(AF_INET,stringIP,&inaddr)) < 1) {
00094             Tcl_AddErrorInfo(interp, 
00095                              "\n    bad format encountered in ip conversion");
00096             return TCL_ERROR;
00097         };
00098         inaddr = htonl(inaddr);
00099         /* apply the mask the to the ip portion, just to make sure  */
00100         /*  what we return is cleaned up */
00101         inaddr = inaddr & mask;
00102         sprintf(v4HEX,"0x%08X",inaddr);
00103         /* printf ("\n\n /*  %s",v4HEX); */*/
00104         Tcl_ListObjAppendElement(interp, listPtr,
00105                                  Tcl_NewStringObj(v4HEX,-1));
00106         sprintf(v4HEX,"0x%08X",mask);
00107         Tcl_ListObjAppendElement(interp, listPtr,
00108                                  Tcl_NewStringObj(v4HEX,-1));
00109         Tcl_ListObjAppendElement(interp, returnPtr, listPtr);
00110         Tcl_DecrRefCount(addrList);
00111     }
00112     
00113     if (convertListc==1) {
00114         Tcl_SetObjResult(interp,listPtr);
00115     } else {
00116         Tcl_SetObjResult(interp,returnPtr);
00117     }
00118     
00119     return TCL_OK;
00120 }
00121 
00122 critcl::ccommand isOverlapNativec {clientData interp objc objv} {
00123         int i; 
00124         unsigned int ipaddr,ipMask, mask1mask2;
00125         unsigned int ipaddr2,ipMask2;
00126         int compareListc,comparePrefixMaskc;
00127         int allSet,inlineSet,index;
00128         Tcl_Obj **compareListv,**comparePrefixMaskv, *listPtr;
00129         Tcl_Obj *result;
00130     static CONST char *options[] = {
00131                 "-all",     "-inline", "-ipv4", NULL
00132     };
00133     enum options {
00134         OVERLAP_ALL, OVERLAP_INLINE, OVERLAP_IPV4
00135     };
00136 
00137         allSet = 0;
00138         inlineSet = 0;
00139         listPtr = NULL;
00140 
00141         /* printf ("\n objc = %d",objc); */
00142         if (objc < 3) {
00143                 Tcl_WrongNumArgs(interp, 1, objv, "?options? <hexIP> <hexMask> <hexList>");
00144                 return TCL_ERROR;
00145         }
00146         for (i = 1; i < objc-3; i++) {
00147            if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
00148                    != TCL_OK) {
00149                    return TCL_ERROR;
00150            }
00151            switch (index) {
00152            case OVERLAP_ALL:
00153                    allSet = 1;
00154                    /* printf ("\n all selected"); */
00155                    break;
00156            case OVERLAP_INLINE:
00157                    inlineSet = 1;
00158                    /* printf ("\n inline selected"); */
00159                    break;
00160            case OVERLAP_IPV4:
00161                break;
00162            }
00163         }
00164         /* options are parsed */
00165 
00166         /* create return obj */
00167         result = Tcl_GetObjResult (interp);
00168 
00169         /*  ipaddr =  and ipmask */
00170         Tcl_GetIntFromObj(interp,objv[objc-3],&ipaddr);
00171         Tcl_GetIntFromObj(interp,objv[objc-2],&ipMask);
00172 
00173         /* split the 3rd argument into <ipaddr> <mask> pairs */
00174         if (Tcl_ListObjGetElements (interp, objv[objc-1], &compareListc, &compareListv) != TCL_OK) {
00175                 return TCL_ERROR;
00176         }
00177 /*       printf("comparing %x/%x \n",ipaddr,ipMask); */
00178 
00179         if (allSet || inlineSet) {
00180                 listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
00181         }
00182 
00183         for (i = 0; i < compareListc; i++) {
00184                         /* split the ipaddr2 and ipmask2  */
00185                 if (Tcl_ListObjGetElements (interp, 
00186                         compareListv[i], 
00187                         &comparePrefixMaskc, 
00188                         &comparePrefixMaskv) != TCL_OK) {
00189             return TCL_ERROR;
00190                 }
00191                 if (comparePrefixMaskc != 2) {
00192             Tcl_AddErrorInfo(interp,"need format {{<ipaddr> <mask>} {<ipad..}}");
00193                         return TCL_ERROR;
00194                 }
00195                 Tcl_GetIntFromObj(interp,comparePrefixMaskv[0],&ipaddr2);
00196                 Tcl_GetIntFromObj(interp,comparePrefixMaskv[1],&ipMask2);
00197 /*               printf(" with %x/%x \n",ipaddr2,ipMask2); */
00198                 mask1mask2 = ipMask & ipMask2;
00199 /*               printf("  mask1mask2 %x \n",mask1mask2); */
00200 /*               printf("  ipaddr & mask1mask2  %x\n",ipaddr & mask1mask2); */
00201 /*               printf("  ipaddr2 & mask1mask2 %x\n",ipaddr2 & mask1mask2); */
00202                 if ((ipaddr & mask1mask2) == (ipaddr2 & mask1mask2)) {
00203             if (allSet) {
00204             if (inlineSet) {
00205                 Tcl_ListObjAppendElement(interp, listPtr,
00206                              compareListv[i]);
00207             } else {
00208                 /* printf("\n appending %d",i+1); */
00209                 Tcl_ListObjAppendElement(interp, listPtr,
00210                              Tcl_NewIntObj(i+1));
00211             };
00212             } else {
00213             if (inlineSet) {
00214                 Tcl_ListObjAppendElement(interp, listPtr,
00215                              compareListv[i]);
00216                 Tcl_SetObjResult(interp,listPtr);
00217             } else {
00218                 Tcl_SetIntObj (result, i+1);
00219             }
00220             return TCL_OK;
00221             };
00222                 };
00223                     };
00224 
00225         if (allSet || inlineSet) {
00226                 Tcl_SetObjResult(interp, listPtr);
00227                 return TCL_OK;
00228         } else {
00229                 Tcl_SetIntObj (result, 0);
00230                 return TCL_OK;
00231         }
00232         return TCL_OK;
00233 
00234 
00235 
00236 }
00237 
00238 
00239 }
00240 
00241 package provide ipMorec 1.0
00242 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1