📄 tftpserver.cpp
字号:
strncpy(name, iniStrPtr, 255); char *value = strchr(name, '='); if (value) { *value = 0; value++; if (!cfig.homes[0].alias[0] && cfig.homes[0].target[0]) { sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", iniStrPtr); logMess(1); } else if (strchr(name, '/') || strchr(name, '\\') || strchr(name, '>') || strchr(name, '<') || strchr(name, '.')) { sprintf(logBuff, "Section [HOME], invalid chars in alias %s, entry ignored", name); logMess(1); } else if (name[0] && strlen(name) < 64 && value[0]) { for (int i = 0; i < 8; i++) { if (cfig.homes[i].alias[0] && !strcasecmp(name, cfig.homes[i].alias)) { sprintf(logBuff, "Section [HOME], Duplicate Entry: %s ignored", iniStrPtr); logMess(1); break; } else if (!cfig.homes[i].alias[0]) { strcpy(cfig.homes[i].alias, name); strcpy(cfig.homes[i].target, value); if (cfig.homes[i].target[strlen(cfig.homes[i].target) - 1] != '/') strcat(cfig.homes[i].target, "/"); break; } } } else { sprintf(logBuff, "Section [HOME], alias name too large", name); logMess(1); } } else if (!cfig.homes[0].alias[0] && !cfig.homes[0].target[0]) { strcpy(cfig.homes[0].target, name); if (cfig.homes[0].target[strlen(cfig.homes[0].target) - 1] != '/') strcat(cfig.homes[0].target, "/"); } else if (cfig.homes[0].alias[0]) { sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", iniStrPtr); logMess(1); } else if (cfig.homes[0].target[0]) { sprintf(logBuff, "Section [HOME], Duplicate Path: %s ignored", iniStrPtr); logMess(1); } else { printf(logBuff, "Section [HOME], missing = sign, Invalid Entry: %s ignored", iniStrPtr); logMess(1); } } } if (!cfig.homes[0].target[0]) { strcpy(cfig.homes[0].target, "/home/"); } if (getSection("TFTP-OPTIONS", iniStr, sizeof(iniStr), iniFile)) { char *iniStrPtr = cleanstr(iniStr, false); for (;strlen(iniStrPtr);iniStrPtr = cleanstr(iniStrPtr, true)) { char name[256]; strncpy(name, iniStrPtr, 255); char *value = strchr(name, '='); if (value != NULL) { *value = 0; value++; myLower(name); if (!strcmp(name, "blksize")) { DWORD tblksize = atol(value); if (tblksize < 512) blksize = 512; else if (tblksize > MAX_BLOCK_SIZE) blksize = MAX_BLOCK_SIZE; else blksize = tblksize; } else if (!strcmp(name, "interval")) { interval = atol(value); if (interval < 1) interval = 3; else if (interval > 120) interval = 120; } else if (!strcmp(name, "overwrite")) { if (!strcasecmp(value, "y")) cfig.overwrite = true; else cfig.overwrite = false; } else if (!strcmp(name, "port-range")) { char *ptr = strchr(value, '-'); if (ptr) { *ptr = 0; cfig.minport = atol(value); cfig.maxport = atol(++ptr); if (cfig.minport < 1024 || cfig.minport >= USHRT_MAX || cfig.maxport < 1024 || cfig.maxport >= USHRT_MAX || cfig.minport > cfig.maxport) { cfig.minport = 0; cfig.maxport = 0; sprintf(logBuff, "Invalid port range %s\n", value); logMess(1); } } else { sprintf(logBuff, "Invalid port range %s\n", value); logMess(1); } } else { sprintf(logBuff, "Unknown Option %s\n", name); logMess(1); } } } } if (getSection("ALLOWED-CLIENTS", iniStr, sizeof(iniStr), iniFile)) { char *iniStrPtr = cleanstr(iniStr, false); for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = cleanstr(iniStrPtr, true)) { char name[256]; strncpy(name, iniStrPtr, 255); DWORD rs = 0; DWORD re = 0; char *ptr = strchr(name, '-'); if (ptr) { *ptr = 0; ptr++; rs = htonl(my_inet_addr(name)); re = htonl(my_inet_addr(ptr)); } else { rs = htonl(my_inet_addr(name)); re = rs; } if (rs && rs != INADDR_NONE && re && re != INADDR_NONE && rs <= re) { cfig.hostRanges[i].rangeStart = rs; cfig.hostRanges[i].rangeEnd = re; i++; } else { sprintf(logBuff, "Section [ALLOWED-CLIENTS] Invalid entry %s in ini file, ignored", iniStrPtr); logMess(1); } } } if (!cfig.servers[0]) getServ(); int i = 0; for (int j = 0; j < MAX_SERVERS && cfig.servers[j]; j++) { cfig.tftpConn[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (cfig.tftpConn[i].sock == -1) { sprintf(logBuff, "Failed to Create Socket"); logMess(1); continue; } cfig.tftpConn[i].addr.sin_family = AF_INET; cfig.tftpConn[i].addr.sin_addr.s_addr = cfig.servers[j]; cfig.tftpConn[i].addr.sin_port = htons(cfig.ports[j]); socklen_t nRet = bind(cfig.tftpConn[i].sock, (sockaddr*) & cfig.tftpConn[i].addr, sizeof(struct sockaddr_in) ); if (nRet == -1) { close(cfig.tftpConn[i].sock); sprintf(logBuff, "%s Port %u, bind failed, %s", IP2String(cfig.servers[j]), cfig.ports[j], strerror(errno)); logMess(1); continue; } if (cfig.maxFD < cfig.tftpConn[i].sock) cfig.maxFD = cfig.tftpConn[i].sock; cfig.tftpConn[i].server = cfig.servers[j]; cfig.tftpConn[i].port = cfig.ports[j]; i++; } cfig.maxFD++; if (!cfig.tftpConn[0].server) { sprintf(logBuff, "No listening Interfaces available, stopping..."); logMess(1); exit(-1); } else if (verbatim) { printf("\nStarting TFTP...\n"); } else { sprintf(logBuff, "Starting TFTP Service"); logMess(1); } if (cfig.tftpConn[0].server) { for (int i = 0; i < 8; i++) if (cfig.homes[i].target[0]) { sprintf(logBuff, "alias /%s is mapped to %s", cfig.homes[i].alias, cfig.homes[i].target); logMess(1); } for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++) { sprintf(logBuff, "listening On: %s:%i", IP2String(cfig.tftpConn[i].server),cfig.tftpConn[i].port); logMess(1); } if (cfig.hostRanges[0].rangeStart) { char temp[128]; for (int i = 0; i <= 32 && cfig.hostRanges[i].rangeStart; i++) { sprintf(logBuff, "%s", "permitted clients: "); sprintf(temp, "%s-", IP2String(htonl(cfig.hostRanges[i].rangeStart))); strcat(logBuff, temp); sprintf(temp, "%s", IP2String(htonl(cfig.hostRanges[i].rangeEnd))); strcat(logBuff, temp); logMess(1); } } else { sprintf(logBuff, "%s", "permitted Clients: all"); logMess(1); } if (cfig.minport) { sprintf(logBuff, "port range: %u-%u", cfig.minport, cfig.maxport); logMess(1); } else { sprintf(logBuff, "server port ranges: all"); logMess(1); } sprintf(logBuff, "max blksize: %u", blksize); logMess(1); sprintf(logBuff, "defult blksize: %u", 512); logMess(1); sprintf(logBuff, "default interval: %u", interval); logMess(1); sprintf(logBuff, "overwrite existing files: %s", cfig.overwrite ? "yes" : "no"); logMess(1); if (!verbatim) { sprintf(logBuff, "logging: %s", cfig.logLevel > 1 ? "all" : "errors"); logMess(1); } }}char *cleanstr(char* buff, bool next){ if (strlen(buff) && next) buff += strlen(buff) + 1; while (strlen(buff)) if (*buff >= '0' && *buff <= '9' || *buff >= 'A' && *buff <= 'Z' || *buff >= 'a' && *buff <= 'z' || *buff == '/') break; else buff += strlen(buff) + 1; return buff;}bool getSection(char *sectionName, char *buffer, int sizeofbuffer, char *fileName){ char section[128]; sprintf(section, "[%s]", sectionName); myUpper(section); FILE *f = fopen(fileName, "r"); char buff[512]; char *ptr = buffer; *ptr = 0; bool found = false; while (f && fgets(buff, 255, f)) { myUpper(buff); if (strstr(buff, section) == buff) { found = true; while (fgets(buff, 255, f)) { if (strstr(buff, "[") == buff) break; sprintf(ptr, "%s", buff); ptr += strlen(buff); while (*ptr <= 32) ptr--; ptr++; *ptr = 0; ptr++; } *ptr = 0; } } if (f) fclose(f); return found;}char *IP2String(DWORD ip){ in_addr inaddr; inaddr.s_addr = ip; sprintf(tempbuff, "%s", inet_ntoa(inaddr)); return tempbuff;}char *myUpper(char *string){ char diff = 'a' - 'A'; WORD len = strlen(string); for (int i = 0; i < len; i++) if (string[i] >= 'a' && string[i] <= 'z') string[i] -= diff; return string;}char *myLower(char *string){ char diff = 'a' - 'A'; WORD len = strlen(string); for (int i = 0; i < len; i++) if (string[i] >= 'A' && string[i] <= 'Z') string[i] += diff; return string;}BYTE isIP(char *string){ int j = 0; for (; *string; string++) { if (*string == '.') j++; else if (*string < '0' || *string > '9') return 0; } if (j == 3) return 1; else return 0;}void getServ(){ struct ifconf Ifc; struct ifreq IfcBuf[MAX_SERVERS]; struct ifreq *pIfr; int num_ifreq; int i; int fd; Ifc.ifc_len = sizeof(IfcBuf); Ifc.ifc_buf = (char *) IfcBuf; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { if ( ioctl(fd, SIOCGIFCONF, &Ifc) >= 0) { num_ifreq = Ifc.ifc_len / sizeof(struct ifreq); for ( pIfr = Ifc.ifc_req, i = 0 ; i < num_ifreq; pIfr++, i++ ) { DWORD ip = ((sockaddr_in*)(&pIfr->ifr_ifru.ifru_addr))->sin_addr.s_addr; for (BYTE j = 0; j < MAX_SERVERS; j++) { if (cfig.servers[j] == ip) break; else if (!cfig.servers[j]) { cfig.servers[j] = ip; cfig.ports[j] = 69; break; } } } } }}void clean(request* req){ if (req->file) fclose(req->file); if (req->m_socket >= 0) close(req->m_socket); if (req->pkt[0]) free(req->pkt[0]); if (req->pkt[1]) free(req->pkt[1]); free(req);}DWORD my_inet_addr(char* str){ if (str == NULL) return INADDR_ANY; DWORD x = inet_addr(str); if (x == INADDR_NONE) return INADDR_ANY; else return x;}void logMess(BYTE messLevel){ if (verbatim) printf("%s\n", logBuff); else if (messLevel <= cfig.logLevel) syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), logBuff);}void logMess(request *req, BYTE messLevel){ if (verbatim) { if (!req->serverError.errormessage[0]) printf(req->serverError.errormessage, strerror(errno)); if (req->path[0]) printf("Client %s:%u %s, %s\n", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage); else printf("Client %s:%u, %s\n", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->serverError.errormessage); } else if (messLevel <= cfig.logLevel) { if (!req->serverError.errormessage[0]) printf(req->serverError.errormessage, strerror(errno)); if (req->path[0]) sprintf(logBuff,"Client %s:%u %s, %s\n", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage); else sprintf(logBuff,"Client %s:%u, %s\n", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->serverError.errormessage); syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), logBuff); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -