summary refs log tree commit diff stats
diff options
context:
space:
mode:
authornome <nome@rb8-comp.he10.nutilius.lan>2024-09-24 19:26:41 +0200
committernome <nome@rb8-comp.he10.nutilius.lan>2024-09-24 19:26:41 +0200
commitff594286edf603c760f797da04191f15b06ac7a7 (patch)
tree915d81818657f62d4d9537fbcef365cade8c8dcd
downloadlinuxnet-ff594286edf603c760f797da04191f15b06ac7a7.tar.gz
Initial load HEAD master
-rw-r--r--sockclnt.c352
-rw-r--r--sockserv.c420
2 files changed, 772 insertions, 0 deletions
diff --git a/sockclnt.c b/sockclnt.c
new file mode 100644
index 0000000..3e1f9bb
--- /dev/null
+++ b/sockclnt.c
@@ -0,0 +1,352 @@
+#include <stdio.h>

+#include <stdarg.h>

+#include <stdlib.h>

+#include <string.h>

+#include <errno.h>

+#include <unistd.h>

+#include <iconv.h>

+#include <signal.h>

+

+#include <sys/wait.h>

+#include <sys/socket.h>

+#include <netinet/in.h>

+#include <netdb.h>

+#include <sys/utsname.h>

+#include <arpa/inet.h>

+

+#define BUFFER_SIZE (1024*1024)

+

+typedef struct {

+    int   inpbufsz;

+    int   outbufsz;

+    short port;

+    char* addr;

+    int   debug;

+} parms_t;

+

+char inpbuf[BUFFER_SIZE];

+char outbuf[BUFFER_SIZE];

+char cnvbuf[BUFFER_SIZE]; /* For iconv */

+void pid_printf(const char* msg, ...);

+void pid_perror(char* msg);

+#ifdef __MVS__

+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen);

+#endif

+

+void init_parms(parms_t *parms, int argc, char* argv[])

+{

+    int opt;

+#ifdef __MVS__

+    char* optarg = NULL;

+#endif

+

+    parms->inpbufsz = 0;

+    parms->outbufsz = 0;

+    parms->debug    = 0;

+    parms->addr     = NULL;

+    parms->port     = 15000;

+

+    while ((opt = getopt(argc, argv, ":i:o:p:a:d:")) != -1) {

+        /* printf("%c %s\n", opt, *__opargf()); */

+#ifdef __MVS__

+        optarg = *__opargf();

+#endif

+        switch (opt) {

+        case 'i':   /* Input buffer size */

+            parms->inpbufsz = atoi(optarg);

+            break;

+        case 'o':  /* Output buffer size */

+            parms->outbufsz = atoi(optarg);

+            break;

+        case 'p': /* Port number */

+            parms->port = (short) atoi(optarg);

+            break;

+        case 'a': /* Listen address */

+            parms->addr = optarg;

+            break;

+        case 'd': /* Enable debug info */

+            printf(optarg);

+            parms->debug = atoi(optarg);

+            break;

+        case ':':

+            printf("Invalid parm value\n!");

+        default:

+            printf("%c\n", opt);

+        }

+    }

+}

+

+in_addr_t convipv4(char* addrstr) {

+

+    char *octet;

+    char* buffer = malloc(strlen(addrstr) + 1);

+

+    if (buffer == NULL) {

+        /* if moc error - give safe response */

+        return htonl(INADDR_ANY);

+    }

+

+    in_addr_t addr = (in_addr_t) 0;

+    strcpy(buffer, addrstr);

+

+    octet = strtok(buffer, ".");

+    while (octet != NULL) {

+      addr = (addr << 8) | (unsigned char) atoi(octet);

+      octet = strtok(NULL, ".");

+    }

+    free(buffer);

+    return htonl(addr);

+}

+

+void handler(int signal) {

+    pid_t pid;

+    int   stat;

+    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {

+        pid_printf("Child process %d finished\n", pid);

+    }

+

+    return;

+}

+

