python通过指定网卡发包_windows下用UDP 广播在特定网卡上发包
背景
總結(jié)
通過路由表來達(dá)到在指定網(wǎng)卡上發(fā)包的效果。
解決方案
更改路由表
使用python的pysnmp庫(kù)更方便
這里給出的是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 是你本機(jī)的IP地址
metric 230 是你決定的metric值,比其他的小就行
if 22 是無線網(wǎng)絡(luò)接口編號(hào),也是通過route print命令看出來的
得到無線網(wǎng)卡信息之后,在特定網(wǎng)絡(luò)廣播(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("找不到一個(gè)可用的無線網(wǎng)卡\n");
closesocket(sock_host);
return -1;
}
// 獲得無線網(wǎng)卡的廣播地址
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 << "子網(wǎng)掩碼:" << 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個(gè)字節(jié)
// mac 二進(jìn)制轉(zhuǎn)16進(jìn)制字符串
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進(jìn)制字符串表示
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個(gè)網(wǎng)卡空間 足夠了
unsigned long stSize = sizeof(IP_ADAPTER_INFO) * ADAPTERNUM;
// 獲取所有網(wǎng)卡信息,參數(shù)二為輸入輸出參數(shù)
int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
// 空間不足
if (ERROR_BUFFER_OVERFLOW == nRel) {
// 釋放空間
if (pIpAdapterInfo != NULL)
delete[] pIpAdapterInfo;
return -1;
}
PIP_ADAPTER_INFO cur = pIpAdapterInfo;
// 多個(gè)網(wǎng)卡 通過鏈表形式鏈接起來的
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://無線網(wǎng)卡,Unknown type
break;
}
}
cur = cur->Next;
}
// 釋放空間
if (pIpAdapterInfo != NULL)
delete[] pIpAdapterInfo;
}
void getAllAdapterInfo()
{
PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO[ADAPTERNUM];// 20個(gè)網(wǎng)卡空間 足夠了
unsigned long stSize = sizeof(IP_ADAPTER_INFO) * ADAPTERNUM;
// 獲取所有網(wǎng)卡信息,參數(shù)二為輸入輸出參數(shù)
int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
// 空間不足
if (ERROR_BUFFER_OVERFLOW == nRel) {
// 釋放空間
if (pIpAdapterInfo != NULL)
delete[] pIpAdapterInfo;
return;
}
PIP_ADAPTER_INFO cur = pIpAdapterInfo;
// 多個(gè)網(wǎng)卡 通過鏈表形式鏈接起來的
while (cur){
cout << "網(wǎng)卡描述:" << 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 << "子網(wǎng)掩碼:" << 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://無線網(wǎng)卡,Unknown type
{
IP_ADDR_STRING *pIpAddrString = &(cur->IpAddressList);
cout << "IP:" << pIpAddrString->IpAddress.String << endl;
cout << "子網(wǎng)掩碼:" << 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個(gè)字節(jié)
// mac 二進(jìn)制轉(zhuǎn)16進(jìn)制字符串
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進(jìn)制字符串表示
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函數(shù)確定在哪個(gè)網(wǎng)卡上發(fā)送
在windows下不可行,但是在Linux下可以通過setsockopt(..., SOL_SOCKET, SO_BINDTODEVICE, "ethX")完成。
參考https://stackoverflow.com/questions/683624/udp-broadcast-on-all-interfaces
總結(jié)
以上是生活随笔為你收集整理的python通过指定网卡发包_windows下用UDP 广播在特定网卡上发包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票内在价值公式
- 下一篇: 征信白户可以申请什么贷款 征信是白户能够