OSSP CVS Repository

ossp - ossp-pkg/l2/l2_sockmon.c 1.3
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/l2/l2_sockmon.c 1.3
/*
**  L2 - OSSP Logging Library
**  Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
**  Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
**
**  This file is part of OSSP L2, a flexible logging library which
**  can be found at http://www.ossp.org/pkg/l2/.
**
**  Permission to use, copy, modify, and distribute this software for
**  any purpose with or without fee is hereby granted, provided that
**  the above copyright notice and this permission notice appear in all
**  copies.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
**  SUCH DAMAGE.
**
**  l2_sockmon.c: Socket monitor for use with l2_test.c
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <errno.h>

#define BACKLOG 1024    /* max # pending connections */
#define BUFFSIZ 256     /* max string size           */

char *strlowerdup(const char *pszIn)
{
    int  i        = 0;
    char *pszTemp = NULL;

/*    ASSERT(pszIn);*/
/*    ASSERT(*pszIn);*/

    if ((pszTemp = (char *)strdup(pszIn)) == NULL)
        return NULL;
    else
    {
        for (i = 0; *(pszTemp + i); i++)
            if (isupper(*(pszTemp + i)))
                *(pszTemp + i) = (char)tolower(*(pszTemp + i));
        return pszTemp;
    }
}

void dowork(int iSock)
{
    char pszBuf[BUFFSIZ];
    int  cc;

/*    ASSERT(iSock);*/

    while (1) { /* Exits when read finishes */
        cc = read(iSock, pszBuf, sizeof (pszBuf));
        if (cc == -1) {
            perror("read");
            exit(1);
        }

        if (cc == 0) {
            /* EOF */
            (void) close(iSock);
            (void) printf("Connection closed\n");
            return;
        }

        pszBuf[cc + 1] = '\0';
        (void) printf("Read: %s", pszBuf);

        if (write(iSock, pszBuf, cc) == -1) {
            perror("write");
            exit(1);
        }
    }
}

