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 + -
显示快捷键?