python通过指定网卡发包_windows下用UDP 广播在特定网卡上发包

本文介绍了如何在Windows下使用Python通过指定网卡进行UDP广播。主要方法是通过更改路由表来实现,同时提供了DOS命令示例和C语言代码片段,展示如何找到无线网卡信息并发送广播数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

总结

通过路由表来达到在指定网卡上发包的效果。

解决方案

更改路由表

使用python的pysnmp库更方便

这里给出的是windows自带的dos命令

route change 255.255.255.255 mask 255.255.255.255 192.168.1.101 metric 230 if 22

其中 192.168.1.101 是你本机的IP地址

metric 230 是你决定的metric值,比其他的小就行

if 22 是无线网络接口编号,也是通过route print命令看出来的

得到无线网卡信息之后,在特定网络广播(192.168.1.255)而不使用255.255.255.255

main.c

#include

#include

#include "GetNICMsg.h"

void raise_message(char *msg);

char * changeIPaddrtoBroadcastIPaddr(char *ipaddr, char *netmask);

#pragma comment(lib,"ws2_32.lib")

#pragma warning(disable:4996)

#define RECV_PORT 2019

#define SEND_PORT 2019

#define MAXBUFLEN 1024

#define DONTPRINTIT 0

#define PRINTIT 1

#define FIRST_USING_WIRELESS_NIC 0

int main()

{

WSADATA wsa;

WSAStartup(0x201, &wsa);

SOCKET sock_host;

sock_host = socket(AF_INET, SOCK_DGRAM, 0);

BOOL bBoardcast = TRUE;

if (SOCKET_ERROR == setsockopt(sock_host, SOL_SOCKET, SO_BROADCAST, (char*)&bBoardcast, sizeof(bBoardcast)))

{

printf("setsockopt failed with error code: %d/n", WSAGetLastError());

return -1;

}

char *ipaddr = NULL, *netmask = NULL,*ip_broadcast;

if (getAllAdapterInfo(&ipaddr, &netmask, MIB_IF_TYPE_WiFi, DONTPRINTIT, FIRST_USING_WIRELESS_NIC)!= 0)

{

raise_message("找不到一个可用的无线网卡\n");

closesocket(sock_host);

return -1;

}

// 获得无线网卡的广播地址

ip_broadcast = changeIPaddrtoBroadcastIPaddr(ipaddr, netmask);

sockaddr_in addr_local, addr_remote;

addr_remote.sin_addr.S_un.S_addr = inet_addr(ip_broadcast);

addr_remote.sin_port = htons(SEND_PORT);

addr_remote.sin_family = AF_INET;

int retval, headlen = sizeof(addr_remote);

char buf[MAXBUFLEN] = "hello???";

int ID_list_temp[5] = { htons(1), htons(2), htons(4), htons(8), htons(16) };

while (1)

{

for (int i = 0; i < 5; ++i)

{

retval = sendto(sock_host, (char *)(ID_list_temp + i), sizeof(int), 0, (sockaddr *)&addr_remote, headlen);

if (retval < 0)

{

retval = WSAGetLastError();

return -1;

}

}

}

return 0;

}

void raise_message(char *msg)

{

printf(msg);

}

char * changeIPaddrtoBroadcastIPaddr(char *ipaddr,char *netmask)

{

unsigned long int ipaddr_int = inet_addr(ipaddr);

unsigned long int netmask_int = inet_addr(netmask);

unsigned long int netmask_low = inet_addr("255.255.255.255");

netmask_low = netmask_low^netmask_int;

ipaddr_int = ipaddr_int | netmask_low;

char *ipbroadcast;

in_addr ipaddr_in;

ipaddr_in.S_un.S_addr = ipaddr_int;

ipbroadcast = inet_ntoa(ipaddr_in);

return ipbroadcast;

}

GetNICMsg.cpp

#include "GetNICMsg.h"

void GetMsgfromcur(char** ipaddr, char **netmask,PIP_ADAPTER_INFO cur, bool printit)

{

IP_ADDR_STRING *pIpAddrString = &(cur->IpAddressList);

if (printit)

{

cout << "IP:" << pIpAddrString->IpAddress.String << endl;

cout << "子网掩码:" << pIpAddrString->IpMask.String << endl;

cout << "Context:" << pIpAddrString->Context << endl;

char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

// mac 地址一般6个字节

// mac 二进制转16进制字符串

char macStr[18] = { 0 };//12+5+1

int k = 0;

for (int j = 0; j < cur->AddressLength; j++){

macStr[k++] = hex[(cur->Address[j] & 0xf0) >> 4];

macStr[k++] = hex[cur->Address[j] & 0x0f];

macStr[k++] = '-';

}

macStr[k - 1] = 0;

cout << "MAC:" << macStr << endl; // mac地址 16进制字符串表示

cout << "--------------------------------------------------" << endl;

}

*ipaddr = (char *)malloc(sizeof(IP_ADDRESS_STRING));

strcpy(*ipaddr, pIpAddrString->IpAddress.String);

*netmask = (char *)malloc(sizeof(IP_ADDRESS_STRING));

strcpy(*netmask, pIpAddrString->IpMask.String);

}

int getAllAdapterInfo(char** ipaddr, char **netmask, int NICtype, bool printit, int sequence)