+int main(int argc, char* argv[]) {

+

+  parms_t parms;

+

+  init_parms(&parms, argc, argv);

+

+  int sock = -1;

+  int count = -1;

+  pid_t pid = 0;

+  pid_t fpid = 0;

+

+#ifdef __MVS__

+  size_t cnvlen;

+  iconv_t cnvinp = iconv_open("IBM-1047", "ISO8859-1");

+  iconv_t cnvout = iconv_open("ISO8859-1" , "IBM-1047");

+#endif

+

+  pid = getpid();

+

+  /* set signal action */

+

+  struct sigaction signew;

+  struct sigaction sigold;

+

+  sigemptyset(&signew.sa_mask);

+

+  signew.sa_flags = SA_NOCLDWAIT; /*SA_NOCLDSTOP;*/

+  signew.sa_flags = 0;

+  signew.sa_handler = handler;

+

+  if (sigaction(SIGCHLD, &signew, &sigold) < 0) {

+      pid_perror("SIGACTION");

+  }

+

+  struct sockaddr_in servaddr, connaddr;

+

+  servaddr.sin_family = AF_INET;

+

+  /* read address from command line */

+  if (parms.addr != NULL) {

+      servaddr.sin_addr.s_addr = convipv4(parms.addr);

+      pid_printf("IP address for connect: %s <0x%8.8X>\n", 

+             parms.addr, 

+             servaddr.sin_addr.s_addr);

+  }

+  else {

+      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

+      pid_printf("IP address for listen: 0.0.0.0 <0x%8.8X>\n", 

+             servaddr.sin_addr.s_addr);

+  }

+  servaddr.sin_port = htons(parms.port);

+

+  sock = socket(AF_INET, SOCK_STREAM, 0);

+

+  if (sock < 0) {

+    pid_perror("SOCKET: ");

+    exit(1);

+  }

+

+  /* Set size of receive buffer */

+  if (parms.inpbufsz > 0) {

+    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &parms.inpbufsz, sizeof(parms.inpbufsz)) == -1) {

+      pid_perror("Error in setting socket option:");

+    }

+    else {

+      pid_printf("InpBufSz: %d\n", parms.inpbufsz);

+    }

+  }

+

+  /* Set size of send buffer */

+  if (parms.outbufsz > 0) {

+    if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &parms.outbufsz, sizeof(parms.outbufsz)) == -1) {

+      pid_perror("Error in setting socket option:");

+    }

+    else {

+      pid_printf("OutBufSz: %d\n", parms.outbufsz);

+    }

+  }

+

+  /* Set reuse addr */

+  int reuse = 1;

+

+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {

+    pid_perror("Error in setting socket option SO_REUSEADDR");

+  }

+

+  if (connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {

+      pid_perror("CONNECT");

+      exit(1);

+  }

+

+  char* message = "ala ma kota";

+  count = snprintf(cnvbuf, sizeof(cnvbuf), "%s\n", message);

+#ifdef __MVS__

+  cnvlen = convert(cnvout, (char *) cnvbuf, count, (char *) outbuf, sizeof(outbuf));

+  count = write(sock, outbuf, cnvlen); 

+#else

+  count = write(sock, cnvbuf, count); 

+#endif

+

+ close(sock);

+

+#ifdef __MVS__

+  iconv_close(cnvinp);

+  iconv_close(cnvout);

+#endif  

+

+  pid_printf("Main process finished\n");

+  return 0;

+  

+    

+}

+

+#ifdef __MVS__

