📄 linux-tcpip.c
字号:
/* -*- 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. */#define DEBUG_SUBSYSTEM S_LNET#include <libcfs/kp30.h>#include <libcfs/libcfs.h>#include <linux/if.h>#include <linux/in.h>#include <linux/file.h>/* For sys_open & sys_close */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)#include <linux/syscalls.h>#else#include <linux/fs.h>#endifintlibcfs_sock_ioctl(int cmd, unsigned long arg){ mm_segment_t oldmm = get_fs(); struct socket *sock; int fd; int rc; struct file *sock_filp; rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock); if (rc != 0) { CERROR ("Can't create socket: %d\n", rc); return rc; } fd = sock_map_fd(sock); if (fd < 0) { rc = fd; sock_release(sock); goto out; } sock_filp = fget(fd); if (!sock_filp) { rc = -ENOMEM; goto out_fd; } set_fs(KERNEL_DS);#ifdef HAVE_UNLOCKED_IOCTL if (sock_filp->f_op->unlocked_ioctl) rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg); else#endif { lock_kernel(); rc =sock_filp->f_op->ioctl(sock_filp->f_dentry->d_inode, sock_filp, cmd, arg); unlock_kernel(); } set_fs(oldmm); fput(sock_filp); out_fd: sys_close(fd); out: return rc;}intlibcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask){ struct ifreq ifr; int nob; int rc; __u32 val; nob = strnlen(name, IFNAMSIZ); 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 = *mask = 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); strcpy(ifr.ifr_name, name); ifr.ifr_addr.sa_family = AF_INET; rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr); if (rc != 0) { CERROR("Can't get netmask for interface %s\n", name); return rc; } val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr; *mask = ntohl(val); return 0;}EXPORT_SYMBOL(libcfs_ipif_query);intlibcfs_ipif_enumerate (char ***namesp){ /* Allocate and fill in 'names', returning # interfaces/error */ char **names; int toobig; int nalloc; int nfound; struct ifreq *ifr; struct ifconf ifc; int rc; int nob; int i; nalloc = 16; /* first guess at max interfaces */ toobig = 0; for (;;) { if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) { toobig = 1; nalloc = CFS_PAGE_SIZE/sizeof(*ifr); CWARN("Too many interfaces: only enumerating first %d\n", nalloc); } 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 || toobig) 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 = strnlen (ifr[i].ifr_name, IFNAMSIZ); 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;}EXPORT_SYMBOL(libcfs_ipif_enumerate);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));}EXPORT_SYMBOL(libcfs_ipif_free_enumeration);intlibcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout){ int rc; mm_segment_t oldmm = get_fs(); long ticks = timeout * HZ; unsigned long then; struct timeval tv; LASSERT (nob > 0); /* Caller may pass a zero timeout if she thinks the socket buffer is * empty enough to take the whole message immediately */ for (;;) { struct iovec iov = { .iov_base = buffer, .iov_len = nob }; struct msghdr msg = { .msg_name = NULL, .msg_namelen = 0, .msg_iov = &iov, .msg_iovlen = 1, .msg_control = NULL, .msg_controllen = 0, .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0 }; if (timeout != 0) { /* Set send timeout to remaining time */ tv = (struct timeval) { .tv_sec = ticks / HZ, .tv_usec = ((ticks % HZ) * 1000000) / HZ }; set_fs(KERNEL_DS); rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); set_fs(oldmm); if (rc != 0) { CERROR("Can't set socket send timeout " "%ld.%06d: %d\n", (long)tv.tv_sec, (int)tv.tv_usec, rc); return rc; } } set_fs (KERNEL_DS); then = jiffies; rc = sock_sendmsg (sock, &msg, iov.iov_len); ticks -= jiffies - then; set_fs (oldmm); if (rc == nob) return 0; if (rc < 0) return rc; if (rc == 0) { CERROR ("Unexpected zero rc\n"); return (-ECONNABORTED); } if (ticks <= 0) return -EAGAIN; buffer = ((char *)buffer) + rc; nob -= rc; } return (0);}EXPORT_SYMBOL(libcfs_sock_write);intlibcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout){ int rc; mm_segment_t oldmm = get_fs(); long ticks = timeout * HZ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -