user-tcpip.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 605 行 · 第 1/2 页

C
605
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2005 Cluster File Systems, Inc. * *   This file is part of Lustre, http://www.lustre.org. * *   Lustre is free software; you can redistribute it and/or *   modify it under the terms of version 2 of the GNU General Public *   License as published by the Free Software Foundation. * *   Lustre is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with Lustre; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#ifndef __KERNEL__#ifndef REDSTORM#include <sys/socket.h>#include <netinet/tcp.h>#include <sys/ioctl.h>#include <unistd.h>#include <string.h>#include <unistd.h>#include <poll.h>#include <net/if.h>#include <arpa/inet.h>#include <errno.h>#if defined(__sun__) || defined(__sun)#include <sys/sockio.h>#endif#ifndef __CYGWIN__#include <sys/syscall.h>#endif#include <libcfs/libcfs.h>#include <libcfs/kp30.h>/* * Functions to get network interfaces info */intlibcfs_sock_ioctl(int cmd, unsigned long arg){        int fd, rc;                fd = socket(AF_INET, SOCK_STREAM, 0);                if (fd < 0) {                rc = -errno;                CERROR("socket() failed: errno==%d\n", errno);                return rc;        }        rc = ioctl(fd, cmd, arg);        close(fd);        return rc;}intlibcfs_ipif_query (char *name, int *up, __u32 *ip){        struct ifreq   ifr;        int            nob;        int            rc;        __u32          val;        nob = strlen(name);        if (nob >= IFNAMSIZ) {                CERROR("Interface name %s too long\n", name);                return -EINVAL;        }        CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);        strcpy(ifr.ifr_name, name);        rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);        if (rc != 0) {                CERROR("Can't get flags for interface %s\n", name);                return rc;        }        if ((ifr.ifr_flags & IFF_UP) == 0) {                CDEBUG(D_NET, "Interface %s down\n", name);                *up = 0;                *ip = 0;                return 0;        }        *up = 1;        strcpy(ifr.ifr_name, name);        ifr.ifr_addr.sa_family = AF_INET;        rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);        if (rc != 0) {                CERROR("Can't get IP address for interface %s\n", name);                return rc;        }        val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;        *ip = ntohl(val);        return 0;}voidlibcfs_ipif_free_enumeration (char **names, int n){        int      i;        LASSERT (n > 0);        for (i = 0; i < n && names[i] != NULL; i++)                LIBCFS_FREE(names[i], IFNAMSIZ);        LIBCFS_FREE(names, n * sizeof(*names));}intlibcfs_ipif_enumerate (char ***namesp){        /* Allocate and fill in 'names', returning # interfaces/error */        char          **names;        int             nalloc;        int             nfound;        struct ifreq   *ifr;        struct ifconf   ifc;        int             rc;        int             nob;        int             i;        nalloc = 16;        /* first guess at max interfaces */        for (;;) {                LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));                if (ifr == NULL) {                        CERROR ("ENOMEM enumerating up to %d interfaces\n",                                nalloc);                        rc = -ENOMEM;                        goto out0;                }                ifc.ifc_buf = (char *)ifr;                ifc.ifc_len = nalloc * sizeof(*ifr);                rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);                if (rc < 0) {                        CERROR ("Error %d enumerating interfaces\n", rc);                        goto out1;                }                LASSERT (rc == 0);                nfound = ifc.ifc_len/sizeof(*ifr);                LASSERT (nfound <= nalloc);                if (nfound < nalloc)                        break;                LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));                nalloc *= 2;        }        if (nfound == 0)                goto out1;        LIBCFS_ALLOC(names, nfound * sizeof(*names));        if (names == NULL) {                rc = -ENOMEM;                goto out1;        }        /* NULL out all names[i] */        memset (names, 0, nfound * sizeof(*names));        for (i = 0; i < nfound; i++) {                nob = strlen (ifr[i].ifr_name);                if (nob >= IFNAMSIZ) {                        /* no space for terminating NULL */                        CERROR("interface name %.*s too long (%d max)\n",                               nob, ifr[i].ifr_name, IFNAMSIZ);                        rc = -ENAMETOOLONG;                        goto out2;                }                LIBCFS_ALLOC(names[i], IFNAMSIZ);                if (names[i] == NULL) {                        rc = -ENOMEM;                        goto out2;                }                memcpy(names[i], ifr[i].ifr_name, nob);                names[i][nob] = 0;        }        *namesp = names;        rc = nfound; out2:        if (rc < 0)                libcfs_ipif_free_enumeration(names, nfound); out1:        LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); out0:        return rc;}/* * Network functions used by user-land lnet acceptor */intlibcfs_sock_listen (int *sockp, __u32 local_ip, int local_port, int backlog){        int                rc;        int                option;        struct sockaddr_in locaddr;                *sockp = socket(AF_INET, SOCK_STREAM, 0);        if (*sockp < 0) {                rc = -errno;                CERROR("socket() failed: errno==%d\n", errno);                return rc;        }        option = 1;        if ( setsockopt(*sockp, SOL_SOCKET, SO_REUSEADDR,                        (char *)&option, sizeof (option)) ) {                rc = -errno;                CERROR("setsockopt(SO_REUSEADDR) failed: errno==%d\n", errno);                goto failed;        }        if (local_ip != 0 || local_port != 0) {                memset(&locaddr, 0, sizeof(locaddr));                locaddr.sin_family = AF_INET;                locaddr.sin_port = htons(local_port);                locaddr.sin_addr.s_addr = (local_ip == 0) ?                                          INADDR_ANY : htonl(local_ip);                if ( bind(*sockp, (struct sockaddr *)&locaddr, sizeof(locaddr)) ) {                        rc = -errno;                        if ( errno == -EADDRINUSE )                                CDEBUG(D_NET, "Port %d already in use\n",                                       local_port);                        else                                CERROR("bind() to port %d failed: errno==%d\n",                                       local_port, errno);                        goto failed;                }        }        if ( listen(*sockp, backlog) ) {                rc = -errno;                CERROR("listen() with backlog==%d failed: errno==%d\n",                       backlog, errno);                goto failed;        }                return 0;  failed:        close(*sockp);        return rc;}intlibcfs_sock_accept (int *newsockp, int sock, __u32 *peer_ip, int *peer_port){        struct sockaddr_in accaddr;        socklen_t accaddr_len = sizeof(struct sockaddr_in);        *newsockp = accept(sock, (struct sockaddr *)&accaddr, &accaddr_len);        if ( *newsockp < 0 ) {                CERROR("accept() failed: errno==%d\n", errno);                return -errno;        }        *peer_ip = ntohl(accaddr.sin_addr.s_addr);        *peer_port = ntohs(accaddr.sin_port);                return 0;}intlibcfs_sock_read (int sock, void *buffer, int nob, int timeout){        int rc;        struct pollfd pfd;        cfs_time_t start_time = cfs_time_current();        pfd.fd = sock;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?