+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen) {

+

+    /* iconv variables */

+    int rc;

+    char*  inpptr;

+    char*  outptr;

+    size_t inpcnt;

+    size_t outcnt;

+

+    inpptr = inpbuf;

+    outptr = outbuf;

+    inpcnt = inplen;

+    outcnt = outlen;

+#ifdef DEBUG

+    pid_printf("Buffer: ");

+    for (int i = 0; i < inplen; ++i) {

+        printf("%2.2X", inpbuf + i);

+    }

+    printf("\n");

+

+#endif

+

+    rc = iconv(cd, &inpptr, &inpcnt, &outptr, &outcnt);

+

+    outlen = outlen - outcnt;

+

+#ifdef DEBUG

+    pid_printf("Iconv: rc=%d errno=%d inpcnt=%d outcnt=%d\n", rc, errno, inpcnt, outcnt);

+

+    pid_printf("Output: ");

+    for (int i = 0; i < outlen; ++i) {

+        printf("%2.2X", outbuf + i);

+    }

+#endif

+    printf("\n");

+

+    if (rc == ((size_t) -1)) {

+        return (size_t) 0;

+    }

+

+    return (size_t) outlen; 

+}

+

+#endif

+

+void example_gethostbyname(char* addr) {

+

+    struct hostent *hostinfo;

+

+    printf("%s\n", addr);

+    hostinfo = gethostbyname(addr);

+    if (hostinfo != NULL) {

+        char* name = NULL;

+        char** p;

+        p = hostinfo->h_aliases;

+        name = *p++;

+        while(name != NULL) {

+            printf("%s\n", name);

+            name = *p++;

+        }

+

+        /* Address list print */

+        char* addr = NULL;

+        p = hostinfo->h_addr_list;

+        addr = *p++;

+        while(addr != NULL) {

+            for (int i = 0; i < 4; ++i) {

+                printf("%2.2X\n", addr[i]);

+            }

+            addr = *p++;

+        }

+    }

+    else {

+#ifdef __MVS__

+        printf("Error(threads): %d\n", *__h_errno()); 

+#endif

+        printf("Error: %d\n", h_errno); 

+    } 

+      exit(0);

+}

+

+void pid_printf(const char* format, ...) {

+    pid_t pid = getpid();

+    char* fmtptr = NULL;

+    int   fmtlen = 0;

+    char* bufptr = NULL;

+    int   buflen = 0;

+    char* fmtpfx = "%8.8X ";

+

+    /*

+    fmtlen = strlen(fmtpfx) + strlen(format) + 1;

+    fmtptr = malloc(fmtlen);

+

+    if (fmtptr) {

+        strncpy(fmtptr, fmtpfx, fmtlen);

+        strncat(fmtptr, format, fmtlen);

+        printf(fmtptr, pid, va_list

+        free(fmtptr);

+    }

+    */

+    printf("%8.8X ", pid);

+    va_list args;

+    va_start(args, format);

+    vprintf(format, args);

+    va_end(args);

+

+    fflush(stdout);

+    return;

+}

+

+void pid_perror(char* msg) {

+    pid_t pid = getpid();

+    char* bufptr = NULL;

+    int   buflen = 0;

+

+    buflen = 8 + 1 + strlen(msg) + 1;

+    bufptr = malloc(buflen);

+

+    if (bufptr) {

+        snprintf(bufptr, buflen, "%8.8X %s", pid, msg);

+        perror(bufptr);

+        fflush(stderr);

+        free(bufptr);

+    }

+

+

+    return;

+}
\ No newline at end of file
diff --git a/sockserv.c b/sockserv.c
new file mode 100644
index 0000000..6c675ee
--- /dev/null
+++ b/sockserv.c
@@ -0,0 +1,420 @@
+#include <stdio.h>

+#include <stdarg.h>

+#include <stdlib.h>

+#include <string.h>

+#include <errno.h>

+#include <unistd.h>

+#include <iconv.h>

+#include <signal.h>

+

+#include <sys/wait.h>

+#include <sys/socket.h>

+#include <netinet/in.h>

+#include <netdb.h>

+#include <sys/utsname.h>

+#include <arpa/inet.h>

+

+#define BUFFER_SIZE (1024*1024)

+

+typedef struct {

+    int   inpbufsz;

+    int   outbufsz;

+    short port;

+    char* addr;

+    int   debug;

+} parms_t;

+

+char inpbuf[BUFFER_SIZE];

+char outbuf[BUFFER_SIZE];

+char cnvbuf[BUFFER_SIZE]; /* For iconv */

