Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // MSV TFTP Daemon 1.0 - 21.11.2012 22:24
- // 1.1 - 24.11.2012 2:40
- // Used MSVLibrsry code, Brain, Reverse engineering.
- // Not used: FAQ, RFC.
- // DEL: OS: +(available) Windows, -(unavailable, temporarily) Linux, ?(oh my god. maybe) Android.
- // NEW: OS: +(available) Windows, (available) Linux, (oh noo, i'm next) Android.
- // I want:
- // test, test, test...
- // Add config.
- // Add logs.
- // Add tftp extensions.
- // Read Only. Add Write file.
- // Create tftp client.
- // Make packages: rpm, ebuild, deb.
- // Send packages to repositary.
- // Android, i see you.
- // DEL: Problem: send last block. Close file or wait? <Yes>. Last block lose. -> Fail.
- // Main(): go to far far down.
- #ifdef WIN32
- #include <WinSock2.h>
- #include <io.h>
- #include <direct.h>
- #define lseek64 _lseeki64
- typedef __int64 int64;
- typedef int socklen_t;
- #pragma comment(lib,"Ws2_32.lib")
- #else // linux way
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
- #define SOCKADDR SOCKADDR_IN
- #define SOCKADDR sockaddr
- #define SOCKADDR_IN sockaddr_in
- #define O_BINARY 0
- #define FILE_BEGIN 0
- #define FILE_CUR 1
- #define FILE_END 2
- typedef long long int64;
- typedef int SOCKET;
- #define memcpy memmove
- #define closesocket(sock) close(sock)
- void Sleep(unsigned int i){ usleep((int64)i*1000); return ; }
- #endif
- #ifdef WIN32
- #ifndef WINCE
- HANDLE _std_input_handle = GetStdHandle(STD_INPUT_HANDLE);
- HANDLE _std_output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
- #endif
- #endif
- // all systems
- #include <stdio.h>
- #include <time.h>
- #include <fcntl.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- ///////////////////////////////////////////////////////////////////////////////////// For Me
- #define _del(v){ if(v) free(v); }
- #define _deln(v){ if(v){ free(v); v=0; } }
- #define _newn(sz) (unsigned char*)malloc(sz)
- ///////////////////////////////////////////////////////////////////////////////////// Strings
- class VString{
- public:
- unsigned char *data;
- unsigned int sz;
- void Init(){ data=0; sz=0; }
- VString(){ Init(); }
- VString(const VString &line){ data=line; sz=line.sz; }
- VString(const char *line){ data=(unsigned char*)line; sz=strlen((const char*)line); }
- VString(const unsigned char *line){ data=(unsigned char*)line; sz=strlen((const char*)line); }
- VString(const char *line, const unsigned int s){ data=(unsigned char*)line; sz=s; }
- VString(const unsigned char *line, const unsigned int s){ data=(unsigned char *)line; sz=s; }
- VString& operator=(VString line){ data=line; sz=line; return *this; }
- VString& operator=(unsigned char* line){ data=line; sz=strlen((const char*)line); return *this; }
- VString& operator=(char* line){ data=(unsigned char*)line; sz=strlen((const char*)line); return *this; }
- VString& set(VString line){ return setu(line.data, line.sz); return *this; }
- VString& set(char* line, const unsigned int size){ sz=size; data=(unsigned char*)line; return *this; }
- VString& setu(unsigned char* line, const unsigned int size){ sz=size; data=(unsigned char*)line; return *this; }
- VString str(const int p){
- if(sz<=p) return VString();
- return VString(data+p, sz-p);
- }
- operator void*()const { return data; }
- operator char*()const { return (char*)data; }
- operator unsigned char*()const { return data; }
- operator unsigned int()const { return sz; }
- // operator VString(){ return *this; }
- char *rchar()const { return (char*)data; }
- unsigned char *uchar()const { return data; }
- char *end()const { return (char*)data+sz; }
- unsigned char *endu()const { return data+sz; }
- void Clean(){ Init(); }
- };
- class MString: public VString{
- // unsigned char *data;
- // unsigned int sz;
- public:
- void Init(){ _deln(data); sz=0; }
- MString(){ data=0; sz=0; }
- protected:
- void MStringNew(const void*line){ // optimize
- if(!sz){ data=0; return ; }
- data=_newn(sz+1);
- if(line) memcpy(data, line, sz);
- data[sz]=0;
- return ;
- }
- public:
- MString(const VString line){ sz=line.sz; MStringNew(line); }
- MString(const unsigned char *line, const unsigned int s){ sz=s; MStringNew(line); }
- MString& operator=(const VString line){ sz=line; unsigned char *odata=data; MStringNew(line); _deln(odata); return *this; }
- MString& operator=(const unsigned char* line){ unsigned char *odata=data; sz=strlen((const char*)line); MStringNew(line); _deln(odata); return *this; }
- MString& operator=(const char* line){ unsigned char *odata=data; sz=strlen((const char*)line); MStringNew(line); _deln(odata); return *this; }
- ~MString(){ Init(); }
- MString& set(VString line){ sz=line; unsigned char *odata=data; MStringNew(line); _deln(odata); return *this; }
- MString& set(char* line, const unsigned int size){ sz=size; unsigned char *odata=data; MStringNew(line); _deln(odata); return *this; }
- MString& setu(unsigned char* line, const unsigned int size){ sz=size; unsigned char *odata=data; MStringNew(line); _deln(odata); return *this; }
- MString str(const int p){
- if(sz<=p) return MString();
- return MString(data+p, sz-p);
- }
- void Clean(){ Init(); }
- };
- int compare(unsigned char *l1, unsigned int s1, unsigned char *l2, unsigned int s2){
- if(s1!=s2) return 0;
- for(int i=0; i<s1; i++){ if(*l1++!=*l2++) return 0; }
- return 1;
- }
- int operator==(const VString &l1, const VString &l2){ return compare(l1, l1, l2, l2); }
- int operator==(const unsigned char *l1, const VString &l2){ return compare((unsigned char*)l1, strlen((char*)l1), l2, l2); }
- int operator==(const VString &l1, const unsigned char *l2){ return compare(l1, l1, (unsigned char*)l2, strlen((char*)l2)); }
- int operator==(const char *l1, const VString &l2){ return compare((unsigned char*)l1, strlen((char*)l1), l2, l2); }
- int operator==(const VString &l1, const char *l2){ return compare(l1, l1, (unsigned char*)l2, strlen((char*)l2)); }
- ///////////////////////////////////////////////////////////////////////////////////// String Operations
- int rtms(unsigned char *to, unsigned char *fr, unsigned int frs, unsigned char *&line){ //read to symbol
- if(!line || !fr || !frs) return 0;
- unsigned char *lfr, *tfr, *ln;
- to-=frs-1;
- for(line; line<to; line++){
- if(*line==*fr){
- lfr=fr+1; tfr=fr+frs; ln=line+1;
- for(lfr; lfr<tfr; lfr++){ if(*ln++!=*lfr){ break; } }
- if(lfr==tfr){ return 1; }
- }
- } line=to+(frs-1); return 0;
- }
- VString PartLine(VString line, VString &two, VString el){
- unsigned char *pos=line;
- if(!rtms(line.endu(), el, el, pos)){ two.Clean(); return line; }
- two.setu(pos+el.sz, line.endu()-pos-el.sz);
- return VString(line.uchar(), pos-line.uchar());
- }
- ///////////////////////////////////////////////////////////////////////////////////// Print
- inline int print(const VString &line){ if(!line) return 0;
- #ifdef WIN32
- DWORD wr;
- return WriteFile(_std_output_handle, line, line, &wr, 0); //printf(line);
- #else
- return write(1, line, line);
- #endif
- }
- // multiprint
- inline int print(const VString &l1, const VString &l2){
- int r=print(l1); r=print(l2) && r; return r;
- }
- inline int print(const VString &l1, const VString &l2, const VString &l3){
- int r=print(l1); r=print(l2) && r; r=print(l3) && r; return r;
- }
- ///////////////////////////////////////////////////////////////////////////////////// Socket Options
- int OpenUDPPort(unsigned short port, const char*ip=0){
- SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sock==-1) return 0;
- SOCKADDR_IN sin;
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
- if (ip) sin.sin_addr.s_addr = inet_addr(ip);
- else sin.sin_addr.s_addr = INADDR_ANY;
- //int i=1;
- //if(setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&i, 4)) print("SOCKOPT ERROR\r\n");
- //if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i))) print("SOCKOPT ERROR\r\n");
- // KeepAlive(sock);
- int err = bind(sock, (SOCKADDR*)&sin, sizeof(sin) ); if(err<0){ closesocket(sock); return 0; }
- //err = listen( sock, SOMAXCONN); if(err<0) { closesocket(sock); return 0; }
- return (int)sock;
- }
- ///////////////////////////////////////////////////////////////////////////////////// Defines
- #define S1K 1024
- #define S8K (1024*8)
- ///////////////////////////////////////////////////////////////////////////////////// File IO
- #ifdef WIN32
- #define O_CREAT _O_CREAT
- #define O_RDONLY _O_RDONLY
- #define S_IREAD _S_IREAD
- #define S_IWRITE _S_IWRITE
- #endif
- int CreateFile(char* file, int op, int pm){ return open(file, op|O_BINARY, pm); }
- int ReadFile(int fl, unsigned char* buf, unsigned int sz){ return read(fl, buf, sz); }
- int WriteFile(int fl, unsigned char* buf, unsigned int sz){ return write(fl, buf, sz); }
- int64 SetFilePointer(int fl, int64 pos, int origin=FILE_BEGIN){ return lseek64(fl, pos, origin); }
- int CloseHandle(int fl){ return close(fl); }
- #define IsHandle(h) ((h) && ((int)h)!=-1)
- #define ishandle(h) ((h) && ((int)h)!=-1)
- bool IsFile(VString file){
- int fl; fl=CreateFile(file, O_RDONLY, S_IREAD| S_IWRITE);
- if(!ishandle(fl)) return 0;
- CloseHandle(fl); return 1;
- }
- ///////////////////////////////////////////////////////////////////////////////////// Special
- unsigned int time(){ return time(0); }
- ///////////////////////////////////////////////////////////////////////////////////// Hmm. Class for open files
- class tftp_data{
- public:
- unsigned int ip; unsigned short port; unsigned int time, fl;
- MString file;
- };
- class tftp_d{
- tftp_data tdata[128]; int tdatai; // may create: elenents list
- public:
- tftp_d(){ tdatai=0; memset(tdata, 0, sizeof(tdata)); } // may use: for .. tdata[i].time=0;
- tftp_data* Get(unsigned int ip, unsigned short port){
- for(int k=0; k<sizeof(tdata)/sizeof(tftp_data); k++){
- if(tdata[k].ip==ip && tdata[k].port==port) return &tdata[k];
- }
- return 0;
- }
- tftp_data* Add(unsigned int ip, unsigned short port, VString file){
- int i=-1;
- for(int k=0; k<sizeof(tdata)/sizeof(tftp_data); k++){
- if(!tdata[k].time){ i=k; break; } // don't dublicate tdata=...
- }
- if(i==-1) i=DelOld(1); else DelOld(); // hmm. no free. kill one?
- tdata[i].ip=ip; tdata[i].port=port; tdata[i].file=file; tdata[i].time=time();
- return &tdata[i];
- }
- int DelOld(int r=0){
- int d=0; unsigned int tm=time(); // del more 1 hour? 3600 sec.
- for(int k=0; k<sizeof(tdata)/sizeof(tftp_data); k++){
- if(tdata[d].time+3600<tm){
- tdata[k].time=0; tdata[k].ip=0; tdata[k].port=0; tdata[k].file.Clean();
- if(tdata[k].fl){ CloseHandle(tdata[k].fl); tdata[k].fl=0; }
- }
- if(tdata[d].time>tdata[k].time) d=k;
- }
- return d;
- }
- int Del(tftp_data* data){
- if(!data) return 0;
- //int pos=data-&tdata;
- if(data->fl){ CloseHandle(data->fl); tdata->fl=0; }
- data->time=0; data->ip=0; data->port=0; data->file.Clean();
- return 1;
- }
- }tftp_d;
- ///////////////////////////////////////////////////////////////////////////////////// TFTP
- #define TFTP_RRQ 1
- #define TFTP_WRQ 2
- #define TFTP_DATA 3
- #define TFTP_ACK 4
- #define TFTP_ERR 5
- int TFTPError(int err, VString text, unsigned char *buf, unsigned int bufs){
- if(bufs<5) return 0;
- if(text=="-"){
- switch(err){
- case 0: text="Not defined, see error message (if any)."; break;
- case 1: text="File not found."; break;
- case 2: text="Access violation."; break;
- case 3: text="Disk full or allocation exceeded."; break;
- case 4: text="Illegal TFTP operation."; break;
- case 5: text="Unknown transfer ID."; break;
- case 6: text="File already exists."; break;
- case 7: text="No such user."; break;
- }
- }
- int bufi=5;
- buf[0]=0; buf[1]=TFTP_ERR; *(unsigned short*)(buf+2)=ntohs(err);
- if(bufs<5+text.sz) text.sz=bufs-5;
- memcpy(buf+4, text, text); bufi+=text.sz;
- buf[bufi-1]=0;
- return bufi;
- }
- int TFTPSend(SOCKET sock, unsigned int cip, unsigned int cport, unsigned char *buf, int bufi){
- // send
- sockaddr_in from; int fromlen=sizeof(from);
- from.sin_family = AF_INET;
- from.sin_addr.s_addr=ntohl(cip);
- from.sin_port=htons(cport);
- return sendto(sock, (char*)buf, bufi, 0, (struct sockaddr*)&from, fromlen);
- }
- int RecvUDP(SOCKET sock, unsigned int cip, unsigned int cport, unsigned char* rcvbuf, int rcvi){
- if(rcvi<2) return 0;
- unsigned char buf[S1K]; int bufi=0;
- unsigned short op=ntohs(*(unsigned short*)rcvbuf);
- if(op==TFTP_RRQ){
- VString fl=VString(rcvbuf+2, rcvi-2), type, o, t;
- fl=PartLine(fl, t, VString("\x00", 1));
- type=PartLine(t, t, VString("\x00", 1));
- MString file=fl; //file.Add("./", fl);
- if(!IsFile(file)){ print("Request file: ", file, ". Not found.\r\n");
- bufi=TFTPError(1, "-", buf, sizeof(buf));
- TFTPSend(sock, cip, cport, buf, bufi);
- return 0;
- }
- t=file; o=PartLine(t, t, "..");
- if(!o || t){
- print("Hacher found! Get file: '", file, "'. Get out!\r\n");
- bufi=TFTPError(2, "-", buf, sizeof(buf));
- TFTPSend(sock, cip, cport, buf, bufi);
- return 0;
- }
- tftp_data* tdata=tftp_d.Add(cip, cport, file);
- tdata->fl=CreateFile(file, O_RDONLY, 0);
- buf[0]=0; buf[1]=TFTP_DATA; *(unsigned short*)(buf+2)=ntohs(1);
- ReadFile(tdata->fl, buf+4, 512);
- TFTPSend(sock, cip, cport, buf, 516); print("Request file: '", file, ". Send first block. \r\n");
- return 1;
- }
- else if(op==TFTP_ACK){
- unsigned short bl=ntohs(*(unsigned short*)(rcvbuf+2));
- buf[0]=0; buf[1]=TFTP_DATA; *(unsigned short*)(buf+2)=ntohs(bl+1);
- tftp_data* tdata=tftp_d.Get(cip, cport);
- if(!tdata){ print("No pervous request!\r\n");
- bufi=TFTPError(5, "-", buf, sizeof(buf));
- TFTPSend(sock, cip, cport, buf, bufi);
- return 0;
- }
- //print("block: ", itos(bl), "\r\n");
- printf("ACK: %d. Send next block.\r\n", bl);
- unsigned int p=SetFilePointer(tdata->fl, bl*512, FILE_BEGIN);
- int rd=ReadFile(tdata->fl, buf+4, 512);
- TFTPSend(sock, cip, cport, buf, 4+rd);
- if(!rd){
- printf("End Of File. Close.\r\n", bl);
- tftp_d.Del(tdata);
- }
- return 1;
- }else{
- int z=0;
- }
- return 1;
- }
- ///////////////////////////////////////////////////////////////////////////////////// Main
- int main(int args, char* arg[]){
- #ifdef WIN32
- WSADATA WsaData; WSAStartup (MAKEWORD( 2, 2 ), &WsaData);
- #endif
- // server configurations
- int openport=69;
- chdir("./"); // set directory
- //openport
- SOCKET osock=OpenUDPPort(openport);
- if(!osock){ printf("Ooops. UDP port not opened. Exit."); return 1; }
- // recv
- sockaddr_in from, local; int fromlen=sizeof(from);
- unsigned char rcvbuf[S8K], *rcv=(unsigned char*)&rcvbuf; int rcvi=0;
- while(1){
- rcvi=recvfrom(osock, (char*)rcv, S8K, 0, (struct sockaddr*)&from, (socklen_t*)&fromlen);
- if(rcvi==0){ Sleep(1); continue; }
- else if(rcvi<0){ break; }
- RecvUDP(osock, ntohl(from.sin_addr.s_addr), htons(from.sin_port), rcvbuf, rcvi);
- }
- printf("Exit.\r\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement