Back to index

im-sdk  12.3.91
iiimp-data-collector.c
Go to the documentation of this file.
00001 #pragma ident "$Id: iiimp-data-collector.c,v 1.4 2002/02/26 00:16:54 kasha Exp kasha $"
00002 
00003 
00004 #include <stdio.h>
00005 #include <unistd.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <fcntl.h>
00009 #include <pthread.h>
00010 #include <errno.h>
00011 #include <sys/uio.h>
00012 #include <sys/types.h>
00013 #include <sys/socket.h>
00014 
00015 #include "iiimp-opcode.h"
00016 
00017 int           fd_log = -1;
00018 
00019 #define FD_MAX       (1024)
00020 
00021 static int    fd_type[FD_MAX];
00022 static char   pad[16];
00023 
00024 #define IO_READ             (0xfe)
00025 #define IO_WRITE     (0xef)
00026 #define MAGIC        "IIIMP DUMP DATA"
00027 #define DATA_VERSION (1)
00028 
00029 #define FD_UNDEFINED (0)
00030 #define FD_CANDIDATE (1)
00031 #define FD_IIIMP     (2)
00032 #define FD_NOT_IIIMP (3)
00033 
00034 
00035 extern ssize_t       _read(int, void *, size_t);
00036 extern ssize_t       _write(int, const void *, size_t);
00037 extern int    _close(int);
00038 extern int    _socket(int, int, int);
00039 extern int    _accept(int s, struct sockaddr * addr, socklen_t * addrlen);
00040 extern ssize_t       _send(int fildes, const void * msg, size_t len, int flags);
00041 extern ssize_t       _recv(int s, void * msg, size_t len, int flags);
00042 
00043 int           pad_size(int nbyte);
00044 
00045 
00046 static void
00047 log_prepare()
00048 {
00049        char          logfile[1024];
00050        char *        p;
00051        struct iovec  iov[4];
00052        uint32_t      byte_order;
00053        uint32_t      version;
00054 
00055        if (-1 != fd_log) return;
00056 
00057        memset(pad, 0xff, sizeof (pad));
00058 
00059        p = getenv("IIIMP_LOG_FILE");
00060        if (NULL == p) {
00061               if (0 == getuid()) {
00062                      p = "/var/run/iiimp-data.%d";
00063               } else {
00064                      p = "/var/tmp/iiimp-data.%d";
00065               }
00066        }
00067        sprintf(logfile, p, getpid());
00068        fd_log = open(logfile, O_CREAT | O_WRONLY | O_APPEND, 0666);
00069 
00070        if (-1 != fd_log) {
00071               iov[0].iov_base = (caddr_t)MAGIC;
00072               iov[0].iov_len = 16;
00073 
00074               byte_order = 1;
00075               iov[1].iov_base = (caddr_t)(&byte_order);
00076               iov[1].iov_len = (sizeof (byte_order));
00077 
00078               version = DATA_VERSION;
00079               iov[2].iov_base = (caddr_t)(&version);
00080               iov[2].iov_len = (sizeof (version));
00081 
00082               iov[3].iov_base = (caddr_t)(pad);
00083               iov[3].iov_len = (16 - iov[1].iov_len - iov[2].iov_len);
00084 
00085               writev(fd_log, iov, 4);
00086        }
00087 
00088        return;
00089 }
00090 
00091 
00092 void
00093 dump(int iot, int fd, const void * buf, size_t nbyte) {
00094        struct iovec  iov[6];
00095        int           iov_count;
00096        int           iov_data_size;
00097        uint32_t      thread_id;
00098        uint32_t      io_type;
00099        uint32_t      fildes;
00100        uint32_t      data_size;
00101        int           n;
00102 
00103        if (-1 == fd_log) return;
00104 
00105        n = 0;
00106        iov_data_size = 0;
00107 
00108        thread_id = pthread_self();
00109        iov[n].iov_base = (caddr_t)(&thread_id);
00110        iov[n].iov_len = (sizeof (thread_id));
00111        iov_data_size += (sizeof (thread_id));
00112        n += 1;
00113 
00114        io_type = iot;
00115        iov[n].iov_base = (caddr_t)(&io_type);
00116        iov[n].iov_len = (sizeof (io_type));
00117        iov_data_size += (sizeof (io_type));
00118        n += 1;
00119 
00120        fildes = fd;
00121        iov[n].iov_base = (caddr_t)(&fildes);
00122        iov[n].iov_len = (sizeof (fildes));
00123        iov_data_size += (sizeof (fildes));
00124        n += 1;
00125 
00126        data_size = nbyte;
00127        iov[n].iov_base = (caddr_t)(&data_size);
00128        iov[n].iov_len = (sizeof (data_size));
00129        iov_data_size += (sizeof (data_size));
00130        n += 1;
00131 
00132        iov[n].iov_base = (caddr_t)(buf);
00133        iov[n].iov_len = data_size;
00134        iov_data_size += data_size;
00135        n += 1;
00136 
00137        iov[n].iov_base = pad;
00138        iov[n].iov_len = pad_size(iov_data_size);
00139        iov_count = ((0 == iov[n].iov_len) ? n : (n + 1));
00140 
00141        writev(fd_log, iov, iov_count);
00142 
00143        return;
00144 }
00145 
00146 
00147 int
00148 pad_size(int nbyte) {
00149        int    i;
00150 
00151        i = (nbyte % 16);
00152        return ((0 == i) ? 0 : (16 - i));
00153 }
00154 
00155 
00156 ssize_t
00157 read(int fildes, void * buf, size_t nbyte)
00158 {
00159        ssize_t              r;
00160        int           errno_save;
00161        struct iovec  iov[5];
00162        int           iov_count;
00163        int           iov_data_size;
00164        uint32_t      thread_id;
00165        uint32_t      io_type;
00166        uint32_t      data_size;
00167 
00168        r = _read(fildes, buf, nbyte);
00169        errno_save = errno;
00170 
00171        if (r <= 0) return r;
00172 
00173        if ((0 <= fildes) && (fildes < FD_MAX) &&
00174            (FD_CANDIDATE == fd_type[fildes])) {
00175               if ((4 <= r) && (4 <= nbyte) &&
00176                   (IM_CONNECT == (0x7f & *((unsigned char *)buf)))) {
00177                      log_prepare();
00178                      if (-1 == fd_log) {
00179                             fd_type[fildes] = FD_NOT_IIIMP;    /* give up */
00180                             return r;
00181                      }
00182                      fd_type[fildes] = FD_IIIMP; /* probably IIIMP port */
00183               } else {
00184                      fd_type[fildes] = FD_NOT_IIIMP;    /* not IIIMP port */
00185                      return r;
00186               }
00187        }
00188 
00189        if ((0 <= fildes) && (fildes < FD_MAX) &&
00190            (FD_IIIMP == fd_type[fildes])) {
00191               dump(IO_READ, fildes, buf, r);
00192        }
00193 
00194        errno = errno_save;
00195        return r;
00196 }
00197 
00198 
00199 ssize_t
00200 write(int fildes, const void * buf, size_t nbyte)
00201 {
00202        unsigned char *      p;
00203        struct iovec  iov[4];
00204        int           iov_count;
00205        int           iov_data_size;
00206        uint32_t      thread_id;
00207        uint32_t      io_type;
00208        uint32_t      data_size;
00209 
00210        p = (unsigned char *)buf;
00211 
00212        while ((0 <= fildes) && (fildes < FD_MAX) &&
00213               (FD_CANDIDATE == fd_type[fildes])) {
00214               int           op;
00215               int           len;
00216               int           byte_order;
00217 
00218               fd_type[fildes] = FD_NOT_IIIMP; /* temporary */
00219 
00220               if (nbyte <= 8) break;      /* too short for IM_CONNECT */
00221 
00222               op = (0x7f & *(p + 0));
00223               if (IM_CONNECT != op) break;
00224 
00225               byte_order = *(p + 4);
00226               if ((0x42 != byte_order) && (0x6c != byte_order)) break;
00227 
00228               len = (((*(p + 1) << 16) +
00229                       (*(p + 2) << 8) +
00230                       (*(p + 3) << 0)) * 4);
00231               if ((len + 4) != nbyte) break;
00232 
00233               log_prepare();
00234               if (-1 == fd_log) break;
00235 
00236               fd_type[fildes] = FD_IIIMP; /* probably IIIMP port */
00237 
00238               if (FD_UNDEFINED != fd_type[fildes]) break;
00239        }
00240 
00241        if ((0 <= fildes) && (fildes < FD_MAX) &&
00242            (FD_IIIMP == fd_type[fildes])) {
00243               dump(IO_WRITE, fildes, buf, nbyte);
00244        }
00245 
00246        return _write(fildes, buf, nbyte);
00247 }
00248 
00249 
00250 int
00251 close(int fildes)
00252 {
00253        if ((0 <= fildes) && (fildes < FD_MAX)) {
00254               if (FD_IIIMP == fd_type[fildes]) {
00255                      dump(IO_WRITE, fildes, NULL, 0);
00256               }
00257               fd_type[fildes] = FD_UNDEFINED;
00258        }
00259        return _close(fildes);
00260 }
00261 
00262 
00263 int
00264 socket(int domain, int type, int protocol)
00265 {
00266        int    fildes;
00267 
00268        fildes = _socket(domain, type, protocol);
00269        if ((0 <= fildes) && (fildes < FD_MAX)) {
00270               if (FD_IIIMP == fd_type[fildes]) {
00271                      dump(IO_WRITE, fildes, NULL, 0);
00272               }
00273               fd_type[fildes] = FD_CANDIDATE;
00274        }
00275 
00276        return fildes;
00277 }
00278 
00279 
00280 int
00281 accept(int s, struct sockaddr * addr, void * addrlen)
00282 {
00283        int    fildes;
00284 
00285        fildes = _accept(s, addr, addrlen);
00286        if ((0 <= fildes) && (fildes < FD_MAX)) {
00287               if (FD_IIIMP == fd_type[fildes]) {
00288                      dump(IO_WRITE, fildes, NULL, 0);
00289               }
00290               fd_type[fildes] = FD_CANDIDATE;
00291        }
00292 
00293        return fildes;
00294 }
00295 
00296 
00297 ssize_t
00298 recv(int fildes, void * msg, size_t len, int flags)
00299 {
00300        ssize_t              r;
00301        int           errno_save;
00302        struct iovec  iov[5];
00303        int           iov_count;
00304        int           iov_data_size;
00305        uint32_t      thread_id;
00306        uint32_t      io_type;
00307        uint32_t      data_size;
00308 
00309        r = _recv(fildes, msg, len, flags);
00310        errno_save = errno;
00311 
00312        if (r <= 0) return r;
00313 
00314        if ((0 <= fildes) && (fildes < FD_MAX) &&
00315            (FD_CANDIDATE == fd_type[fildes])) {
00316               if ((4 <= r) && (4 <= len) &&
00317                   (IM_CONNECT == (0x7f & *((unsigned char *)msg)))) {
00318                      log_prepare();
00319                      if (-1 == fd_log) {
00320                             fd_type[fildes] = FD_NOT_IIIMP;    /* give up */
00321                             return r;
00322                      }
00323                      fd_type[fildes] = FD_IIIMP; /* probably IIIMP port */
00324               } else {
00325                      fd_type[fildes] = FD_NOT_IIIMP;    /* not IIIMP port */
00326                      return r;
00327               }
00328        }
00329 
00330        if ((0 <= fildes) && (fildes < FD_MAX) &&
00331            (FD_IIIMP == fd_type[fildes])) {
00332               dump(IO_READ, fildes, msg, r);
00333        }
00334 
00335        errno = errno_save;
00336        return r;
00337 }
00338 
00339 
00340 ssize_t
00341 send(int s, const void * msg, size_t len, int flags)
00342 {
00343        unsigned char *      p;
00344        struct iovec  iov[4];
00345        int           iov_count;
00346        int           iov_data_size;
00347        uint32_t      thread_id;
00348        uint32_t      io_type;
00349        uint32_t      data_size;
00350 
00351        p = (unsigned char *)msg;
00352 
00353        while ((0 <= s) && (s < FD_MAX) &&
00354               (FD_CANDIDATE == fd_type[s])) {
00355               int           op;
00356               int           len;
00357               int           byte_order;
00358 
00359               fd_type[s] = FD_NOT_IIIMP; /* temporary */
00360 
00361               if (len <= 8) break; /* too short for IM_CONNECT */
00362 
00363               op = (0x7f & *(p + 0));
00364               if (IM_CONNECT != op) break;
00365 
00366               byte_order = *(p + 4);
00367               if ((0x42 != byte_order) && (0x6c != byte_order)) break;
00368 
00369               len = (((*(p + 1) << 16) +
00370                       (*(p + 2) << 8) +
00371                       (*(p + 3) << 0)) * 4);
00372               if ((len + 4) != len) break;
00373 
00374               log_prepare();
00375               if (-1 == fd_log) break;
00376 
00377               fd_type[s] = FD_IIIMP;      /* probably IIIMP port */
00378 
00379               if (FD_UNDEFINED != fd_type[s]) break;
00380        }
00381 
00382        if ((0 <= s) && (s < FD_MAX) &&
00383            (FD_IIIMP == fd_type[s])) {
00384               dump(IO_WRITE, s, msg, len);
00385        }
00386 
00387        return _send(s, msg, len, flags);
00388 }