📄 tftpserver.cpp
字号:
if (string[i] >= 'A' && string[i] <= 'Z') string[i] += diff; return string;}bool 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 clean(request* req){ if (req->file) fclose(req->file); 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 init(){ memset(&cfig, 0, sizeof(cfig)); char iniStr[4096]; char name[512]; char value[512]; if (verbatim) { cfig.logLevel = 2; printf("%s\n\n", sVersion); } else if (getSection("LOGGING", iniStr, 1, iniFile)) { char *iniStrPtr = myGetToken(iniStr, 0); if (!iniStrPtr[0] || !strcasecmp(iniStrPtr, "None")) cfig.logLevel = 0; else if (!strcasecmp(iniStrPtr, "Errors")) cfig.logLevel = 1; else if (!strcasecmp(iniStrPtr, "All")) cfig.logLevel = 2; else if (!strcasecmp(iniStrPtr, "Debug")) cfig.logLevel = 3; else { cfig.logLevel = 1; sprintf(logBuff, "Section [LOGGING], Invalid Logging Level: %s, ignored", myGetToken(iniStr, 0)); logMess(logBuff, 1); } } if (!verbatim && cfig.logLevel && logFile[0]) { FILE *f = fopen(logFile, "wt"); if (f) { fprintf(f, "%s\n", sVersion); fclose(f); } else { sprintf(iniStr, "Warning: faled to open log file %s", logFile); syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), iniStr); logFile[0] = 0; } } FILE *f = fopen(iniFile, "rt"); if (f) fclose(f); else { sprintf(logBuff, "Warning: Failed to open ini File %s", iniFile); logMess(logBuff, 1); } if (getSection("LISTEN-ON", iniStr, 1, iniFile)) { char *iniStrPtr = myGetToken(iniStr, 0); for (int i = 0; i < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1)) { WORD port = 69; mySplit(name, value, iniStrPtr, ':'); if (strlen(value)) { port = atoi(value); } DWORD ip = my_inet_addr(name); if (isIP(name) && ip) { 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] = port; i++; break; } } } else { sprintf(logBuff, "Warning: Section [LISTEN-ON], Invalid IP Address %s, ignored", iniStrPtr); logMess(logBuff, 1); } } } if (getSection("HOME", iniStr, 1, iniFile)) { char *iniStrPtr = myGetToken(iniStr, 0); for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1)) { mySplit(name, value, iniStrPtr, '='); if (strlen(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(logBuff, 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(logBuff, 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(logBuff, 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(logBuff, 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(logBuff, 1); } else if (cfig.homes[0].target[0]) { sprintf(logBuff, "Section [HOME], Duplicate Path: %s ignored", iniStrPtr); logMess(logBuff, 1); } else { sprintf(logBuff, "Section [HOME], missing = sign, Invalid Entry: %s ignored", iniStrPtr); logMess(logBuff, 1); } } } if (!cfig.homes[0].target[0]) { strcpy(cfig.homes[0].target, "/home/"); } if (getSection("TFTP-OPTIONS", iniStr, 1, iniFile)) { char *iniStrPtr = myGetToken(iniStr, 0); for (; strlen(iniStrPtr); iniStrPtr = myGetToken(iniStrPtr, 1)) { mySplit(name, value, iniStrPtr, '='); if (strlen(value)) { if (!strcasecmp(name, "blksize")) { DWORD tblksize = atol(value); if (tblksize < 512) blksize = 512; else if (tblksize > USHRT_MAX - 32) blksize = USHRT_MAX - 32; else blksize = tblksize; } else if (!strcasecmp(name, "timeout")) { timeout = atol(value); if (timeout < 1) timeout = 1; else if (timeout > 255) timeout = 255; } else if (!strcasecmp(name, "Read")) { if (!strcasecmp(value, "y")) cfig.fileRead = true; else cfig.fileOverwrite = false; } else if (!strcasecmp(name, "Write")) { if (!strcasecmp(value, "y")) cfig.fileWrite = true; else cfig.fileWrite = false; } else if (!strcasecmp(name, "Overwrite")) { if (!strcasecmp(value, "y")) cfig.fileOverwrite = true; else cfig.fileOverwrite = false; } else { sprintf(logBuff, "Warning: unknown option %s, ignored", name); logMess(logBuff, 1); } } } } if (!cfig.fileRead && !cfig.fileWrite && !cfig.fileOverwrite) { cfig.fileRead = true; } if (getSection("ALLOWED-CLIENTS", iniStr, 1, iniFile)) { char *iniStrPtr = myGetToken(iniStr, 0); for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1)) { DWORD rs = 0; DWORD re = 0; mySplit(name, value, iniStrPtr, '-'); rs = htonl(my_inet_addr(name)); if (strlen(value)) re = htonl(my_inet_addr(value)); else 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(logBuff, 1); } } } if (!cfig.servers[0]) getServ(cfig.servers, cfig.ports, MAX_SERVERS); 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(logBuff, 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]); int 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(tempbuff, cfig.servers[j]), cfig.ports[j], strerror(errno)); logMess(logBuff, 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(logBuff, 1); exit(-1); } else if (verbatim) { printf("starting TFTP...\n"); } else { sprintf(logBuff, "starting TFTP Service"); logMess(logBuff, 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(logBuff, 1); } for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++) { sprintf(logBuff, "listening On: %s:%i", IP2String(tempbuff, cfig.tftpConn[i].server),cfig.tftpConn[i].port); logMess(logBuff, 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(tempbuff, htonl(cfig.hostRanges[i].rangeStart))); strcat(logBuff, temp); sprintf(temp, "%s", IP2String(tempbuff, htonl(cfig.hostRanges[i].rangeEnd))); strcat(logBuff, temp); logMess(logBuff, 1); } } else { sprintf(logBuff, "%s", "permitted clients: all"); logMess(logBuff, 1); } sprintf(logBuff, "max blksize: %u", blksize); logMess(logBuff, 1); sprintf(logBuff, "defult blksize: %u", 512); logMess(logBuff, 1); sprintf(logBuff, "default timeout: %u", timeout); logMess(logBuff, 1); sprintf(logBuff, "file read allowed: %s", cfig.fileRead ? "Yes" : "No"); logMess(logBuff, 1); sprintf(logBuff, "file create allowed: %s", cfig.fileWrite ? "Yes" : "No"); logMess(logBuff, 1); sprintf(logBuff, "file overwrite allowed: %s", cfig.fileOverwrite ? "Yes" : "No"); logMess(logBuff, 1); if (!verbatim) { sprintf(logBuff, "logging: %s", cfig.logLevel > 1 ? "all" : "errors"); logMess(logBuff, 1); } }}void logMess(char *logBuff, BYTE logLevel){ if (verbatim) printf("%s\n", logBuff); else if (logFile[0] && logLevel <= cfig.logLevel) { char currentTime[32]; time_t t = time(NULL); tm *ttm = localtime(&t); strftime(currentTime, sizeof(currentTime), "%d-%b-%y %X", ttm); FILE *f = fopen(logFile, "at"); if (f) { fprintf(f, "[%s] %s\n", currentTime, logBuff); fclose(f); } else { syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), logBuff); } } else if (logLevel <= cfig.logLevel) syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), logBuff);}void logMess(request *req, BYTE logLevel){ 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 (logFile[0] && logLevel <= cfig.logLevel) { char currentTime[32]; time_t t = time(NULL); tm *ttm = localtime(&t); strftime(currentTime, sizeof(currentTime), "%d-%b-%y %X", ttm); FILE *f = fopen(logFile, "at"); if (f) { if (req->path[0]) fprintf(f,"[%s] Client %s:%u %s, %s\n", currentTime, inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage); else fprintf(f,"[%s] Client %s:%u, %s\n", currentTime, inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->serverError.errormessage); fclose(f); } } else if (logLevel <= cfig.logLevel) { char logBuff[256]; if (!req->serverError.errormessage[0]) sprintf(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 + -