基于网卡序号双网卡数据共享(网卡转发)

 基于网卡序号:ifr.ifr_ifindex;

实现网卡之间的数据转发

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>#define    RET_ERROR             -1 
#define    RET_FAIL              0 
#define    RET_SUCCESS              1 #define       NIC1_NIC_IND          1 
#define       NIC2_NIC_IND          2 int g_eth1_index = 0;
int g_eth2_index = 0;const char  ETH_NIC_DEV1[16]        = "eth0";
const char  ETH_NIC_DEV2[16]        = "eth1";/*
函数名称:inline int active_dev( const int sockFd, const char * dev)
功能说明:激活网口
输入参数:sockFd:套接字描述符dev:对应的网口
输出参数:无
返回值:int 成功返回1,失败返回0
关系函数:socket()
线程安全:否
*/
static int active_dev(const int sockFd, const char* dev)
{int     ret;struct  ifreq req;bzero(&req, sizeof(struct ifreq));strncpy(req.ifr_name, dev, sizeof(req.ifr_name));ret = ioctl(sockFd, SIOCGIFFLAGS, &req);if (ret == -1){return(RET_FAIL);}req.ifr_flags |= IFF_UP;ret = ioctl(sockFd, SIOCSIFFLAGS, &req);if (ret == -1){return(RET_FAIL);}return(RET_SUCCESS);
}/*函数名称:inline int open_socket( int & sockFd)功能说明:新建套接字。输入参数:sockFd:套接字描述符输出参数:无返回值:int 成功返回新建的套接字描述符,失败返回0关系函数:无线程安全:否
*/
int open_socket(void)
{struct ifreq ifr;int s;int ret;int sockFd = 0;sockFd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));if (sockFd < 0){exit(0);}ret = active_dev(sockFd, ETH_NIC_DEV1);if (ret == RET_FAIL){close(sockFd);exit(0);}strncpy(ifr.ifr_name, ETH_NIC_DEV1, sizeof(ifr.ifr_name));s = ioctl(sockFd, SIOCGIFFLAGS, &ifr);if (s < 0){close(sockFd);exit(0);}ifr.ifr_flags |= IFF_PROMISC;ifr.ifr_flags |= IFF_UP;s = ioctl(sockFd, SIOCSIFFLAGS, &ifr);if (s < 0){}ioctl(sockFd, SIOCGIFINDEX, &ifr);//sl.sll_ifindex = ifr.ifr_ifindex;g_eth1_index = ifr.ifr_ifindex;ret = active_dev(sockFd, ETH_NIC_DEV2);if (ret == RET_FAIL){close(sockFd);exit(0);}strncpy(ifr.ifr_name, ETH_NIC_DEV2, sizeof(ifr.ifr_name));s = ioctl(sockFd, SIOCGIFFLAGS, &ifr);if (s < 0){close(sockFd);exit(0);}ifr.ifr_flags |= IFF_PROMISC;ifr.ifr_flags |= IFF_UP;s = ioctl(sockFd, SIOCSIFFLAGS, &ifr);if (s < 0){}ioctl(sockFd, SIOCGIFINDEX, &ifr);//sl.sll_ifindex = ifr.ifr_ifindex;g_eth2_index = ifr.ifr_ifindex;return(sockFd);
}/*函数名称:inline int set_sockopt( const int sockFd)功能说明:对新建的套接字进行设置。输入参数:sockFd:套接字描述符输出参数:无返回值:int 成功返回0,失败返回0关系函数:无线程安全:否
*/
int set_sockopt(const int sockFd)
{int optval = 0;int optlen = 0;int ret;ret = getsockopt(sockFd, SOL_SOCKET, SO_RCVBUF, &optval, (socklen_t*)&optlen);if (ret < 0){return(RET_FAIL);}optval = 1024 * 128;// * 16;optlen = sizeof(optval);ret = setsockopt(sockFd, SOL_SOCKET, SO_RCVBUF, &optval, (socklen_t)optlen);if (ret < 0){return(RET_FAIL);}ret = getsockopt(sockFd, SOL_SOCKET, SO_RCVBUF, &optval, (socklen_t*)&optlen);if (ret < 0){return(RET_FAIL);}optval = 1024 * 512;// * 8;optlen = sizeof(optval);ret = setsockopt(sockFd, SOL_SOCKET, SO_SNDBUF, &optval, (socklen_t)optlen);if (ret < 0){return(RET_FAIL);}ret = getsockopt(sockFd, SOL_SOCKET, SO_SNDBUF, &optval, (socklen_t*)&optlen);if (ret < 0){return(RET_FAIL);}return(RET_SUCCESS);
}/*函数名称:int recv_via_dev( const int sockFd, char & devInd,char * data, const
int len)功能说明:封装的接收函数输入参数:sockFd:套接字描述符devInd:网口标识data:接收的数据Len:接收数据的长度输出参数:无返回值:int 成功返回1,失败返回0关系函数:无线程安全:是
*/
int recv_via_dev(const int sockFd, int* devInd, char* data, int len)
{int ret = 0;struct sockaddr_ll sa;socklen_t sz = sizeof(sa);ret = recvfrom(sockFd, data, len, 0, (struct sockaddr*)&sa, &sz);   //function defined in systemif (ret == -1){return -1;}if (sa.sll_ifindex == g_eth1_index){*devInd = NIC1_NIC_IND;}else if (sa.sll_ifindex == g_eth2_index){*devInd = NIC2_NIC_IND;}else{return -1;}return(ret);
}/*函数名称:int send_via_dev( const int sockFd, const char devInd, char * & data,
int & len, unsigned short vlanid=0)功能说明:封装的发送函数输入参数:sockFd:套接字描述符devInd:网口标识data:发送的数据Len:发送数据的长度vlanid:vlan标识输出参数:无返回值:int 成功返回1,失败返回0关系函数:无线程安全:是
*/
int send_via_dev(const int sockFd, int devInd, char* data, int len)
{int ret = 0;struct sockaddr_ll sa;sa.sll_family = AF_INET;memcpy(sa.sll_addr, data, 6);sa.sll_halen = 6;if (devInd == NIC1_NIC_IND){sa.sll_ifindex = g_eth1_index;}else if (devInd == NIC2_NIC_IND){sa.sll_ifindex = g_eth2_index;}else{return -1;}ret = sendto(sockFd, data, len, 0, (struct sockaddr*)&sa, sizeof(sa));if (ret < 0){}return(ret);
}int main(void)
{char data[1500] = {0};int sockFd = open_socket();int devInd = 0;int recvLen = 0;struct ethhdr *     eth;set_sockopt(sockFd);while(1){recvLen = recv_via_dev(sockFd, &devInd, data, 1500);if (recvLen >= 0){//eth = (struct ethhdr*)data;//printf("port eth%d recv proto %x\n", devInd, ntohs(eth->h_proto));if (NIC1_NIC_IND == devInd){devInd = NIC2_NIC_IND;}else if (NIC2_NIC_IND == devInd){devInd = NIC1_NIC_IND;}send_via_dev(sockFd, devInd, data, recvLen);}//fflush(stdout);//fflush(stderr);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/64309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

经管博士科研基础【12】包络定理

当我们知道一个函数的最优解时&#xff0c;我们要求解这一个函数的值函数关于函数中某一个参数的导数&#xff0c;那么就可以使用包络定理。 1. 无约束条件下的包络定理 函数在其极值点处对一个参数&#xff08;参数不是自变量&#xff09;取偏导数的结果&#xff0c;等价于这…

【List】List集合有序测试案例:ArrayList,LinkedList,Vector(123)

List是有序、可重复的容器。 有序&#xff1a; List中每个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问 元素&#xff0c;从而精确控制这些元素。 可重复&#xff1a; List允许加入重复的元素。更确切地讲&#xff0c;List通常允许满足 e1.equals(e2) 的元素…

Node.js crypto模块 加密算法

背景 微信小程序调用飞蛾热敏纸打印机&#xff0c;需要进行参数sig签名校验&#xff0c;使用的是sha1进行加密 // 通过crypto.createHash()函数&#xff0c;创建一个hash实例&#xff0c;但是需要调用md5&#xff0c;sha1&#xff0c;sha256&#xff0c;sha512算法来实现实例的…

小兔鲜商02

npm i vueuse/core -fvue插件使用&#xff1a; 许多公用的全局组件&#xff0c;&#xff0c;可以通过插件注册进去&#xff0c;就不用一个一个导入组件&#xff0c;&#xff0c; import XtxSkeleton from /components/library/xtx-skeletonexport default {install (app) {// …

C++并发编程:使用C++实现线程安全的栈

C并发编程&#xff1a;使用C实现线程安全的栈 引言 在多线程编程中&#xff0c;数据结构的线程安全性是至关重要的。本文将详细介绍如何使用C20标准库中的一些新特性来实现一个线程安全的栈。 什么是线程安全的栈&#xff1f; 简单来说&#xff0c;一个线程安全的栈是一个可…

linux操作系统中的动静态库(未完)

1. 静态库与动态库 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库动态库&#xff08;.so&#xff09;&#xff1a;程序在运行的时候才去链接动态库的代码&#xff0c;多个程序共享使用库的…

为什么Java接口可以多继承,而类不可以?

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

unity 跨屏显示

1.代码 /*Type:设置分辨率*/ using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Runtime.InteropServices;public class ScreenManager : MonoBehaviour {[HideInInspector]//导入设置窗口函数 [DllImport("…

Redis之MoreKey问题及Scan命令解读

目录 MoreKey问题讨论 Scan命令 Sscan命令 Hscan命令 Zscan命令 MoreKey问题讨论 keys * 查看当前库所有key 对于海量数据执行key *会造成严重服务卡顿、影响业务。在实际环境中最好不要使用。生产制造过程中keys * / flushdb/flushall等危险命令以防止误删误用。 大量的…

kotlin实现猜数游戏

游戏规则 1.程序随机生成一个1到100的数字&#xff0c;作为MagicNumber 2.用户根据提示输入数据&#xff0c;只有三次机会输入数据 代码 代码很简单&#xff0c;使用了let内置函数 fun main() {//生成随机数可以使用java的方法//val magicNumber Random().nextInt(11)val ma…

如何确认linux的包管理器是yum还是apt,确认之后安装其他程序的时候就需要注意安装命令

打开终端 输入apt&#xff0c;下图中提示未找到命令&#xff0c;则基本上包管理工具就是用yum的 输入yum&#xff0c;我们看到有打印信息&#xff0c;则说明包管理工具是yum的&#xff0c;离线安装命令使用rpm

斥资4亿,收购这家WLAN厂商,结果……

晚上好&#xff0c;我的网工朋友 不少朋友可能有隐形&#xff0c;2019年的时候&#xff0c;Juniper花费4.05亿美元&#xff0c;收购WiFi初创公司Mist Systems。 Mist Systems是一家买无线产品起家的公司&#xff0c;由前思科高管创建的。主打的产品是“AI-Driven WLAN”&…

大数据平台测试-优秀员工申请模板

在企业里,优秀员工是需要申请的,下面分享一些模板: 1、申请个人优秀奖-测试质量奖 申报优秀员工-测试质量奖参考模板: 推动XXX质量共建的优秀实践者,通过验证的产研流程把控,过程问题的据理力争, 推动整体质量的大幅提升。在其强有力的执行和严格的把关下,XXX的质量管…

Kotlin 协程 - 多路复用 select()

一、概念 又叫选择表达式&#xff0c;是一个挂起函数&#xff0c;可以同时等待多个挂起结果&#xff0c;只取用最快恢复的那个值&#xff08;即多种方式获取数据&#xff0c;哪个更快返回结果就用哪个&#xff09;。 同时到达 select() 会优先选择先写子表达式&#xff0c;想随…

EI、Scopus双检索| 2023年第四届自动化、机械与设计工程国际会议

会议简介 Brief Introduction 2023年第四届自动化、机械与设计工程国际会议&#xff08;SAMDE 2023&#xff09; 会议时间&#xff1a;2023年12月8 -10日 召开地点&#xff1a;中国南京 大会官网&#xff1a;www.samde.org 机械设计制造及其自动化学科在国民经济中处于极其重要…

Java设计模式:一、六大设计原则-05:接口隔离原则

文章目录 一、定义&#xff1a;接口隔离原则二、模拟场景&#xff1a;接口隔离原则三、违背方案&#xff1a;接口隔离原则3.1 工程结构3.2 英雄技能调用3.2.1 英雄技能接口3.2.2 英雄&#xff1a;后裔3.2.3 英雄&#xff1a;廉颇 3.3 单元测试 四、改善代码&#xff1a;接口隔离…

QT6为工程添加资源文件,并在ui界面引用

以添加图片资源为例 右键工程名字&#xff08;不是最上面的名字&#xff09;&#xff0c;点击添加现有文件 这种方式虽然添加到了工程中&#xff0c;但不能在UI设计界面完成引用。主要原因可能是未把文件放入到项目资源文件中&#xff0c;以下面一种方式可以看出区别。 点击添…

常用的Spring Boot 注解及示例代码

简介&#xff1a;Spring Boot 是一个用于快速构建基于 Spring 框架的应用程序的工具&#xff0c;通过提供一系列的注解&#xff0c;它使得开发者可以更加轻松地配置、管理和控制应用程序的各种行为。以下是一些常用的 Spring Boot 注解&#xff0c;以及它们的功能和示例代码&am…

C++算法 —— 分治(2)归并

文章目录 1、排序数组2、数组中的逆序对3、计算右侧小于当前元素的个数4、翻转对 本篇前提条件是已学会归并排序 1、排序数组 排序数组 排序数组也可以用归并排序来做。 vector<int> tmp;//写成全局是因为如果在每一次小的排序中都创建一次&#xff0c;更消耗时间和空间…

【C++】—— c++11之智能指针

前言&#xff1a; 本期&#xff0c;我们将要学习的是在c11中新提出的概念——异常指针&#xff01; 目录 &#xff08;一&#xff09;智能指针的引入 &#xff08;二&#xff09;内存泄漏 1、什么是内存泄漏&#xff0c;内存泄漏的危害 2、内存泄漏分类&#xff08;了解&a…