// // Created by dongwenzhe on 2022/10/9. // #include #include using namespace std; #include #include #include #include #include #include #include #include #include #include #include #include "opendhcpd.h" #include "s2j/cJSON.h" #include const char *getRequestMethod(const char *buffer) { int i = 0; char httpMethod[64] = {0}; for (; i < 64 && i < strlen(buffer); i++) { if (buffer[i] >= 'A' && buffer[i] <= 'Z') { if (buffer[i] == ' ') { break; } else { httpMethod[i] = buffer[i]; } } } httpMethod[i] = 0; return strdup(httpMethod); } void sendUserList(data19 *req, const char *pRequest, dhcpMap *dhcpCache, data2 *cfig, time_t t) { char logBuff[512]; dhcpMap::iterator p; printf("Input: %s\n", pRequest); if (pRequest == nullptr || strlen(pRequest) == 0) { sprintf(logBuff, "Requeset Json"); logDHCPMess(logBuff, 1); closesocket(req->sock); free(req); return; } cJSON *pRoot = cJSON_Parse(pRequest); if (!pRoot) { closesocket(req->sock); free(req); return; } cJSON *pMsgContent = cJSON_GetObjectItem(pRoot, "msgContent"); if (!pMsgContent) { closesocket(req->sock); free(req); cJSON_Delete(pRoot); return; } cJSON *pUserMac = cJSON_GetObjectItem(pMsgContent, "userMac"); if (!pUserMac) { closesocket(req->sock); free(req); cJSON_Delete(pRoot); return; } req->memSize = (int)(2048 + (135 * dhcpCache->size()) + (cfig->dhcpSize * 26)); req->dp = (char *)calloc(1, req->memSize); if (!req->dp) { sprintf(logBuff, "Memory Error"); logDHCPMess(logBuff, 1); closesocket(req->sock); free(req); return; } cJSON *pRspRoot = cJSON_CreateObject(); cJSON_AddNumberToObject(pRspRoot, "version", 3); cJSON_AddNumberToObject(pRspRoot, "cryptoType", 0); cJSON_AddNumberToObject(pRspRoot, "timeStamp", (unsigned int)time(nullptr)); cJSON *pRspMsg = cJSON_CreateObject(); cJSON *pMsgArray = cJSON_CreateArray(); cJSON_AddItemToObject(pRspMsg, "userInfo", pMsgArray); for (int i = 0; i < cJSON_GetArraySize(pUserMac); i++) { char tempbuff[512]; cJSON *pItem = cJSON_GetArrayItem(pUserMac, i); cJSON *pRspItem = cJSON_CreateObject(); p = dhcpCache->find(pItem->valuestring); cJSON_AddStringToObject(pRspItem, "userMac", pItem->valuestring); if (p != dhcpCache->end()) { data7 *dhcpEntry = p->second; cJSON_AddStringToObject(pRspItem, "ip", IP2String(tempbuff, dhcpEntry->ip)); cJSON_AddStringToObject(pRspItem, "hostname", dhcpEntry->hostname); if (dhcpEntry->display && dhcpEntry->expiry >= t) { tm *ttm = localtime(&dhcpEntry->expiry); strftime(tempbuff, sizeof(tempbuff), "%d-%b-%y %X", ttm); cJSON_AddStringToObject(pRspItem, "leaseExpiry", tempbuff); } else { cJSON_AddStringToObject(pRspItem, "leaseExpiry", "Expiry"); } } else { cJSON_AddStringToObject(pRspItem, "ip", ""); cJSON_AddStringToObject(pRspItem, "hostname", ""); } cJSON_AddItemToArray(pMsgArray, pRspItem); } cJSON_AddItemToObject(pRspRoot, "msgContent", pRspMsg); char *fp = req->dp; //char *maxData = req->dp + (req->memSize - 512); //fp += sprintf(fp, send200, strlen(rspBuf)); fp += sprintf(fp, "%s", cJSON_Print(pRspRoot)); cJSON_Delete(pRoot); cJSON_Delete(pRspRoot); req->bytes = (int)(fp - req->dp); pthread_t threadId; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&threadId, &attr, sendHTTP, (void *)req); pthread_attr_destroy(&attr); } void sendAllLists(data19 *req, bool kRunning, dhcpMap *dhcpCache, data2 *cfig) { char logBuff[512]; data7 *dhcpEntry; dhcpMap::iterator p; req->memSize = (int)(2048 + (135 * dhcpCache->size()) + (cfig->dhcpSize * 26)); req->dp = (char *)calloc(1, req->memSize); if (!req->dp) { sprintf(logBuff, "Memory Error"); logDHCPMess(logBuff, 1); closesocket(req->sock); free(req); return; } char *fp = req->dp; char *maxData = req->dp + (req->memSize - 512); cJSON *pRspRoot = cJSON_CreateObject(); cJSON_AddNumberToObject(pRspRoot, "version", 3); cJSON_AddNumberToObject(pRspRoot, "cryptoType", 0); cJSON_AddNumberToObject(pRspRoot, "timeStamp", (unsigned int)time(nullptr)); cJSON *pRspMsg = cJSON_CreateObject(); cJSON *pMsgArray = cJSON_CreateArray(); cJSON_AddItemToObject(pRspMsg, "users", pMsgArray); for (p = dhcpCache->begin(); kRunning && p != dhcpCache->end() && fp < maxData; p++) { //cJSON *pRspItem = cJSON_CreateObject(); if ((dhcpEntry = p->second)) { cJSON_AddStringToObject(pMsgArray, "", dhcpEntry->mapname); } //cJSON_AddItemToArray(pMsgArray, pRspItem); } cJSON_AddItemToObject(pRspRoot, "msgContent", pRspMsg); fp += sprintf(fp, "%s", cJSON_Print(pRspRoot)); cJSON_Delete(pRspRoot); req->bytes = (int)(fp - req->dp); pthread_t threadId; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&threadId, &attr, sendHTTP, (void *)req); pthread_attr_destroy(&attr); } int method_Judge(data19 *req, char *buffer, char *fp, bool kRunning, dhcpMap *dhcpCache, data2 *cfig, time_t t) { const char *pMethod = getRequestMethod(buffer); const char *pBody = strstr(buffer, "\r\n\r\n"); int res = 0; if (strlen(pBody) > 4) { pBody = strdup(&pBody[4]); } else { pBody = nullptr; } // // printf("+++++++pBody(%04d)\n", recCnt); // if (pBody == nullptr) { // // printf("NULL\n"); // // } else if (strlen(pBody) <= 4) { // // printf("Empty\n"); // } else { // pBody = strdup(&pBody[4]); // // printf("(%s): %s\n", pMethod, pBody); // } // // printf("-------pBody(%04d)\n", recCnt); printf("Head: [%s]\n", fp); if (strcmp(pMethod, "POST") == 0) { sendUserList(req, pBody, dhcpCache, cfig, t); res = 1; return res; } if (pMethod) { free((void *)pMethod); } if (pBody) { free((void *)pBody); } if (fp && !strcasecmp(fp, "/allusers")) { sendAllLists(req, kRunning, dhcpCache, cfig); res = 2; return res; } return res; } #pragma clang diagnostic push #pragma ide diagnostic ignored "cert-err34-c" int getHwAddr(char *buff, char *mac) { if (buff == nullptr || mac == nullptr) { return -1; } int i; unsigned int p[6]; if (sscanf(mac, "%x:%x:%x:%x:%x:%x", &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]) < 6) { return -1; } for (i = 0; i < 6; i++) { buff[i] = (char)p[i]; } return 0; } #pragma clang diagnostic pop int arpSet(const char *ifname, char *ipStr, char *mac) { if (ifname == nullptr || ipStr == nullptr || mac == nullptr) { printf("para is null.\n"); return -1; } struct arpreq req {}; struct sockaddr_in *sin; int ret; int sock_fd; memset(&req, 0, sizeof(struct arpreq)); sin = (struct sockaddr_in *)&req.arp_pa; sin->sin_family = AF_INET; sin->sin_addr.s_addr = inet_addr(ipStr); //arp_dev长度为[16],注意越界 strncpy(req.arp_dev, ifname, 15); req.arp_flags = ATF_PERM | ATF_COM; if (getHwAddr((char *)req.arp_ha.sa_data, mac) < 0) { printf("get mac error.\n"); return -1; } sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) { printf("get socket error.\n"); return -1; } ret = ioctl(sock_fd, SIOCSARP, &req); if (ret < 0) { printf("ioctl error.\n"); close(sock_fd); return -1; } close(sock_fd); return 0; } sockaddr_in get_cliAddr(char *nicif, char *tempbuff, data9 *req) { arpSet(nicif, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->chaddr); sockaddr_in cliAddr {}; memcpy(&cliAddr, &req->remote, sizeof(sockaddr_in)); cliAddr.sin_addr.s_addr = inet_addr(IP2String(tempbuff, req->dhcpp.header.bp_yiaddr)); return cliAddr; }