/*
* ss.c "sockstat", socket statistics
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <fnmatch.h>
#include <getopt.h>
#include <stdbool.h>
#include "utils.h"
#include "rt_names.h"
#include "ll_map.h"
#include "libnetlink.h"
#include "namespace.h"
#include "SNAPSHOT.h"
#include <linux/tcp.h>
#include <linux/sock_diag.h>
#include <linux/inet_diag.h>
#include <linux/unix_diag.h>
#include <linux/netdevice.h> /* for MAX_ADDR_LEN */
#include <linux/filter.h>
#include <linux/packet_diag.h>
#include <linux/netlink_diag.h>
#define MAGIC_SEQ 123456
#define DIAG_REQUEST(_req, _r) \
struct { \
struct nlmsghdr nlh; \
_r; \
} _req = { \
.nlh = { \
.nlmsg_type = SOCK_DIAG_BY_FAMILY, \
.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST,\
.nlmsg_seq = MAGIC_SEQ, \
.nlmsg_len = sizeof(_req), \
}, \
}
#if HAVE_SELINUX
#include <selinux/selinux.h>
#else
/* Stubs for SELinux functions */
static int is_selinux_enabled(void)
{
return -1;
}
static int getpidcon(pid_t pid, char **context)
{
*context = NULL;
return -1;
}
static int getfilecon(char *path, char **context)
{
*context = NULL;
return -1;
}
static int security_get_initial_context(char *name, char **context)
{
*context = NULL;
return -1;
}
#endif
int resolve_hosts = 0;
int resolve_services = 1;
int preferred_family = AF_UNSPEC;
int show_options = 0;
int show_details = 0;
int show_users = 0;
int show_mem = 0;
int show_tcpinfo = 0;
int show_bpf = 0;
int show_proc_ctx = 0;
int show_sock_ctx = 0;
/* If show_users & show_proc_ctx only do user_ent_hash_build() once */
int user_ent_hash_build_init = 0;
int follow_events = 0;
int netid_width;
int state_width;
int addrp_width;
int addr_width;
int serv_width;
int screen_width;
static const char *TCP_PROTO = "tcp";
static const char *UDP_PROTO = "udp";
static const char *RAW_PROTO = "raw";
static const char *dg_proto = NULL;
enum
{
TCP_DB,
DCCP_DB,
UDP_DB,
RAW_DB,
UNIX_DG_DB,
UNIX_ST_DB,
UNIX_SQ_DB,
PACKET_DG_DB,
PACKET_R_DB,
NETLINK_DB,
MAX_DB
};
#define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
#define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
#define ALL_DB ((1<<MAX_DB)-1)
#define INET_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<RAW_DB))
enum {
SS_UNKNOWN,
SS_ESTABLISHED,
SS_SYN_SENT,
SS_SYN_RECV,
SS_FIN_WAIT1,
SS_FIN_WAIT2,
SS_TIME_WAIT,
SS_CLOSE,
SS_CLOSE_WAIT,
SS_LAST_ACK,
SS_LISTEN,
SS_CLOSING,
SS_MAX
};
#define SS_ALL ((1 << SS_MAX) - 1)
#define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
#include "ssfilter.h"
struct filter
{
int dbs;
int states;
int families;
struct ssfilter *f;
};
static const struct filter default_dbs[MAX_DB] = {
[TCP_DB] = {
.states = SS_CONN,
.families = (1 << AF_INET) | (1 << AF_INET6),
},
[DCCP_DB] = {
.states = SS_CONN,
.families = (1 << AF_INET) | (1 << AF_INET6),
},
[UDP_DB] = {
.states = (1 << SS_ESTABLISHED),
.families = (1 << AF_INET) | (1 << AF_INET6),
},
[RAW_DB] = {
.states = (1 << SS_ESTABLISHED),
.families = (1 << AF_INET) | (1 << AF_INET6),
},
[UNIX_DG_DB] = {
.states = (1 << SS_CLOSE),
.families = (1 << AF_UNIX),
},
[UNIX_ST_DB] = {
.states = SS_CONN,
.families = (1 << AF_UNIX),
},
[UNIX_SQ_DB] = {
.states = SS_CONN,
.families = (1 << AF_UNIX),
},
[PACKET_DG_DB] = {
.states = (1 << SS_CLOSE),
.families = (1 << AF_PACKET),
},
[PACKET_R_DB] = {
.states = (1 << SS_CLOSE),
.families = (1 << AF_PACKET),
},
[NETLINK_DB] = {
.states = (1 << SS_CLOSE),
.families = (1 << AF_NETLINK),
},
};
static const struct filter default_afs[AF_MAX] = {
[AF_INET] = {
.dbs = INET_DBM,
.states = SS_CONN,
},
[AF_INET6] = {
.dbs = INET_DBM,
.states = SS_CONN,
},
[AF_UNIX] = {
.dbs = UNIX_DBM,
.states = SS_CONN,
},
[AF_PACKET] = {
.dbs = PACKET_DBM,
.states = (1 << SS_CLOSE),
},
[AF_NETLINK] = {
.dbs = (1 << NETLINK_DB),
.states = (1 << SS_CLOSE),
},
};
static int do_default = 1;
static struct filter current_filter;
static void filter_db_set(struct filter *f, int db)
{
f->states |= default_dbs[db].states;
f->dbs |= 1 << db;
do_default = 0;
}
static void filter_af_set(struct filter *f, int af)
{
f->states |= default_afs[af].states;
f->families |= 1 << af;
do_default = 0;
preferred_family = af;
}
static int filter_af_get(struct filter *f, int af)
{
return f->families & (1 << af);
}
static void filter_default_dbs(struct filter *f)
{
filter_db_set(f, UDP_DB);
filter_db_set(f, DCCP_DB);
filter_db_set(f, TCP_DB);
filter_db_set(f, RAW_DB);
filter_db_set(f, UNIX_ST_DB);
filter_db_set(f, UNIX_DG_DB);
filter_db_set(f, UNIX_SQ_DB);
filter_db_set(f, PACKET_R_DB);
filter_db_set(f, PACKET_DG_DB);
filter_db_set(f, NETLINK_DB);
}
static void filter_states_set(struct filter *f, int states)
{
if (states)
f->states = (f->states | states) & states;
}
static void filter_merge_defaults(struct filter *f)
{
int db;
int af;
for (db = 0; db < MAX_DB; db++) {
if (!(f->dbs & (1 << db)))
continue;
if (!(default_dbs[db].families & f->families))
f->families |= default_dbs[db].families;
}
for (af = 0; af < AF_MAX; af++) {
if (!(f->families & (1 << af)))
continue;
if (!(default_afs[af].dbs & f->dbs))
f->dbs |= default_afs[af].dbs;
}
}
static FILE *generic_proc_open(const char *env, const char *name)
{
const char *p = getenv(env);
char store[128];
if (!p) {
p = getenv("PROC_ROOT") ? : "/proc";
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
p = store;
}
return fopen(p, "r");
}
static FILE *net_tcp_open(void)
{
return generic_proc_open("PROC_NET_TCP", "net/tcp");
}
static FILE *net_tcp6_open(void)
{
return generic_proc_open("PROC_NET_TCP6", "net/tcp6");
}
static FILE *net_udp_open(void)
{
return generic_proc_open("PROC_NET_UDP", "net/udp");
}
static FILE *net_udp6_open(void)
{
return generic_proc_open("PROC_NET_UDP6", "net/udp6");
}
static FILE *net_raw_open(void)
{
return generic_proc_open("PROC_NET_RAW", "net/raw");
}
static FILE *net_raw6_open(void)
{
return generic_proc_open("PROC_NET_RAW6", "net/raw6");
}
static FILE *net_unix_open(void)
{
return generic_proc_open("PROC_NET_UNIX", "net/unix");
}
static FILE *net_packet_open(void)
{
return generic_proc_open("PROC_NET_PACKET", "net/packet");
}
static FILE *net_netlink_open(void)
{
return generic_proc_open("PROC_NET_NETLINK", "net/netlink");
}
static FILE *slabinfo_open(void)
{
return generic_proc_open("PROC_SLABINFO", "slabinfo");
}
static FILE *net_sockstat_open(void)
{
return generic_proc_open("PROC_NET_SOCKSTAT", "net/sockstat");
}
static FILE *net_sockstat6_open(void)
{
return generic_proc_open("PROC_NET_SOCKSTAT6", "net/sockstat6");
}
static FILE *net_snmp_open(void)
{
return generic_proc_open("PROC_NET_SNMP", "net/snmp");
}
static FILE *ephemeral_ports_open(void)
{
return generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", "sys/net/ipv4/ip_local_port_range");
}
struct user_ent {
struct user_ent *next;
unsigned int ino;
int pid;
int fd;
char *process;
char *process_ctx;
char *socket_ctx;
};
#define USER_ENT_HASH_SIZE 256
struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE];
static int user_ent_hashfn(unsigned int ino)
{
int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino;
return val & (US
移植iproute2-4.4.0
需积分: 0 58 浏览量
更新于2024-06-08
收藏 692KB GZ 举报
《移植iproute2-4.4.0:深入理解与实践》
在IT行业中,网络管理是至关重要的一环,而iproute2工具包是Linux系统中用于网络配置和路由管理的核心组件之一。本文将深入探讨如何移植iproute2-4.4.0到不同的操作系统或硬件平台,以及这个第三方库在实际应用中的关键知识点。
iproute2是一款功能强大的开源软件,包含了多个实用程序,如ip、rt、ss、tc等,它们分别用于IP地址管理、路由表操作、套接字状态查询和流量控制。4.4.0版本是iproute2的一个稳定版本,提供了对现代网络协议和技术的广泛支持。
移植iproute2-4.4.0首先需要了解其依赖的库和编译环境。通常,这个过程包括以下步骤:
1. **环境准备**:确保目标系统已经安装了必要的开发工具,如GCC编译器、Make工具、autoconf、automake、libtool等。同时,还需要检查系统内核版本,确保与iproute2兼容。
2. **源码获取**:从官方仓库或镜像站点下载iproute2-4.4.0的源代码,并进行解压。
3. **配置编译**:运行autoreconf命令生成configure脚本,然后使用./configure --prefix=/path/to/install指定安装路径,进行配置。在这个阶段,编译器会检查系统环境,确定编译选项。
4. **编译与安装**:执行make命令进行编译,生成可执行文件。之后,使用make install将iproute2及其组件安装到指定路径。
5. **依赖处理**:如果iproute2依赖于系统特定的库或模块,可能需要额外处理,比如安装特定版本的库,或者修改源码以适应新环境。
6. **测试与调试**:移植后,务必对所有工具进行功能测试,确保它们能在新环境中正常工作。遇到问题时,使用gdb等调试工具定位并解决。
iproute2-4.4.0的移植过程中涉及的关键知识点有:
- **网络协议理解**:iproute2工具集处理各种网络协议,如TCP/IP、IPv4/IPv6、VLAN、QoS等。移植时,需理解这些协议的工作原理和系统实现。
- **内核接口**:iproute2与内核有紧密交互,包括直接调用内核API或通过netlink接口通信。移植时需考虑内核接口的差异。
- **流量控制(Traffic Control, TC)**:iproute2中的tc工具用于设置和管理网络带宽限制。理解TC框架和规则配置是移植的重要部分。
- **路由与策略**:ip和rt工具涉及路由表的管理,包括静态路由、策略路由等。移植时需了解不同平台的路由规则和策略。
- **多平台适配**:针对不同的硬件平台或操作系统,如ARM、MIPS、FreeBSD等,可能需要调整源码以适应其体系结构或API差异。
- **权限与安全**:移植过程中要考虑系统的权限模型和安全策略,确保iproute2工具在新环境中能正确执行网络管理任务。
移植iproute2-4.4.0是一个涉及到网络协议、系统内核、编译技术、跨平台适配等多方面知识的过程。只有深入理解这些知识点,才能顺利完成移植,并确保其在新环境下稳定运行。
m0_73421738
- 粉丝: 183
- 资源: 1
最新资源
- 西电微机原理实验-西安电子科技大学微机原理课程实验概述与指导
- 智慧校园(校园AI 产品) 校园安全 智慧校园 教育数字化 AI校园
- 西电微机原理实验四:8255可编程并行接口的应用
- 基于 Go+Echo 开发的多房间实时通讯系统。详细文档+优秀项目+全部资料.zip
- 基于 Go + Vue 的现代化博客系统详细文档+优秀项目+全部资料.zip
- 基于 go + grpc + consul 的微服务系统详细文档+优秀项目+全部资料.zip
- 基于 golang goframe + vue3 的、前后端分离的后台管理系统快捷使用模板,支持按钮级别的 RBAC。详细文档+优秀项目+全部资料.zip
- 基于 goframe2 和vue3 开发的全栈前后端分离的后台管理系统,详细文档+优秀项目+全部资料.zip
- 基于 Golang 的 容器管理系统 API详细文档+优秀项目+全部资料.zip
- 基于 React 实现的电商后台管理系统的前端项目详细文档+优秀项目+全部资料.zip
- 基于 Golang开发的微服务网关,能够实现高性能 HTTP API 转发、服务编排、多租户管理、API 访问权限控制等目的,拥有强大的自定义插件系统可以自行扩展详细文档+优秀项目+全部资料.zip
- 基于 Vue + Go 实现客户关系管理系统,,主要功能有仪表盘、客户管理、合同管理、产品管理、配置、订阅等功能详细文档+优秀项目+全部资料.zip
- 基于beego v2.0.1框架和AdminLte前端框架,开发的go语言通用后台系统,详细文档+优秀项目+全部资料.zip
- 基于 SpringBoot + Spring + SpringMvc + Mybatis + Shiro+ Redis 开发单点登录管理系统详细文档+优秀项目+全部资料.zip
- 基于beego的简易blog系统详细文档+优秀项目+全部资料.zip
- 基于Beego开发的可切换模板的 BBS 社交博客系统、它安装简单便捷,页面简介优美。前端是HTML+JS+CSS,不需要掌握一些前端技术栈也能轻松自定义页面。详细文档+优秀项目+全部资料.zip