+void pid_printf(const char* msg, ...);

+void pid_perror(char* msg);

+#ifdef __MVS__

+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen);

+#endif

+

+void init_parms(parms_t *parms, int argc, char* argv[])

+{

+    int opt;

+#ifdef __MVS__

+    char* optarg = NULL;

+#endif

+

+    parms->inpbufsz = 0;

+    parms->outbufsz = 0;

+    parms->debug    = 0;

+    parms->addr     = NULL;

+    parms->port     = 15000;

+

+    while ((opt = getopt(argc, argv, ":i:o:p:a:d:")) != -1) {

+        /* printf("%c %s\n", opt, *__opargf()); */

+#ifdef __MVS__

+        optarg = *__opargf();

+#endif

+        switch (opt) {

+        case 'i':   /* Input buffer size */

+            parms->inpbufsz = atoi(optarg);

+            break;

+        case 'o':  /* Output buffer size */

+            parms->outbufsz = atoi(optarg);

+            break;

+        case 'p': /* Port number */

+            parms->port = (short) atoi(optarg);

+            break;

+        case 'a': /* Listen address */

+            parms->addr = optarg;

+            break;

+        case 'd': /* Enable debug info */

+            printf(optarg);

+            parms->debug = atoi(optarg);

+            break;

+        case ':':

+            printf("Invalid parm value\n!");

+        default:

+            printf("%c\n", opt);

+        }

+    }

+}

+

+in_addr_t convipv4(char* addrstr) {

+

+    char *octet;

+    char* buffer = malloc(strlen(addrstr) + 1);

+

+    if (buffer == NULL) {

+        /* if moc error - give safe response */

+        return htonl(INADDR_ANY);

+    }

+

+    in_addr_t addr = (in_addr_t) 0;

+    strcpy(buffer, addrstr);

+

+    octet = strtok(buffer, ".");

+    while (octet != NULL) {

+      addr = (addr << 8) | (unsigned char) atoi(octet);

+      octet = strtok(NULL, ".");

+    }

+    free(buffer);

+    return htonl(addr);

+}

+

+void handler(int signal) {

+    pid_t pid;

+    int   stat;

+    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {

+        pid_printf("Child process %d finished\n", pid);

+    }

+

+    return;

+}

+

+int main(int argc, char* argv[]) {

+

+  parms_t parms;

+

+  init_parms(&parms, argc, argv);

+

+  int sock = -1;

+  int conn = -1;

+  int count = -1;

+  pid_t pid = 0;

+  pid_t fpid = 0;

+  iconv_t cnvinp;

+  iconv_t cnvout;

+

+  pid = getpid();

+

+  /* set signal action */

+

+  struct sigaction signew;

+  struct sigaction sigold;

+

+  sigemptyset(&signew.sa_mask);

+

+  signew.sa_flags = SA_NOCLDWAIT; /*SA_NOCLDSTOP;*/

+  signew.sa_flags = 0;

+  signew.sa_handler = handler;

+

+  if (sigaction(SIGCHLD, &signew, &sigold) < 0) {

+      pid_perror("SIGACTION");

+  }

+

+  struct sockaddr_in servaddr, connaddr;

+

+  servaddr.sin_family = AF_INET;

+

+  /* read address from command line */

+  if (parms.addr != NULL) {

+      servaddr.sin_addr.s_addr = convipv4(parms.addr);

+      pid_printf("IP address for listen: %s <0x%8.8X>\n", 

+             parms.addr, 

+             servaddr.sin_addr.s_addr);

+  }

+  else {

+      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

+      pid_printf("IP address for listen: 0.0.0.0 <0x%8.8X>\n", 

+             servaddr.sin_addr.s_addr);

+  }

+  servaddr.sin_port = htons(parms.port);

+

+  sock = socket(AF_INET, SOCK_STREAM, 0);

+

+  if (sock < 0) {

+    pid_perror("SOCKET: ");

+    exit(1);

+  }

+

+  /* Set size of receive buffer */

+  if (parms.inpbufsz > 0) {

+    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &parms.inpbufsz, sizeof(parms.inpbufsz)) == -1) {

+      pid_perror("Error in setting socket option:");

+    }