int myserver(int iFamily, int iProtocol, int iPort)
{
    char pszBuf[BUFFSIZ];
    struct sockaddr_in  laddr4,   faddr4,    caddr4;
    struct sockaddr_in6 laddr6,   faddr6,    caddr6;
    int                 iSock,    iNewsock;
    int                 iSockopt, iProtofam;
    int                 iTrans,   cc;
    socklen_t           faddrlen;

/*    ASSERT(iPort);*/
    /* Set up an IPv4 TCP socket to listen on for connections. */
    if (iFamily == AF_INET6)
    {
        laddr6.sin6_family      = AF_INET6;
        laddr6.sin6_flowinfo    = 0;
        laddr6.sin6_port        = iPort;
        laddr6.sin6_addr        = in6addr_any; /* Structure assignment */
    }
    else if (iFamily == AF_INET)
    {
        laddr4.sin_family       = AF_INET;
        laddr4.sin_port         = iPort;
        laddr4.sin_addr.s_addr  = INADDR_ANY;
    }
    else
        return -1; /* Not IPv4 or IPv6 */

    iProtofam = (iFamily   == AF_INET)     ? PF_INET    : PF_INET6;
    iTrans    = (iProtocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
    iSock     = socket(iProtofam, iTrans, iProtocol);

    if (iSock == -1) {
        perror("socket");
        return -1;
    }

    /* Tell the system to allow local addresses to be reused. */
    iSockopt = 1;
    if (setsockopt(iSock, SOL_SOCKET, SO_REUSEADDR, (void *)&iSockopt,\
        sizeof (iSockopt)) == -1) {
        perror("setsockopt(SO_REUSEADDR)");
        (void) close(iSock);
        return -1;
    }

    if (iFamily == AF_INET6) {
        if (bind(iSock, (struct sockaddr *)&laddr6, sizeof (laddr6)) == -1) {
            perror("bind"); /* Bad bind */
            (void) close(iSock);
            return -1;
            }
    }
    else if (iFamily == AF_INET) {
        if (bind(iSock, (struct sockaddr *)&laddr4, sizeof (laddr4)) == -1) {
            perror("bind"); /* Bad bind */
            (void) close(iSock);
            return -1;
            }
    }

    if (iProtocol == IPPROTO_UDP) {
        if (iFamily == AF_INET6) {
            for (;;) { /* Receive messages */
                faddrlen = sizeof(caddr6);
                memset(pszBuf, 0x0, BUFFSIZ); /* Init the buffer */
                cc = recvfrom(iSock, pszBuf, BUFFSIZ, 0, (struct sockaddr *)\
                    &caddr6, &faddrlen);

                if (cc == -1) {
                    perror("recvfrom");
                    exit(1);
                }

                if (cc == 0) {
                    /* EOF */
                    (void) close(iSock);
                    (void) printf("Connection closed\n");
                    return;
                }

                if (cc != BUFFSIZ) {
                    pszBuf[cc + 1] = '\0';
                    (void) printf("Read: %s", pszBuf);

                    if (write(iSock, pszBuf, cc) == -1) {
                        perror("write");
                        exit(1);
                    }
                }
                else
                    return -1;
            }
        }
        else if (iFamily == AF_INET) {
            for (;;) { /* Receive messages */
                faddrlen = sizeof(caddr4);
                memset(pszBuf, 0x0, BUFFSIZ); /* Init the buffer */
                cc = recvfrom(iSock, pszBuf, BUFFSIZ, 0, (struct sockaddr *)\
                    &caddr4, &faddrlen);

                if (cc == -1) {
                    perror("recvfrom");
                    exit(1);
                }

                if (cc == 0) {
                    /* EOF */
                    (void) close(iSock);
                    (void) printf("Connection closed\n");
                    return;
                }

                if (cc != BUFFSIZ) {
                    pszBuf[cc + 1] = '\0';
                    (void) printf("Read: %s", pszBuf);

                    if (write(iSock, pszBuf, cc) == -1) {
                        perror("write");
                        exit(1);
                    }
                }
                else
                    return -1;
            }
        }
    }
    else if (iProtocol == IPPROTO_TCP) { /* Only try to listen if we have TCP */
        if (listen(iSock, BACKLOG) == -1) {
            perror("listen"); /* Listen just blew up */
            (void) close(iSock);
            return -1;
        }

        /* Wait for a connection request */
        if (iFamily == AF_INET6) {
            for (;;) {
                faddrlen = sizeof (faddr6);
                iNewsock = accept(iSock, (struct sockaddr *)&faddr6, &faddrlen);
                if (iNewsock == -1) {
                    if (errno != EINTR && errno != ECONNABORTED) {
                        perror("accept");
                    }
                    continue;
                }
                (void) printf("Connection from %s/%d\n",\
                    inet_ntop(faddr6.sin6_addr), ntohs(faddr6.sin6_port));
                dowork(iNewsock); /* do some sockwork */
            }
        }
        else if (iFamily == AF_INET) {
            for (;;) {
                faddrlen = sizeof (faddr4);
                iNewsock = accept(iSock, (struct sockaddr *)&faddr4, &faddrlen);
                if (iNewsock == -1) {
                    if (errno != EINTR && errno != ECONNABORTED) {
                        perror("accept");
                    }
                    continue;
                }
                (void) printf("Connection from %s/%d\n",\
                    inet_ntop(faddr4.sin_addr), ntohs(faddr4.sin_port));
                dowork(iNewsock); /* do some sockwork */
            }
        }
        /* NOTREACHED */
    }
    else
        return -1; /* We are being asked to serve other than TCP or UDP */
}

int main(int argc, char *argv[])
{
    int iFam      = -1;
    int iProto = -1;
    int iPort  = 0;

    if (argc != 4) {
        (void) fprintf(stderr, "Usage: %s <IPv4-or-IPv6> <TCP-or-UDP> <Port>\n", argv[0]);
        exit(1); /* Dink donk if the user doesn't know how to use this */
    }

    iFam    = (!strcmp(argv[1], "IPv6")) ? AF_INET6    : AF_INET;
    iProto  = (!strcmp(argv[2], "UDP"))  ? IPPROTO_UDP : IPPROTO_TCP;
    iPort   = htons(atoi(argv[3]));

    return myserver(iFam, iProto, iPort);
}

CVSTrac 2.0.1