{

if (sequence == 0)

sequence = 1;

int CurrentSequence = 1;

//char *ipaddr = (char *)malloc(sizeof(IP_ADDRESS_STRING));

PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO[ADAPTERNUM];// 20个网卡空间 足够了

unsigned long stSize = sizeof(IP_ADAPTER_INFO) * ADAPTERNUM;

// 获取所有网卡信息,参数二为输入输出参数

int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);

// 空间不足

if (ERROR_BUFFER_OVERFLOW == nRel) {

// 释放空间

if (pIpAdapterInfo != NULL)

delete[] pIpAdapterInfo;

return -1;

}

PIP_ADAPTER_INFO cur = pIpAdapterInfo;

// 多个网卡 通过链表形式链接起来的

while (cur){

if (cur->Type == NICtype)

{

switch (cur->Type) {

case MIB_IF_TYPE_OTHER:

break;

case MIB_IF_TYPE_ETHERNET:

GetMsgfromcur(ipaddr, netmask,cur, printit);

if (strcmp(UeslessIPaddr, *ipaddr) != 0)

{

if (CurrentSequence == sequence)

return 0;

else

++CurrentSequence;

}

break;

case MIB_IF_TYPE_TOKENRING:

break;

case MIB_IF_TYPE_FDDI:

break;

case MIB_IF_TYPE_PPP:

break;

case MIB_IF_TYPE_LOOPBACK:

break;

case MIB_IF_TYPE_SLIP:

break;

case MIB_IF_TYPE_WiFi:

GetMsgfromcur(ipaddr, netmask, cur, printit);

if (strcmp(UeslessIPaddr, *ipaddr) != 0)

{

if (CurrentSequence == sequence)

return 0;

else

++CurrentSequence;

}

break;

default://无线网卡,Unknown type

break;

}

}

cur = cur->Next;

}

// 释放空间

if (pIpAdapterInfo != NULL)

delete[] pIpAdapterInfo;

}

void getAllAdapterInfo()

{

PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO[ADAPTERNUM];// 20个网卡空间 足够了

unsigned long stSize = sizeof(IP_ADAPTER_INFO) * ADAPTERNUM;

// 获取所有网卡信息,参数二为输入输出参数

int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);

// 空间不足

if (ERROR_BUFFER_OVERFLOW == nRel) {

// 释放空间

if (pIpAdapterInfo != NULL)

delete[] pIpAdapterInfo;

return;

}

PIP_ADAPTER_INFO cur = pIpAdapterInfo;

// 多个网卡 通过链表形式链接起来的

while (cur){

cout << "网卡描述:" << cur->Description << endl;

switch (cur->Type) {

case MIB_IF_TYPE_OTHER:

break;

case MIB_IF_TYPE_ETHERNET:

{

IP_ADDR_STRING *pIpAddrString = &(cur->IpAddressList);

cout << "IP:" << pIpAddrString->IpAddress.String << endl;

cout << "子网掩码:" << pIpAddrString->IpMask.String << endl;

cout << "Context:" << pIpAddrString->Context << endl;

}

break;

case MIB_IF_TYPE_TOKENRING:

break;

case MIB_IF_TYPE_FDDI:

break;

case MIB_IF_TYPE_PPP:

break;

case MIB_IF_TYPE_LOOPBACK:

break;

case MIB_IF_TYPE_SLIP:

break;

default://无线网卡,Unknown type

{

IP_ADDR_STRING *pIpAddrString = &(cur->IpAddressList);

cout << "IP:" << pIpAddrString->IpAddress.String << endl;

cout << "子网掩码:" << pIpAddrString->IpMask.String << endl;

}

break;

}

char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

// mac 地址一般6个字节

// mac 二进制转16进制字符串

char macStr[18] = { 0 };//12+5+1

int k = 0;

for (int j = 0; j < cur->AddressLength; j++){

macStr[k++] = hex[(cur->Address[j] & 0xf0) >> 4];

macStr[k++] = hex[cur->Address[j] & 0x0f];

macStr[k++] = '-';

}

macStr[k - 1] = 0;

cout << "MAC:" << macStr << endl; // mac地址 16进制字符串表示

cur = cur->Next;

cout << "--------------------------------------------------" << endl;

}

// 释放空间

if (pIpAdapterInfo != NULL)

delete[] pIpAdapterInfo;

}

GetNICMsg.h

#ifndef __GETNICMSG__

#define __GETNICMSG__

#include

#include

#include

#include

#pragma comment(lib,"Iphlpapi.lib")

#pragma comment(lib,"ws2_32.lib")

#pragma warning(disable:4996)

using namespace std;

#define ADAPTERNUM 20

#define MIB_IF_TYPE_WiFi 71

#define UeslessIPaddr "0.0.0.0"

int getAllAdapterInfo(char** ipaddr, char **netmask, int NICtype, bool printit, int sequence);

void getAllAdapterInfo();

void GetMsgfromcur(char** ipaddr, char **netmask, PIP_ADAPTER_INFO cur, bool printit);

#endif

通过setsockopt函数确定在哪个网卡上发送

在windows下不可行,但是在Linux下可以通过setsockopt(..., SOL_SOCKET, SO_BINDTODEVICE, "ethX")完成。

参考https://stackoverflow.com/questions/683624/udp-broadcast-on-all-interfaces

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值