+    else {

+      pid_printf("InpBufSz: %d\n", parms.inpbufsz);

+    }

+  }

+

+  /* Set size of send buffer */

+  if (parms.outbufsz > 0) {

+    if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &parms.outbufsz, sizeof(parms.outbufsz)) == -1) {

+      pid_perror("Error in setting socket option:");

+    }

+    else {

+      pid_printf("OutBufSz: %d\n", parms.outbufsz);

+    }

+  }

+

+  /* Set reuse addr */

+  int reuse = 1;

+

+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {

+    pid_perror("Error in setting socket option SO_REUSEADDR");

+  }

+

+  if (bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {

+      pid_perror("BIND");

+      exit(1);

+  }

+

+  if (listen(sock, 10) == -1) {

+      pid_perror("LISTEN");

+      exit(1);

+  }

+

+

+  struct utsname info;

+  char nodename[5] = "----";

+  if (uname(&info) == -1) {

+      pid_perror("Uname error:");

+  } else { 

+     strncpy(nodename, info.nodename, sizeof(nodename));

+  } 

+ 

+  cnvinp = iconv_open("IBM-1047", "ISO8859-1");

+  cnvout = iconv_open("ISO8859-1" , "IBM-1047");

+  for ( ; ; ) {

+      size_t cnvlen;

+      socklen_t connsize = sizeof(connaddr);

+

+      conn = accept(sock, (struct sockaddr *) &connaddr, &connsize);

+      if (conn < 0) {

+          if (errno == EINTR) {

+              continue; /* interrupted syscall */

+          } else {

+              pid_perror("ACCEPT:");

+              exit(1);

+          }

+      }

+      fpid = fork();

+      if (fpid == 0) { 

+          /* Here inside child process */ 

+          pid_printf("Forked process initialized\n");

+          close(sock);

+

+

+          pid_printf("IP address for serv: <0x%8.8X>\n", servaddr.sin_addr.s_addr);

+          pid_printf("IP port for serv: <%5d>\n", servaddr.sin_port);

+          pid_printf("IP address for peer: <0x%8.8X>\n", connaddr.sin_addr.s_addr);

+          pid_printf("IP port for peer: <%5d>\n", connaddr.sin_port);

+

+          char locip[256]; 

+          char rmtip[265];

+          strcpy(locip, inet_ntoa(servaddr.sin_addr));

+          strcpy(rmtip, inet_ntoa(connaddr.sin_addr));

+          count = snprintf(cnvbuf, sizeof(cnvbuf), "%s PID:%8.8X LOC-IP:%s:%05.5d RMT-IP:%s:%05.5d \n", 

+                           nodename, getpid(), locip, servaddr.sin_port, rmtip, connaddr.sin_port);

+#ifdef __MVS__

+          cnvlen = convert(cnvout, (char *) cnvbuf, count, (char *) outbuf, sizeof(outbuf));

+          count = write(conn, outbuf, cnvlen); 

+#else

+          count = write(conn, cnvbuf, count); 

+#endif

+

+

+          count = read(conn, inpbuf, sizeof(inpbuf)); 

+          while (count > 0) {

+              pid_printf("Packet received, size: %d\n", count);

+

+              if (parms.debug != 0) {

+#ifdef __MVS__

+                  cnvlen = convert(cnvinp, (char *) inpbuf, count, (char *) cnvbuf, sizeof(cnvbuf));

+                  pid_printf("Packet bytes below: \n%.*s\n", cnvlen, cnvbuf);

+#else

+                  pid_printf("Packet bytes below: \n%.*s\n", count, inpbuf);

+#endif

+              }

+

+              count = read(conn, inpbuf, sizeof(inpbuf)); 

+          }

+          if (count == 0) {

+              pid_printf("Forked process will be finished\n");

+          }

+          else if (count < 0 ) {

+              pid_printf("ERRNO: %d\n", fpid, errno);

+              pid_printf("Interrupt\n");

+          }

+

+          exit(0);

+      }

+      close(conn);

+  }

+

+  iconv_close(cnvinp);

+  iconv_close(cnvout);

+  close(sock);

+

+  pid_printf("Main process finished\n");

+  return 0;

+  

+    

+}

