"Fossies" - the Fresh Open Source Software Archive

Member "trafshow-5.2.3/colormask.c" (5 Apr 2004, 13683 Bytes) of package /linux/misc/old/trafshow-5.2.3.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "colormask.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *  Copyright (c) 1993-1997,2004 Rinet Corp., Novosibirsk, Russia
    3  *
    4  * Redistribution and use in source forms, with and without modification,
    5  * are permitted provided that this entire comment appears intact.
    6  * Redistribution in binary form may occur without any restrictions.
    7  *
    8  * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
    9  */
   10 
   11 #ifdef  HAVE_CONFIG_H
   12 #include <config.h>
   13 #endif
   14 
   15 #ifdef  HAVE_HAS_COLORS
   16 
   17 #ifdef  HAVE_SLCURSES
   18 #include <slcurses.h>
   19 #elif   HAVE_NCURSES
   20 #include <ncurses.h>
   21 #else
   22 #include <curses.h>
   23 #endif
   24 #include <sys/param.h>
   25 #include <sys/types.h>
   26 #include <sys/socket.h>
   27 #include <netinet/in.h>
   28 #include <arpa/inet.h>
   29 #include <stdio.h>
   30 #include <stdlib.h>
   31 #include <string.h>
   32 #include <unistd.h>
   33 #include <ctype.h>
   34 #include <netdb.h>
   35 #include <errno.h>
   36 
   37 #include "colormask.h"
   38 #include "trafshow.h"
   39 #include "netstat.h"
   40 #ifdef  DEBUG
   41 #include "show_stat.h" /* just for hdr2str() */
   42 #endif
   43 
   44 /* mask entry */
   45 struct cm_entry {
   46     struct internet_header in_hdr;
   47     int src_mask;       /* source ip address mask */
   48     int dst_mask;       /* destination ip address mask */
   49 
   50     short   pair;       /* color-pair */
   51     int     attr;       /* video attributes; bold, blink, etc */
   52 };
   53 
   54 static struct cm_entry *color_mask = NULL;
   55 static int n_masks = 0;
   56 static int n_pairs = 0;
   57 static const char *rc_file = 0;
   58 static int rc_line;
   59 
   60 /* SLcurses can't handle attributes as well; so hack it */
   61 #ifdef  HAVE_SLCURSES
   62 static void
   63 slang_init_pair(short pair, short fc, short bc, int at)
   64 {
   65     SLtt_set_color_object(pair, ((fc | (bc << 8)) << 8) | at);
   66 }
   67 
   68 static int
   69 slang_pair_content(short pair, short *fc, short *bc)
   70 {
   71     int attr;
   72     SLtt_Char_Type at;
   73 
   74     at = SLtt_get_color_object(pair);
   75     attr = at & (A_BOLD | A_BLINK);
   76     at &= ~(A_BOLD | A_BLINK);
   77     at >>= 8;
   78     *fc = at & 0xff;
   79     *bc = (at >> 8) & 0xff;
   80 
   81     return attr;
   82 }
   83 #endif  /* HAVE_SLCURSES */
   84 
   85 static short
   86 findpair(short f, short b, int a)
   87 {
   88     int i;
   89     short f1 = -1, b1 = -1;
   90     struct cm_entry *cm;
   91 
   92     for (cm = color_mask, i = 0; cm != NULL && i < n_masks-1; cm++, i++) {
   93 #ifdef  HAVE_SLCURSES
   94         int a1 = slang_pair_content(cm->pair, &f1, &b1);
   95         if (f1 >= COLORS) f1 = -1;
   96         if (b1 >= COLORS) b1 = -1;
   97         if (f == f1 && b == b1 && a == a1) return cm->pair;
   98 #else
   99         pair_content(cm->pair, &f1, &b1);
  100         if (f1 >= COLORS) f1 = -1;
  101         if (b1 >= COLORS) b1 = -1;
  102         if (f == f1 && b == b1) return cm->pair;
  103 #endif
  104     }
  105     return 0;
  106 }
  107 
  108 static int
  109 add_colormask(const char *s, struct cm_entry *m)
  110 {
  111     int i, attr = 0;
  112     short fc, bc;
  113     char f[100], *b;
  114     static char *ctab[8] = { "black", "red", "green", "yellow",
  115                 "blue", "magenta", "cyan", "white" };
  116 #ifdef  HAVE_USE_DEFAULT_COLORS
  117     static short fc_def = -1, bc_def = -1;
  118 #else
  119     static short fc_def = COLOR_WHITE, bc_def = COLOR_BLACK;
  120 #endif
  121 
  122     if ((b = strchr(strcpy(f, s), ':')) != NULL) *b++ = '\0';
  123 
  124     if (*f) {
  125         for (i = 0; i < 8; i++)
  126             if (!strcasecmp(ctab[i], f)) break;
  127         if (i < 8) fc = i;
  128         else {
  129             fc = atoi(f);
  130             if (fc < 1 || fc > COLORS) {
  131                 fprintf(stderr, "%s: line %d: Unknown color `%s'\n",
  132                     rc_file, rc_line, f);
  133                 return -1;
  134             }
  135         }
  136         if (isupper((int)*f)) attr |= A_BOLD;
  137     } else fc = fc_def;
  138 
  139     if (b && *b) {
  140         for (i = 0; i < 8; i++)
  141             if (!strcasecmp(ctab[i], b)) break;
  142         if (i < 8) bc = i;
  143         else {
  144             bc = atoi(b);
  145             if (bc < 1 || bc > COLORS) {
  146                 fprintf(stderr, "%s: line %d: Unknown color `%s'\n",
  147                     rc_file, rc_line, b);
  148                 return -1;
  149             }
  150         }
  151         if (isupper((int)*b)) attr |= A_BLINK;
  152     } else bc = bc_def;
  153 
  154     if (m != NULL) {
  155         if ((color_mask = realloc(color_mask, ++n_masks * sizeof(struct cm_entry))) == NULL) {
  156             fprintf(stderr, "add_colormask: realloc: Out of memory?\n");
  157             return -1;
  158         }
  159         if ((m->pair = findpair(fc, bc, attr)) == 0) {
  160             if (++n_pairs < COLOR_PAIRS-1) {
  161 #ifdef  HAVE_SLCURSES
  162                 slang_init_pair(n_pairs, fc, bc, attr);
  163 #else
  164                 init_pair(n_pairs, fc, bc);
  165 #endif
  166             } else {
  167                 fprintf(stderr, "%s: line %d: Max %d color-pairs can be used\n",
  168                     rc_file, rc_line, COLOR_PAIRS-1);
  169                 return -1;
  170             }
  171             m->pair = n_pairs;
  172         }
  173         m->attr = attr;
  174         memcpy(color_mask + (n_masks-1), m, sizeof(struct cm_entry));
  175     } else {    /* default colors */
  176 #ifdef  HAVE_SLCURSES
  177         slang_init_pair(0, fc, bc, attr);
  178 #else
  179 #ifdef  HAVE_BKGD
  180         init_pair(COLOR_PAIRS-1, fc, bc);
  181         bkgd(COLOR_PAIR(COLOR_PAIRS-1) | attr);
  182 #elif   HAVE_WBKGD
  183         init_pair(COLOR_PAIRS-1, fc, bc);
  184         wbkgd(stdscr, COLOR_PAIR(COLOR_PAIRS-1) | attr);
  185 #else /* assume the color-pair 0 is background for whole screen */
  186         init_pair(0, fc, bc);
  187 #endif
  188 #endif
  189         fc_def = fc;
  190         bc_def = bc;
  191     }
  192     return 0;
  193 }
  194 
  195 static int
  196 is_any(const char *s)
  197 {
  198     if (!s || !*s) return 0;
  199     return (!strcmp(s, "*") || !strcasecmp(s, "any") || !strcasecmp(s, "all"));
  200 }
  201 
  202 static int
  203 is_number(const char *s)
  204 {
  205     if (!s || !*s) return 0;
  206     for (; *s; s++) {
  207         if (!isdigit((int)*s)) return 0;
  208     }
  209     return 1;
  210 }
  211 
  212 static char *
  213 str2proto(const char *str, int *proto)
  214 {
  215     int num;
  216     struct protoent *pe;
  217 
  218     if (is_any(str)) {
  219         *proto = 0;
  220         return "";
  221     }
  222     if (is_number(str)) {
  223         num = atoi(str);
  224         if (num > 0 && num <= 0xff) {
  225             if ((pe = getprotobynumber(num)) != 0) {
  226                 *proto = pe->p_proto;
  227                 return pe->p_name;
  228             }
  229             *proto = num;
  230             return "";
  231         }
  232     }
  233     if ((pe = getprotobyname(str)) != 0) {
  234         *proto = pe->p_proto;
  235         return pe->p_name;
  236     }
  237     fprintf(stderr, "%s: line %d: Unknown protocol `%s'\n",
  238         rc_file, rc_line, str);
  239     return 0;
  240 }
  241 
  242 static int
  243 str2port(const char *str, const char *proto)
  244 {
  245     int num;
  246     struct servent *se;
  247 
  248     if (is_any(str))
  249         return 0;
  250 
  251     num = atoi(str);
  252     if (num > 0 && num <= 0xffff)
  253         return htons((u_int16_t)num);
  254 
  255     if ((se = getservbyname(str, (proto && *proto) ? proto : 0)) != 0)
  256         return se->s_port;
  257 
  258     if (proto && *proto) {
  259         fprintf(stderr, "%s: line %d: Unknown port `%s' at protocol `%s'\n",
  260             rc_file, rc_line, str, proto);
  261     } else {
  262         fprintf(stderr, "%s: line %d: Unknown port `%s'\n",
  263             rc_file, rc_line, str);
  264     }
  265     return -1;
  266 }
  267 
  268 static int
  269 str2addr(const char *str, const char *proto, struct ip_address *addr, int *mask)
  270 {
  271     int op, ver = 0;
  272     char buf[256], *cp, *mp, *pp;
  273 
  274     if (proto && !strcasecmp(proto, "IPv6")) {
  275 #ifdef INET6
  276         ver = 6;
  277 #else
  278         fprintf(stderr, "%s: line %d: IPv6 is unsupported at this system\n",
  279             rc_file, rc_line);
  280         return -1;
  281 #endif
  282     }
  283     cp = strcpy(buf, str);
  284     if ((mp = strchr(cp, '/')) != 0) {
  285         *mp++ = '\0';
  286         cp = mp;
  287     }
  288     if ((pp = strchr(cp, ',')) != 0) {
  289         *pp++ = '\0';
  290     }
  291     if (mp && !is_number(mp)) {
  292         fprintf(stderr, "%s: line %d: %s: Mask must be number of bits\n",
  293             rc_file, rc_line, mp);
  294         return -1;
  295     }
  296     if (!is_any(buf)) {
  297         op = 0;
  298 #ifdef INET6
  299         if (ver == 6 || strchr(buf, ':')) {
  300             ver = 6;
  301             op = inet_pton(AF_INET6, buf, &addr->ip6_addr);
  302             if (op < 0) {
  303                 fprintf(stderr, "%s: line %d: %s: %s\n",
  304                     rc_file, rc_line, buf, strerror(errno));
  305                 return -1;
  306             }
  307         }
  308 #endif
  309         if (!op) {
  310             ver = 4;
  311             op = inet_pton(AF_INET, buf, &addr->ip_addr);
  312             if (op < 0) {
  313                 fprintf(stderr, "%s: line %d: %s: %s\n",
  314                     rc_file, rc_line, buf, strerror(errno));
  315                 return -1;
  316             }
  317         }
  318         if (!op) {
  319             struct hostent *he;
  320             if ((he = gethostbyname(buf)) == 0) {
  321                 fprintf(stderr, "%s: line %d: %s: Unknown host\n",
  322                     rc_file, rc_line, buf);
  323                 return -1;
  324             }
  325             if (he->h_addrtype == AF_INET) {
  326                 ver = 4;
  327                 memcpy(&addr->ip_addr, he->h_addr,
  328                        MIN(sizeof(addr->ip_addr), he->h_length));
  329             }
  330 #ifdef INET6
  331             else if (he->h_addrtype == AF_INET6) {
  332                 ver = 6;
  333                 memcpy(&addr->ip6_addr, he->h_addr,
  334                        MIN(sizeof(addr->ip6_addr), he->h_length));
  335             }
  336 #endif
  337             else {
  338                 fprintf(stderr, "%s: line %d: %s: Unknown address family\n",
  339                     rc_file, rc_line, buf);
  340                 return -1;
  341             }
  342         }
  343     }
  344     if (pp) {
  345         if ((op = str2port(pp, proto)) == -1)
  346             return -1;
  347         addr->ip_port = op;
  348     }
  349     if (mask) {
  350         if (mp) {
  351             op = atoi(mp);
  352             if (op < 8 || op > 128) {
  353                 fprintf(stderr, "%s: line %d: %d: Wrong mask\n",
  354                     rc_file, rc_line, op);
  355                 return -1;
  356             }
  357             *mask = op;
  358         } else  *mask = 0;
  359     }
  360     return ver;
  361 }
  362 
  363 int
  364 init_colormask()
  365 {
  366     FILE *fp;
  367     int num;
  368     struct cm_entry me, *cm;
  369     char *cp, buf[1024];
  370     char s1[256], s2[256], s3[256], s4[256];
  371 
  372     if (rc_file) {
  373         free((char *)rc_file);
  374         rc_file = 0;
  375     }
  376     if (!color_conf) {
  377         if ((cp = getenv("HOME")) != 0) {
  378             (void)strcpy(buf, cp);
  379             (void)strcat(buf, "/");
  380         } else  buf[0] = '\0';
  381         (void)strcat(buf, ".");
  382         (void)strcat(buf, progname);
  383         if ((fp = fopen(buf, "r")) == NULL) {
  384             (void)strcpy(buf, "/etc/");
  385             (void)strcat(buf, progname);
  386             if ((fp = fopen(buf, "r")) == NULL) return 0;
  387         }
  388         rc_file = strdup(buf);
  389     } else {
  390         if ((fp = fopen(color_conf, "r")) == NULL) {
  391             fprintf(stderr, "%s: %s\n", color_conf, strerror(errno));
  392             return -1;
  393         }
  394         rc_file = strdup(color_conf);
  395     }
  396     if (!rc_file) {
  397         fprintf(stderr, "init_colormask: strdup: Out of memory?\n");
  398         (void)fclose(fp);
  399         return -1;
  400     }
  401     rc_line = 0;
  402     cm = &me;
  403 
  404 #ifdef  HAVE_USE_DEFAULT_COLORS
  405     use_default_colors();
  406 #endif
  407     while (fgets(buf, sizeof(buf), fp) != NULL) {
  408         rc_line++;
  409         if (buf[0] == '\n' || buf[0] == '#') continue;
  410         if ((cp = strchr(buf, '#')) != NULL) {
  411             *cp++ = '\n';
  412             *cp = '\0';
  413         }
  414         memset(cm, 0, sizeof(struct cm_entry));
  415         num = sscanf(buf, "%s %s %s %s\n", s1, s2, s3, s4);
  416         if (num == 2) {
  417             if (strcasecmp(s1, "default")) {
  418                 if ((cp = strchr(s1, '/')) != 0) {
  419                     *cp++ = '\0';
  420                     if ((cp = str2proto(cp, &num)) == 0) {
  421                         (void)fclose(fp);
  422                         return -1;
  423                     }
  424                     cm->in_hdr.proto = num;
  425                 }
  426                 if ((num = str2port(s1, cp)) == -1) {
  427                     (void)fclose(fp);
  428                     return -1;
  429                 }
  430                 cm->in_hdr.src.ip_port = num;
  431                 cm->in_hdr.dst.ip_port = 0;
  432                 if (add_colormask(s2, cm) < 0) {
  433                     (void)fclose(fp);
  434                     return -1;
  435                 }
  436                 cm->in_hdr.src.ip_port = 0;
  437                 cm->in_hdr.dst.ip_port = num;
  438                 if (add_colormask(s2, cm) < 0) {
  439                     (void)fclose(fp);
  440                     return -1;
  441                 }
  442             } else if (add_colormask(s2, 0) < 0) {
  443                 (void)fclose(fp);
  444                 return -1;
  445             }
  446         } else if (num == 3) {
  447             num = str2addr(s1, 0, &cm->in_hdr.src, &cm->src_mask);
  448             if (num == -1) {
  449                 (void)fclose(fp);
  450                 return -1;
  451             }
  452             cm->in_hdr.ver = num;
  453             num = str2addr(s2, 0, &cm->in_hdr.dst, &cm->dst_mask);
  454             if (num == -1) {
  455                 (void)fclose(fp);
  456                 return -1;
  457             }
  458             if (!cm->in_hdr.ver) {
  459                 cm->in_hdr.ver = num;
  460             } else if (num && num != cm->in_hdr.ver) {
  461                 fprintf(stderr, "%s: line %d: Addresses family mismatch\n",
  462                     rc_file, rc_line);
  463                 (void)fclose(fp);
  464                 return -1;
  465             }
  466             if (add_colormask(s3, cm) < 0) {
  467                 (void)fclose(fp);
  468                 return -1;
  469             }
  470         } else if (num == 4) {
  471             if ((cp = str2proto(s1, &num)) == 0) {
  472                 (void)fclose(fp);
  473                 return -1;
  474             }
  475             cm->in_hdr.proto = num;
  476             num = str2addr(s2, cp, &cm->in_hdr.src, &cm->src_mask);
  477             if (num == -1) {
  478                 (void)fclose(fp);
  479                 return -1;
  480             }
  481             cm->in_hdr.ver = num;
  482             num = str2addr(s3, cp, &cm->in_hdr.dst, &cm->dst_mask);
  483             if (num == -1) {
  484                 (void)fclose(fp);
  485                 return -1;
  486             }
  487             if (!cm->in_hdr.ver) {
  488                 cm->in_hdr.ver = num;
  489             } else if (num && num != cm->in_hdr.ver) {
  490                 fprintf(stderr, "%s: line %d: Addresses family mismatch\n",
  491                     rc_file, rc_line);
  492                 (void)fclose(fp);
  493                 return -1;
  494             }
  495             if (add_colormask(s4, cm) < 0) {
  496                 (void)fclose(fp);
  497                 return -1;
  498             }
  499         } else {
  500             fprintf(stderr, "%s: line %d: Bad format\n",
  501                 rc_file, rc_line);
  502             (void)fclose(fp);
  503             return -1;
  504         }
  505     }
  506     (void)fclose(fp);
  507 #ifdef  DEBUG
  508     for (cm = color_mask, num = 0; cm && num < n_masks; cm++, num++) {
  509         struct netstat_header nh;
  510         memset(&nh, 0, sizeof(nh));
  511         nh.in_hdr = cm->in_hdr;
  512         hdr2str(&nh, s1, sizeof(s1), s2, sizeof(s2), s3, sizeof(s3));
  513         fprintf(stderr, "%d:", num+1);
  514         fprintf(stderr, " proto=%s", s3);
  515         fprintf(stderr, " src=%s", s1);
  516         fprintf(stderr, " src_mask=%d", cm->src_mask);
  517         fprintf(stderr, " dst=%s", s2);
  518         fprintf(stderr, " dst_mask=%d", cm->dst_mask);
  519         fprintf(stderr, " color_pair=%d\r\n", (int)cm->pair);
  520     }
  521     fflush(stderr);
  522     pause();
  523 #endif
  524     return n_masks;
  525 }
  526 
  527 static u_int32_t
  528 netmask(int bits)
  529 {
  530     register u_int32_t mask = 0;
  531     int i;
  532     for (i = 0; i < bits; i++) {
  533         mask >>= 1;
  534         mask |= 0x80000000L;
  535     }
  536     return (u_int32_t)htonl(mask);
  537 }
  538 
  539 int
  540 colormask(nh)
  541     const struct netstat_header *nh;
  542 {
  543     /* sanity check */
  544     if (!nh) return A_NORMAL;
  545 
  546     if (nh->in_hdr.ver) {
  547         register const struct cm_entry *cm;
  548         int i;
  549         for (cm = color_mask, i = 0; cm && i < n_masks; cm++, i++) {
  550             /* IP version */
  551             if (cm->in_hdr.ver) {
  552                 if (nh->in_hdr.ver != cm->in_hdr.ver)
  553                     continue;
  554             }
  555             /* IP protocol */
  556             if (cm->in_hdr.proto) {
  557                 if (nh->in_hdr.proto != cm->in_hdr.proto)
  558                     continue;
  559             }
  560             /* IP source address */
  561             if (cm->in_hdr.src.ip_addr.s_addr) {
  562                 if (cm->src_mask) {
  563                     u_int32_t mask = netmask(cm->src_mask);
  564                     if ((nh->in_hdr.src.ip_addr.s_addr & mask) ^
  565                         (cm->in_hdr.src.ip_addr.s_addr & mask))
  566                         continue;
  567                 } else if (nh->in_hdr.src.ip_addr.s_addr !=
  568                        cm->in_hdr.src.ip_addr.s_addr)
  569                     continue;
  570             }
  571             /* IP source port */
  572             if (cm->in_hdr.src.ip_port) {
  573                 if (nh->in_hdr.src.ip_port != cm->in_hdr.src.ip_port)
  574                     continue;
  575             }
  576             /* IP destination address */
  577             if (cm->in_hdr.dst.ip_addr.s_addr) {
  578                 if (cm->dst_mask) {
  579                     u_int32_t mask = netmask(cm->dst_mask);
  580                     if ((nh->in_hdr.dst.ip_addr.s_addr & mask) ^
  581                         (cm->in_hdr.dst.ip_addr.s_addr & mask))
  582                         continue;
  583                 } else if (nh->in_hdr.dst.ip_addr.s_addr !=
  584                        cm->in_hdr.dst.ip_addr.s_addr)
  585                     continue;
  586             }
  587             /* IP destination port */
  588             if (cm->in_hdr.dst.ip_port) {
  589                 if (nh->in_hdr.dst.ip_port != cm->in_hdr.dst.ip_port)
  590                     continue;
  591             }
  592 #ifdef  HAVE_SLCURSES
  593             return (COLOR_PAIR(cm->pair));
  594 #else
  595             return (COLOR_PAIR(cm->pair) | cm->attr);
  596 #endif
  597         }
  598     }
  599 
  600     return A_NORMAL;
  601 }
  602 
  603 #endif  /* HAVE_HAS_COLORS */