netswitch.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. #include <net-snmp/net-snmp-config.h>
  2. #include <net-snmp/net-snmp-includes.h>
  3. #include <net/if.h>
  4. #include <ifaddrs.h>
  5. #include "netswitch.h"
  6. #include "sys.h"
  7. #include "elog.h"
  8. #include "thread.h"
  9. #include "cfg.h"
  10. #include "lock.h"
  11. #include "mail.h"
  12. #include "sqlite_handle.h"
  13. #include "mqtt.h"
  14. #if 1
  15. #define LOGD log_d
  16. #define LOGE log_e
  17. #define LOGW log_w
  18. #else
  19. #define LOGD printf
  20. #define LOGE printf
  21. #define LOGW printf
  22. #endif
  23. #define SW_PORT_START 99329
  24. #define NETSNMP_DS_APP_DONT_FIX_PDUS 0
  25. #ifdef USE_NETSWITCH
  26. typedef struct {
  27. netswitch_info_t sw;
  28. netswitch_info_t sw2;
  29. int ipflag;
  30. char host_ip[64];
  31. char local_ip[64];
  32. int port_start;
  33. pthread_mutex_t mutex;
  34. }ns_handle_t;
  35. static ns_handle_t nsHandle;
  36. static char *get_string(netsnmp_variable_list *var);
  37. ///////////////////////////////////////////////////////////
  38. static netsnmp_variable_list* snmp_getx(int version, char *community, char *ip, char *oid_str, int msgtype)
  39. {
  40. int count;
  41. oid name[MAX_OID_LEN];
  42. size_t namelen=MAX_OID_LEN;
  43. int status;
  44. netsnmp_pdu *pdu=NULL,*rsp=NULL;
  45. netsnmp_session session,*ss=NULL;
  46. netsnmp_variable_list *vars=NULL,*pvar=NULL;
  47. snmp_sess_init(&session);
  48. //session.timeout = 500000; //us
  49. session.version = version;
  50. session.peername = ip;
  51. session.community = (unsigned char*)community;
  52. session.community_len = strlen(community);
  53. oid *poid = snmp_parse_oid(oid_str, name, &namelen);
  54. if(poid==NULL) {
  55. LOGE("___snmp_parse_oid %s failed\n", oid_str);
  56. goto out;
  57. }
  58. ss = snmp_open(&session);
  59. if (ss == NULL) {
  60. LOGE("___snmp_open failed\n");
  61. goto out;
  62. }
  63. pdu = snmp_pdu_create(msgtype);
  64. if(!pdu) {
  65. LOGE("___snmp_pdu_create failed\n");
  66. goto quit;
  67. }
  68. if(msgtype==SNMP_MSG_GETBULK) {
  69. pdu->errstat = 0;//non_repeaters;
  70. pdu->errindex = 10;//max_repetitions;
  71. }
  72. snmp_add_null_var(pdu, name, namelen);
  73. retry:
  74. status = snmp_synch_response(ss, pdu, &rsp);
  75. if (status == STAT_SUCCESS && rsp) {
  76. if (rsp->errstat == SNMP_ERR_NOERROR) {
  77. pvar = snmp_clone_varbind(rsp->variables);
  78. } else {
  79. LOGE("___error in packet, reason: %s\n", snmp_errstring(rsp->errstat));
  80. if (rsp->errindex != 0) {
  81. fprintf(stderr, "failed object: ");
  82. for (count = 1, vars = rsp->variables; vars && count != rsp->errindex; vars = vars->next_variable, count++) {
  83. if (vars) {
  84. fprint_objid(stderr, vars->name, vars->name_length);
  85. }
  86. }
  87. fprintf(stderr, "\n");
  88. }
  89. //retry if the errored variable was successfully removed
  90. if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_APP_DONT_FIX_PDUS)) {
  91. pdu = snmp_fix_pdu(rsp, SNMP_MSG_GET);
  92. snmp_free_pdu(rsp); rsp = NULL;
  93. if (pdu != NULL) {
  94. goto retry;
  95. }
  96. }
  97. }
  98. } else if (status == STAT_TIMEOUT) {
  99. LOGE("snmp_getx timeout: no response from %s\n", session.peername);
  100. } else { /* status == STAT_ERROR */
  101. snmp_sess_perror("snmp_getx", ss);
  102. }
  103. if (rsp) {
  104. snmp_free_pdu(rsp);
  105. }
  106. quit:
  107. snmp_close(ss);
  108. out:
  109. return pvar;
  110. }
  111. /*
  112. SNMP_VERSION_1 SNMP_VERSION_2c SNMP_VERSION_3
  113. SNMP_MSG_GET SNMP_MSG_GETNEXT SNMP_MSG_GETBULK SNMP_MSG_INFORM SNMP_MSG_SET
  114. 1.get:获取一个指定OID的信息;
  115. 2.getnext:指定最终节点的上一层,获取该层及以下子类的信息;
  116. 3.getbulk:和getnext类似,但是getnext只能指定最终层的父节点,而getbulk没有限制;
  117. 4.set:向对方发起控制指令;
  118. 5.getresponse:获取回应;
  119. */
  120. static netsnmp_variable_list* snmp_get(int version, char *community, char *ip, char *oid)
  121. {
  122. return snmp_getx(version, community, ip, oid, SNMP_MSG_GET);
  123. }
  124. static netsnmp_variable_list* snmp_getnext(int version, char *community, char *ip, char *oid)
  125. {
  126. return snmp_getx(version, community, ip, oid, SNMP_MSG_GETNEXT);
  127. }
  128. static netsnmp_variable_list* snmp_getbulk(int version, char *community, char *ip, char *oid)
  129. {
  130. return snmp_getx(version, community, ip, oid, SNMP_MSG_GETBULK);
  131. }
  132. typedef struct {
  133. char chr[2];
  134. }seg_t;
  135. typedef struct {
  136. int cnt;
  137. seg_t seg[20];
  138. }mac_data_t;
  139. static void trim_space(char *ss)
  140. {
  141. while(*ss) ss++;
  142. ss--;
  143. while((*ss)==' ') {*ss=0; ss--;};
  144. }
  145. static int parse_mac(char *ss, mac_data_t *mac)
  146. {
  147. char sp=0;
  148. int i=0,j=0,idx=0;
  149. if(strstr(ss, "-")) {
  150. sp = '-';
  151. }
  152. else if(strstr(ss, " ")) {
  153. sp = ' ';
  154. }
  155. else if(strstr(ss, ":")) {
  156. sp = ':';
  157. }
  158. else {
  159. LOGE("___ wrong mac addr\n");
  160. return -1;
  161. }
  162. trim_space(ss);
  163. memset(mac, 0, sizeof(mac_data_t));
  164. while(ss[i]) {
  165. if(ss[i]==sp) {
  166. idx++;
  167. j=0;
  168. }
  169. else {
  170. mac->seg[idx].chr[j++] = (char)toupper(ss[i]);
  171. }
  172. i++;
  173. }
  174. mac->cnt = idx+1;
  175. return 0;
  176. }
  177. static int get_mac(char *ss, char *mac)
  178. {
  179. int i,j,r;
  180. mac_data_t mdat;
  181. r = parse_mac(ss, &mdat);
  182. if(r) {
  183. return -1;
  184. }
  185. j = 0;
  186. for(i=0; i<mdat.cnt; i++) {
  187. if(mdat.seg[i].chr[1]==0) {
  188. mac[j++] = '0';
  189. mac[j++] = mdat.seg[i].chr[0];
  190. }
  191. else {
  192. mac[j++] = mdat.seg[i].chr[0];
  193. mac[j++] = mdat.seg[i].chr[1];
  194. }
  195. if(i!=mdat.cnt-1) {
  196. mac[j++] = ':';
  197. }
  198. }
  199. mac[j] = 0;
  200. return 0;
  201. }
  202. static port_info_t* get_port(netswitch_info_t *sw, char *mac)
  203. {
  204. int i;
  205. port_info_t *pt=NULL;
  206. for(i=0; i<SW_PORT_MAX; i++) {
  207. pt = &sw->port[i];
  208. if(strcmp(mac, pt->mac)==0) {
  209. break;
  210. }
  211. }
  212. return pt;
  213. }
  214. static char *get_string(netsnmp_variable_list *var)
  215. {
  216. u_char *buf=NULL;
  217. size_t buflen=256,outlen=0;
  218. buf = calloc(buflen, 1);
  219. if(!buf) {
  220. LOGE("___ calloc failed\n");
  221. return NULL;
  222. }
  223. if (sprint_realloc_variable(&buf, &buflen, &outlen, 1, var->name, var->name_length, var)) {
  224. return (char*)buf;
  225. } else {
  226. free(buf);
  227. }
  228. return NULL;
  229. }
  230. static int get_ipaddr(int family, char *iface, char *host, char *local)
  231. {
  232. int r=-1;
  233. char temp[100];
  234. struct ifaddrs *ifap, *ifa;
  235. if (getifaddrs(&ifap) == -1) {
  236. LOGE("___getifaddrs() error\n"); return -1;
  237. }
  238. for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
  239. if (ifa->ifa_addr != NULL && ifa->ifa_addr->sa_family == family) {
  240. if(family==AF_INET) {
  241. struct sockaddr_in *sa,*msk;
  242. sa = (struct sockaddr_in *) ifa->ifa_addr;
  243. msk = (struct sockaddr_in *) ifa->ifa_netmask;
  244. char *p = (char*)inet_ntop(family, &sa->sin_addr, temp, INET6_ADDRSTRLEN);
  245. if(p) {
  246. //printf("___ipv4: %s\n", p);
  247. if(strcmp(p, "127.0.0.1") && strcmp(p, "172.17.0.1")) {
  248. strcpy(host, p); strcpy(local, p);
  249. p = strrchr(host, '.'); p[1] = '1'; p[2] = 0;
  250. r = 0; break;
  251. }
  252. }
  253. }
  254. else {
  255. struct sockaddr_in6 *sa,*msk;
  256. sa = (struct sockaddr_in6 *)ifa->ifa_addr;
  257. msk = (struct sockaddr_in6 *)ifa->ifa_netmask;
  258. char *p = (char*)inet_ntop(family, &sa->sin6_addr, temp, INET6_ADDRSTRLEN);
  259. if(p) {
  260. //printf("___ipv6: %s\n", p);
  261. if(strcmp(p, "::1")) {
  262. strcpy(host, p); strcpy(local, p);
  263. p = strrchr(host, ':'); p[1] = '1'; p[2] = 0;
  264. r = 0; break;
  265. }
  266. }
  267. }
  268. }
  269. }
  270. freeifaddrs(ifap);
  271. return r;
  272. }
  273. static void sw_init(netswitch_info_t *sw)
  274. {
  275. int i;
  276. memset(sw, 0, sizeof(netswitch_info_t));
  277. for(i=0; i<SW_PORT_MAX; i++) {
  278. sw->port[i].id = -1;
  279. }
  280. }
  281. static void sw_init2(netswitch_info_t *sw)
  282. {
  283. int i;
  284. memset(sw, 0, sizeof(netswitch_info_t));
  285. for(i=0; i<SW_PORT_MAX; i++) {
  286. sw->port[i].id = i;
  287. }
  288. }
  289. static void sw_sync_mac_by_id(netswitch_info_t *dst, netswitch_info_t *src)
  290. {
  291. int i,id;
  292. for(i=0; i<SW_PORT_MAX; i++) {
  293. id = src->port[i].id;
  294. if(src->port[i].id != -1) {
  295. strcpy(dst->port[id].mac, src->port[i].mac);
  296. }
  297. }
  298. }
  299. static int get_id_by_mac(netswitch_info_t *sw, port_info_t *pt)
  300. {
  301. int i;
  302. if(pt->mac[0]==0) {
  303. return -1;
  304. }
  305. for(i=0; i<SW_PORT_MAX; i++) {
  306. if(strcmp(sw->port[i].mac, pt->mac)==0) {
  307. return i;
  308. }
  309. }
  310. return -1;
  311. }
  312. static void sw_sync_ip_by_mac(netswitch_info_t *dst, netswitch_info_t *src)
  313. {
  314. int i,id;
  315. for(i=0; i<SW_PORT_MAX; i++) {
  316. id = get_id_by_mac(dst, &src->port[i]);
  317. if(id>=0) {
  318. strcpy(dst->port[id].ip, src->port[i].ip);
  319. }
  320. }
  321. }
  322. static void sw_print(char *s, netswitch_info_t *sw)
  323. {
  324. int i,id,flag=0;
  325. port_info_t *pt=NULL;
  326. for(i=0; i<SW_PORT_MAX; i++) {
  327. pt = &sw->port[i];
  328. if(pt->id>=0 && (pt->ip[0] || pt->mac[0])) {
  329. LOGD("__%s__, port[%d].id: %d\n", s, i+1, pt->id);
  330. LOGD("__%s__, port[%d].up: %d\n", s, i+1, pt->up);
  331. LOGD("__%s__, port[%d].ip: %s\n", s, i+1, pt->ip);
  332. LOGD("__%s__, port[%d].mac: %s\n", s, i+1, pt->mac);
  333. LOGD("__%s__, port[%d].desc: %s\n", s, i+1, pt->desc);
  334. flag = 1;
  335. }
  336. }
  337. if(flag) LOGD("\n");
  338. }
  339. /*
  340. public
  341. BRIDGE-MIB
  342. dot1dTpFdbEntry: 1.3.6.1.2.1.17.4.3.1
  343. 1: dot1dTpFdbAddress - MacAddress(4 - octets)
  344. 2: dot1dTpFdbPort - Integer32(2 - int, int32)
  345. 3: dot1dTpFdbStatus - INTEGER(2 - int, int32)
  346. private
  347. tplink-ipAddr.mib
  348. public
  349. RFC1213-MIB
  350. ipNetToMediaEntry: 1.3.6.1.2.1.4.22.1
  351. 1: ipNetToMediaIfIndex - INTEGER(2 - integer (32 bit))
  352. 2: ipNetToMediaPhysAddress - PhysAddress(4 - octets)
  353. 3: ipNetToMediaNetAddress - IpAddress(64 - IP address)
  354. 4: ipNetToMediaType - INTEGER(2 - integer (32 bit))
  355. ipAddrEntry: 1.3.6.1.2.1.4.20.1 //host ipaddr
  356. 1: ipAdEntAddr - IpAddress(64 - IP address)
  357. 2: ipAdEntIfIndex - INTEGER(2 - integer (32 bit))
  358. 3: ipAdEntNetMask - IpAddress(64 - IP address)
  359. 4: ipAdEntBcastAddr - INTEGER(2 - integer (32 bit))
  360. 5: ipAdEntReasmMaxSize - INTEGER(2 - integer (32 bit))
  361. ifEntry: 1.3.6.1.2.1.2.2.1
  362. 1: ifreIndex - INTEGER(2 - integer (32 bit))
  363. 6: ifPhysAddress - PhysAddress(4 - octets)
  364. 8: ifOperStatus - INTEGER(2 - integer (32 bit))
  365. No Such Instance currently exists at this OID:
  366. 1. MIB文件没有正确添加到MIB树里面,因此agent在收到查询以后真的找不到目标OID.
  367. 2. MIB文件添加成功了,但是snmpd.conf里面的关于权限的配置不对。agent在收到client的查询以后也找到了该OID,
  368. 但是因为没有权限因此返回“No Such Instance currently exists at this OID”。
  369. 关于权限粗看会以为很复杂,尤其是在心浮气燥的时候,其实静下心来仔细看看就会发现也就那么回事
  370. 3. 第三种情况比较特殊,对于net-snmp不熟的也可能会范理解上的错误。
  371. 使用snmpget而忘记了添加OID结尾的实例标识符,net-snmp则会报出“No Such Instance currently exists at this OID”的错误。
  372. */
  373. static int get_port_start(char *ip)
  374. {
  375. int port=-1,val;
  376. netsnmp_variable_list *var,*pvar;
  377. #ifdef SW_STATIC_PORT_START
  378. return SW_PORT_START;
  379. #endif
  380. char *ifEntry="1.3.6.1.2.1.2.2";
  381. var = snmp_getbulk(SNMP_VERSION_2c, "public", ip, ifEntry);
  382. if(var) {
  383. int id;
  384. char *p,*tok="ifIndex.";
  385. for (pvar=var; pvar; pvar=pvar->next_variable) {
  386. char *pstr = get_string(pvar);
  387. if(pstr) {
  388. //LOGD("____5___%s\n", pstr);
  389. p = strstr(pstr, tok);
  390. if(p) {
  391. val = atoi(p+strlen(tok));
  392. if(val>2) {
  393. port = val;
  394. }
  395. }
  396. free(pstr);
  397. if(port>1000) {
  398. LOGD("_____start port: %d\n", port);
  399. break;
  400. }
  401. }
  402. }
  403. snmp_free_varbind(var);
  404. }
  405. else {
  406. LOGE("___get_port_start, snmp_getnext %s failed\n", ifEntry);
  407. }
  408. return port;
  409. }
  410. static int get_hostnet(char *hnet, char *hip)
  411. {
  412. char *p=NULL;
  413. strcpy(hnet, hip);
  414. p = strrchr(hnet, '.');
  415. if(!p) {
  416. p = strrchr(hnet, ':');
  417. if(!p) {
  418. return -1;
  419. }
  420. }
  421. p[1] = '0'; p[2] = 0;
  422. return 0;
  423. }
  424. static int set_ip(char *ip)
  425. {
  426. char temp[200];
  427. sprintf(temp, "ip addr add dev eth0 %s/24", ip);
  428. return system(temp);
  429. }
  430. static int set_gw(char *gw)
  431. {
  432. char temp[200];
  433. sprintf(temp, "route del default; route add default gw %s", gw);
  434. return system(temp);
  435. }
  436. static int sw_get(netswitch_info_t *sw)
  437. {
  438. int r=-1;
  439. int i,j,find=0;
  440. char temp[200];
  441. char *p,*pstr,*tok;
  442. netswitch_info_t tmp;
  443. netsnmp_variable_list *var,*pvar;
  444. ns_handle_t *h=&nsHandle;
  445. sw_init2(sw);
  446. if(h->ipflag==0) {
  447. #ifdef SW_STATIC_IP
  448. char hnet[100];
  449. strcpy(h->host_ip, SW_HOST_IP);
  450. //get_hostnet(hnet, h->host_ip);
  451. //sprintf(temp, "ip addr add dev eth0 %s/24; ip route add %s/24 via %s", SW_PDU_IP, hnet, h->host_ip);
  452. //set_ip(SW_PDU_IP); set_gw(h->host_ip);
  453. h->ipflag = 1;
  454. #else
  455. r = get_ipaddr(AF_INET, "eth0", h->host_ip, h->local_ip);
  456. if(r) {
  457. LOGE("____get ip4 failed\n");
  458. r = get_ipaddr(AF_INET6, "eth0", h->host_ip, h->local_ip);
  459. if(r) {
  460. LOGE("____get ip6 failed\n");
  461. return -1;
  462. }
  463. }
  464. #if 0
  465. if((p=strrchr(h->local_ip, '.')) || (p=strrchr(h->local_ip, ':'))) {
  466. if(strstr(p, "132")==0) {
  467. p[1] = 0; strcat(p, "132");
  468. set_ip(h->local_ip);
  469. }
  470. }
  471. #endif
  472. set_gw(h->host_ip);
  473. h->ipflag = 1;
  474. #endif
  475. }
  476. //LOGD("___netswitch ip: %s\n", h->host_ip);
  477. if(h->port_start==-1) {
  478. h->port_start = get_port_start(h->host_ip);
  479. if(h->port_start==-1) {
  480. return -1;
  481. }
  482. }
  483. #if 1
  484. char *dot1dTpFdbEntryOid="1.3.6.1.2.1.17.4.3.1";
  485. var = snmp_getbulk(SNMP_VERSION_2c, "public", h->host_ip, dot1dTpFdbEntryOid);
  486. if(var) {
  487. sw_init(&tmp);
  488. i = j = 0;
  489. for (pvar=var; pvar!=NULL; pvar=pvar->next_variable) {
  490. char *pstr = get_string(pvar);
  491. if(pstr) {
  492. //LOGD("__1__%s\n", pstr);
  493. if(strstr(pstr, "2.17.4.3.1.1") || strstr(pstr, "3.6.1.2.1.17.4.3.1.1")) { //mac
  494. tok = "Hex-STRING: ";
  495. p = strstr(pstr, tok);
  496. if(p) {
  497. p += strlen(tok);
  498. get_mac(p, tmp.port[i].mac);
  499. //LOGD("____%d___mac: %s\n", i, tmp.port[i].mac);
  500. i++;
  501. }
  502. }
  503. if(strstr(pstr, "2.17.4.3.1.2") || strstr(pstr, "3.6.1.2.1.17.4.3.1.2")) { //port
  504. tok = "INTEGER: ";
  505. p = strstr(pstr, tok);
  506. if(p) {
  507. p += strlen(tok);
  508. tmp.port[j].id = atoi(p) - h->port_start;
  509. //LOGD("____%d___id: %s, port_start: %d, id: %d\n", j, p, h->port_start, tmp.port[j].id);
  510. j++;
  511. }
  512. }
  513. free(pstr);
  514. }
  515. }
  516. snmp_free_varbind(var);
  517. if(j>0) {
  518. sw_sync_mac_by_id(sw, &tmp);
  519. find = 1;
  520. }
  521. }
  522. else {
  523. LOGE("___snmp_getbulk mac failed\n");
  524. }
  525. if(find==0) {
  526. return -1;
  527. }
  528. #endif
  529. #if 1
  530. char *ipNetToMediaEntryOid="1.3.6.1.2.1.4.22.1";
  531. var = snmp_getbulk(SNMP_VERSION_2c, "public", h->host_ip, ipNetToMediaEntryOid);
  532. if(var) {
  533. sw_init(&tmp);
  534. i = j = 0;
  535. for (pvar=var; pvar; pvar=pvar->next_variable) {
  536. pstr = get_string(pvar);
  537. if(pstr) {
  538. //LOGD("__2__%s\n", pstr);
  539. if(strstr(pstr, "ipNetToMediaPhysAddress")) { //mac addr
  540. tok = "STRING: ";
  541. p = strstr(pstr, tok);
  542. if(p) {
  543. p += strlen(tok);
  544. get_mac(p, tmp.port[i].mac);
  545. //LOGD("__%d__%s\n", i, tmp.port[i].mac);
  546. i++;
  547. }
  548. }
  549. else {
  550. tok = "3.6.1.2.1.4.22.1.2.";
  551. p = strstr(pstr, tok);
  552. if(p) {
  553. char *tok1 = " =";
  554. char *tok2 = "Hex-STRING: ";
  555. p += strlen(tok);
  556. p = strstr(p, ".")+1;
  557. char *p1=strstr(p, tok1);
  558. char *p2=strstr(p, tok2);
  559. if(p1 && p2) {
  560. memcpy(tmp.port[i].ip, p, p1-p);
  561. tmp.port[i].ip[p1-p] = 0;
  562. p2 += strlen(tok2);
  563. get_mac(p2, tmp.port[i].mac);
  564. LOGD("__%d__ %s, %s\n", i, tmp.port[i].mac, tmp.port[i].ip);
  565. i++;
  566. }
  567. }
  568. }
  569. if(strstr(pstr, "ipNetToMediaNetAddress")) { //ip addr
  570. tok = "IpAddress: ";
  571. char *p=strstr(pstr, tok);
  572. if(p) {
  573. p += strlen(tok);
  574. strcpy(tmp.port[j].ip, p);
  575. //LOGD("__%d__ %s\n", j, p);
  576. j++;
  577. }
  578. }
  579. free(pstr);
  580. }
  581. }
  582. snmp_free_varbind(var);
  583. if(i>0) {
  584. sw_sync_ip_by_mac(sw, &tmp);
  585. //sw_print("11", sw);
  586. }
  587. }
  588. else {
  589. LOGE("___snmp_getbulk ip addr failed\n");
  590. }
  591. #endif
  592. #if 0
  593. char *ifEntry="1.3.6.1.2.1.2.2.1.8";
  594. for(i=0; i<SW_PORT_MAX; i++) {
  595. sprintf(temp, "%s.%d", ifEntry, i+h->port_start);
  596. var = snmp_get(SNMP_VERSION_2c, "public", h->host_ip, temp);
  597. if(var) {
  598. int id;
  599. tok = "ifOperStatus.";
  600. for (pvar=var; pvar; pvar=pvar->next_variable) {
  601. pstr = get_string(pvar);
  602. if(pstr) {
  603. //LOGD("__3__%s\n", pstr);
  604. p = strstr(pstr, tok);
  605. if(!p) { //ip addr
  606. tok = "INTEGER: ";
  607. p = strstr(pstr, tok);
  608. if(p) {
  609. p += strlen(tok);
  610. id = atoi(p)-h->port_start;
  611. if(strstr(p, "up")) {
  612. sw->port[id].up = 1;
  613. }
  614. else if(strstr(p, "down")) {
  615. sw->port[id].up = 0;
  616. }
  617. j++;
  618. }
  619. }
  620. free(pstr);
  621. }
  622. }
  623. snmp_free_varbind(var);
  624. }
  625. else {
  626. LOGE("___snmp_get ifup failed\n");
  627. }
  628. }
  629. //sw_print("111", sw);
  630. #endif
  631. return 0;
  632. }
  633. static int sw_chk(netswitch_info_t *sw1, netswitch_info_t *sw2, netswitch_evts_t *evts)
  634. {
  635. int i,flag=0;
  636. memset(evts, 0, sizeof(netswitch_evts_t));
  637. for(i=0; i<SW_PORT_MAX; i++) {
  638. if(i<SW_PORT_INDEX_START || i>SW_PORT_INDEX_END) {
  639. continue;
  640. }
  641. #if 0
  642. if(sw1->port[i].up != sw2->port[i].up) {
  643. if(sw2->port[i].up) {
  644. LOGD("____ port %d plug in\n", i+1);
  645. //evts->evt[i].cab = EVT_CAB_IN;
  646. }
  647. else {
  648. LOGD("____ port %d plug out\n", i+1);
  649. //evts->evt[i].cab = EVT_CAB_OUT;
  650. }
  651. //flag = 1;
  652. }
  653. if(strlen(sw2->port[i].ip) && strcmp(sw1->port[i].ip, sw2->port[i].ip)) {
  654. LOGD("____ port %d ip changed from: %s, to: %s\n", i+1, sw1->port[i].ip, sw2->port[i].ip);
  655. //evts->evt[i].dev = EVT_IP_CHG;
  656. //flag = 1;
  657. }
  658. #endif
  659. if(strlen(sw2->port[i].mac) && strcmp(sw1->port[i].mac, sw2->port[i].mac)) {
  660. LOGD("____ port %d mac changed from: %s, to: %s\n", i+1, sw1->port[i].mac, sw2->port[i].mac);
  661. evts->evt[i].dev = EVT_MAC_CHG;
  662. flag = 1;
  663. }
  664. }
  665. return flag;
  666. }
  667. static int sw_cpy(netswitch_info_t *dst, netswitch_info_t *src)
  668. {
  669. int i;
  670. for(i=0; i<SW_PORT_MAX; i++) {
  671. if(i<SW_PORT_INDEX_START || i>SW_PORT_INDEX_END) {
  672. continue;
  673. }
  674. dst->port[i].up = src->port[i].up;
  675. if(src->port[i].ip[0]) {
  676. strcpy(dst->port[i].ip, src->port[i].ip);
  677. }
  678. if(src->port[i].mac[0]) {
  679. strcpy(dst->port[i].mac, src->port[i].mac);
  680. }
  681. }
  682. return 0;
  683. }
  684. static sqlite3* get_db(void)
  685. {
  686. return __globalDeviceManage.db;
  687. }
  688. static int get_prod_id(void)
  689. {
  690. return __globalDeviceManage._globalDevInfo.product.id;
  691. }
  692. static int sw_save(sqlite3 *db, netswitch_info_t *old, netswitch_info_t *new)
  693. {
  694. int i;
  695. for(i=0; i<SW_PORT_MAX; i++) {
  696. if(i<SW_PORT_INDEX_START || i>SW_PORT_INDEX_END) {
  697. continue;
  698. }
  699. if(memcmp(&old->port[i], &new->port[i], sizeof(netswitch_info_t))) {
  700. dev_switch_update_port(db, &new->port[i]);
  701. //LOGD("____ i: %d, id: %d\n", i, new->port[i].id);
  702. }
  703. }
  704. return 0;
  705. }
  706. static int sw_alarm(netswitch_evts_t *evts, netswitch_info_t *old, netswitch_info_t *new)
  707. {
  708. int r=-1;
  709. int i,flag=0;
  710. time_t now;
  711. char temp[400];
  712. char time_str[100];
  713. char alarm_str[4000];
  714. time(&now);
  715. strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(&now));
  716. alarm_str[0] = 0;
  717. for(i=0; i<SW_PORT_MAX; i++) {
  718. if(evts->evt[i].dev) {
  719. if(evts->evt[i].dev==EVT_MAC_CHG) {
  720. //snprintf(temp, sizeof(temp), "port[%d] mac changed from %s to %s\n", i+1, old->port[i].mac, new->port[i].mac);
  721. sprintf(temp, "|$%s$|, |$%s$|%d %s -> %s\n", language_alarm_MAC_changed[0], language_alarm_Ch[0], i+1, old->port[i].mac, new->port[i].mac);
  722. strcat(alarm_str, temp);
  723. flag = 1;
  724. }
  725. }
  726. }
  727. if(flag) {
  728. r = dev_insert_alarm_info(get_db(), get_prod_id(), 2, time_str, alarm_str);
  729. smtp_post_alarm(ALARM_TYPE_NETWORK, 0, NETWORK_MAC_CHANGED, alarm_str);
  730. alarm_para_t para;
  731. para.id = i+1;
  732. para.nalarm = 1;
  733. para.action = -1;
  734. para.actionId = -1;
  735. mqtt_post_alarm(ALARM_TYPE_NETWORK, 0, alarm_str, &para);
  736. }
  737. return r;
  738. }
  739. #endif
  740. static void* netswitch_thread(void *arg)
  741. {
  742. #ifdef USE_NETSWITCH
  743. int r;
  744. netswitch_evts_t evts;
  745. thread_handle_t *h=(thread_handle_t*)arg;
  746. ns_handle_t *nh=(ns_handle_t*)h->arg;
  747. nh->sw2 = nh->sw;
  748. SOCK_STARTUP;
  749. while(h->quit==0) {
  750. pthread_mutex_lock(&nh->mutex);
  751. r = sw_get(&nh->sw2);
  752. pthread_mutex_unlock(&nh->mutex);
  753. if(r==0 && sw_chk(&nh->sw, &nh->sw2, &evts)) {
  754. sw_alarm(&evts, &nh->sw, &nh->sw2);
  755. sw_save(get_db(), &nh->sw, &nh->sw2);
  756. sw_cpy(&nh->sw, &nh->sw2);
  757. }
  758. sleep(1);
  759. }
  760. SOCK_CLEANUP;
  761. #endif
  762. pthread_exit(NULL);
  763. }
  764. int netswitch_init(void)
  765. {
  766. #ifdef USE_NETSWITCH
  767. ns_handle_t *h=&nsHandle;
  768. memset(h, 0, sizeof(ns_handle_t));
  769. h->port_start = -1; //SW_PORT_START
  770. dev_switch_init(get_db(), &h->sw);
  771. pthread_mutex_init(&h->mutex, NULL);
  772. thread_start(THREAD_ID_SWITCH, netswitch_thread, h);
  773. #endif
  774. return 0;
  775. }
  776. int netswitch_deinit(void)
  777. {
  778. #ifdef USE_NETSWITCH
  779. ns_handle_t *h=&nsHandle;
  780. thread_stop(THREAD_ID_SWITCH);
  781. pthread_mutex_destroy(&h->mutex);
  782. #endif
  783. return 0;
  784. }
  785. int netswitch_get(netswitch_info_t *info)
  786. {
  787. #ifdef USE_NETSWITCH
  788. ns_handle_t *h=&nsHandle;
  789. if(!info) {
  790. return -1;
  791. }
  792. pthread_mutex_lock(&h->mutex);
  793. *info = h->sw2;
  794. pthread_mutex_unlock(&h->mutex);
  795. #endif
  796. return 0;
  797. }