+

+#ifdef __MVS__

+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen) {

+

+    /* iconv variables */

+    int rc;

+    char*  inpptr;

+    char*  outptr;

+    size_t inpcnt;

+    size_t outcnt;

+

+    inpptr = inpbuf;

+    outptr = outbuf;

+    inpcnt = inplen;

+    outcnt = outlen;

+#ifdef DEBUG

+    pid_printf("Buffer: ");

+    for (int i = 0; i < inplen; ++i) {

+        printf("%2.2X", inpbuf + i);

+    }

+    printf("\n");

+

+#endif

+

+    rc = iconv(cd, &inpptr, &inpcnt, &outptr, &outcnt);

+

+    outlen = outlen - outcnt;

+

+#ifdef DEBUG

+    pid_printf("Iconv: rc=%d errno=%d inpcnt=%d outcnt=%d\n", rc, errno, inpcnt, outcnt);

+

+    pid_printf("Output: ");

+    for (int i = 0; i < outlen; ++i) {

+        printf("%2.2X", outbuf + i);

+    }

+#endif

+    printf("\n");

+

+    if (rc == ((size_t) -1)) {

+        return (size_t) 0;

+    }

+

+    return (size_t) outlen; 

+}

+

+#endif

+

+void example_gethostbyname(char* addr) {

+

+    struct hostent *hostinfo;

+

+    printf("%s\n", addr);

+    hostinfo = gethostbyname(addr);

+    if (hostinfo != NULL) {

+        char* name = NULL;

+        char** p;

+        p = hostinfo->h_aliases;

+        name = *p++;

+        while(name != NULL) {

+            printf("%s\n", name);

+            name = *p++;

+        }

+

+        /* Address list print */

+        char* addr = NULL;

+        p = hostinfo->h_addr_list;

+        addr = *p++;

+        while(addr != NULL) {

+            for (int i = 0; i < 4; ++i) {

+                printf("%2.2X\n", addr[i]);

+            }

+            addr = *p++;

+        }

+    }

+    else {

+#ifdef __MVS__

+        printf("Error(threads): %d\n", *__h_errno()); 

+#endif

+        printf("Error: %d\n", h_errno); 

+    } 

+      exit(0);

+}

+

+void pid_printf(const char* format, ...) {

+    pid_t pid = getpid();

+    char* fmtptr = NULL;

+    int   fmtlen = 0;

+    char* bufptr = NULL;

+    int   buflen = 0;

+    char* fmtpfx = "%8.8X ";

+

+    /*

+    fmtlen = strlen(fmtpfx) + strlen(format) + 1;

+    fmtptr = malloc(fmtlen);

+

+    if (fmtptr) {

+        strncpy(fmtptr, fmtpfx, fmtlen);

+        strncat(fmtptr, format, fmtlen);

+        printf(fmtptr, pid, va_list

+        free(fmtptr);

+    }

+    */

+    printf("%8.8X ", pid);

+    va_list args;

+    va_start(args, format);

+    vprintf(format, args);

+    va_end(args);

+

+    fflush(stdout);

+    return;

+}

+

+void pid_perror(char* msg) {

+    pid_t pid = getpid();

+    char* bufptr = NULL;

+    int   buflen = 0;

+

+    buflen = 8 + 1 + strlen(msg) + 1;

+    bufptr = malloc(buflen);

+

+    if (bufptr) {

+        snprintf(bufptr, buflen, "%8.8X %s", pid, msg);

+        perror(bufptr);

+        fflush(stderr);

+        free(bufptr);

+    }

+

+

+    return;

+}
\ No newline at end of file