summaryrefslogtreecommitdiffabout
path: root/shared-code/FindIFace.h
blob: 8dec8c4e350938f0450967c5707040739d52fbb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef	__FINDIFACE_H
#define	__FINDIFACE_H

#include "SNMPeer.h"
#include "SNMPExtDLL.h"
#include "SNMPOIDs.h"

namespace Klever {

inline BOOL FindIFace(in_addr& target,in_addr& source)
{
DEFINE_OID(ipRouteDest,		OIDipRouteDest);
DEFINE_OID(ipRouteMask,		OIDipRouteMask);
DEFINE_OID(ipRouteIfIndex,	OIDipRouteIfIndex);
DEFINE_OID(ipRouteMetric1,	OIDipRouteMetric1);
DEFINE_OID(ipAdEntIfIndex,	OIDipAdEntIfIndex);
DEFINE_OID(ipAdEntAddr,		OIDipAdEntAddr);
struct	_route	{
	int iface;
	int metric;
	DWORD nm;
}	routes[16];
int nRoutes = 0;
CSNMPVarBindList vbl;
	vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteDest,sizeof(ipRouteDest))));
	vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteMask,sizeof(ipRouteMask))));
	vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteIfIndex,sizeof(ipRouteIfIndex))));
	vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteMetric1,sizeof(ipRouteMetric1))));
CSNMPExtDLL snmp("INETMIB1");
	while(nRoutes<(sizeof(routes)/sizeof(routes[0]))){
		if(
			snmp.Request(CASNAny::typeASNGetNextRequest,vbl,vbl)
			&& vbl.GetCount() == 4
		){
		POSITION p = vbl.GetHeadPosition();
		_route r = {-1,-1};
		in_addr d, m;
		BOOL bD = FALSE, bM = FALSE;
			while(p){
			CSNMPVarBind& vb = vbl.GetNext(p);
				if(
					vb.IsName(ipRouteDest,sizeof(ipRouteDest))
					&& vb.value.type==CASNAny::typeASNIP
				){
					d.s_addr=vb.value.value.ip.s_addr; bD = TRUE;
				}else if(
					vb.IsName(ipRouteMask,sizeof(ipRouteMask))
					&& vb.value.type==CASNAny::typeASNIP
				){
					m.s_addr=vb.value.value.ip.s_addr; bM = TRUE;
				}else if(
					vb.IsName(ipRouteIfIndex,sizeof(ipRouteIfIndex))
					&& vb.value.type==CASNAny::typeASNInteger
				){
					r.iface=vb.value.value.number;
				}else if(
					vb.IsName(ipRouteMetric1,sizeof(ipRouteMetric1))
					&& vb.value.type==CASNAny::typeASNInteger
				){
					r.metric=vb.value.value.number;
				}else
					break;
			}
			if(r.iface<0 || r.metric<0 || (!bD) || (!bM))
				break;
			if((target.s_addr&m.s_addr)==(d.s_addr&m.s_addr)){
				r.nm=htonl(m.s_addr);
				memmove(&routes[nRoutes++],&r,sizeof(routes[0]));
			}
		}else
			break;
	}
	if(!nRoutes)
		return FALSE;
int rn = 0;
	if(nRoutes>1){
		for(int tmp=1;tmp<nRoutes;tmp++)
			if(
				routes[tmp].metric<routes[rn].metric
				|| routes[tmp].nm>routes[rn].nm
			)
				rn = tmp;
	}
int iface = routes[rn].iface;
	vbl.RemoveAll();
	vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipAdEntAddr,sizeof(ipAdEntAddr))));
	vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipAdEntIfIndex,sizeof(ipAdEntIfIndex))));
	for(;;){
		if(
			snmp.Request(CASNAny::typeASNGetNextRequest,vbl,vbl)
			&& vbl.GetCount()==2
		){
		in_addr a; a.s_addr = INADDR_NONE;
		int ifn = -1;
		POSITION p = vbl.GetHeadPosition();
			while(p){
			CSNMPVarBind& vb = vbl.GetNext(p);
				if(
					vb.IsName(ipAdEntAddr,sizeof(ipAdEntAddr))
					&& vb.value.type==CASNAny::typeASNIP
				){
					a.s_addr=vb.value.value.ip.s_addr;
				}else if(
					vb.IsName(ipAdEntIfIndex,sizeof(ipAdEntIfIndex))
					&& vb.value.type==CASNAny::typeASNInteger
				){
					ifn = vb.value.value.number;
				}else
					break;
			}
			if(ifn<0)
				break;
			if(ifn==iface){
				source.s_addr=a.s_addr;
				return TRUE;
			}
		}else
			break;
	}
	return FALSE;
}

};

#endif	// __FINDIFACE_H