Try   HackMD

SMTP (Simple Mail Transfer Protocol )

tags: network programming linux SMTP protocol stack

請勿用於非法用途或塞垃圾, 詐騙, 等 郵件
Author: WhoAmI
e-mail: kccddb@gmail.com
Date: 20220726
Copyright: CC BY-NC-SA

請自行修改

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> /* struct hostent, gethostbyname */ /* S: 220 www.example.com ESMTP Postfix C: HELO mydomain.com S: 250 Hello mydomain.com C: MAIL FROM: <sender@mydomain.com> S: 250 Ok C: RCPT TO: <friend@example.com> S: 250 Ok C: DATA S: 354 End data with <CR><LF>.<CR><LF> C: Subject: test message C: From:""< sender@mydomain.com> C: To:""< friend@example.com> C: C: Hello, C: This is a test. C: Goodbye. C: . S: 250 Ok: queued as 12345 C: quit S: 221 Bye */ typedef struct _tsmtp{ char *c; char *data; }Tsmtp; const char mailbody[]= "Subject: test message\r\n" "From:""< sender@mydomain.com>\r\n" "To:< kkkxyz@gmail.com>\r\n" "\r\n" "Hello,\r\n" "This is a test.\r\n" "Goodbye.\r\n" "\r\n"; #define TOFCU 1 #ifdef TOFCU Tsmtp smtp_c[]={{"HELO ","xyz.edu.tw\r\n"},\ {"MAIL FROM: ","kkxyz@xyz.edu.tw\r\n"},\ {"RCPT TO: ","kkxyz@xyz.edu.tw\r\n"},\ {"DATA","\r\n"},{mailbody,"\r\n.\r\n"},{"QUIT","\r\n"},NULL}; #else Tsmtp smtp_c[]={{"HELO ","xyz.edu.tw\r\n"},\ {"MAIL FROM: ","xyz@xyz.edu.tw\r\n"},\ {"RCPT TO: ","kkkkxyz@gmail.com\r\n"},\ {"DATA","\r\n"},{mailbody,"\r\n.\r\n"},{"QUIT","\r\n"},NULL}; #endif char smtp_from[256]="sender@mydomain.com"; void error(const char *msg) { perror(msg); exit(0); } static int read_delay_ms(int fd,int msec) { struct timeval tval; fd_set readfds; int n; FD_ZERO(&readfds); FD_SET(fd, &readfds); tval.tv_sec = 0; tval.tv_usec = msec*1000; n = select(fd+1, &readfds, NULL, NULL, &tval); return n; } static int read_delay_s(int fd,int sec) { struct timeval tval; fd_set readfds; int n; FD_ZERO(&readfds); FD_SET(fd, &readfds); tval.tv_sec = sec; tval.tv_usec = 0; n = select(fd+1, &readfds, NULL, NULL, &tval); return n; } int main(int argc,char *argv[]) { int i; /* SMPT port=25 */ int portno= 25; char *host ="mymail.fun.edu.tw"; / struct hostent *server; struct sockaddr_in serv_addr; int sockfd, bytes, sent, received, total, message_size; char response[4096]; int step; char message[512]; int tt; printf("Starting...%s\n",host); /* create the socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); /* lookup the ip address */ server = gethostbyname(host); if (server == NULL) error("ERROR"); /* fill in the structure */ memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(portno); memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length); /* connect the socket */ if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); /* send the request */ step=0; printf("Starting...%s:%d\n",host,portno); for(step=0;step<8;step++){ /* receive the response */ printf("Step %d\n",step); memset(response,0,sizeof(response)); total = sizeof(response)-1; received = 0; do { if(step==5){ tt=read_delay_s(sockfd,15); }else tt=read_delay_ms(sockfd,1000); if(tt<=0)break; bytes = read(sockfd,response+received,total-received); if (bytes < 0) error("ERROR reading response from socket"); if (bytes == 0) break; received+=bytes; } while (received < total); printf("Step %d: Recv %d bytes\n",step, received); if (received == total) error("ERROR storing complete response from socket"); response[received]=0; printf("RECV form server:%s\n",response); if(smtp_c[step].c!=NULL){ if(smtp_c[step].c[0]=='\0')goto END; }else goto END; sprintf(message,"%s%s",smtp_c[step].c,smtp_c[step].data); total = strlen(message); printf("SEND[%d]:%s\n",total,message); sent = 0; if(total>0){ do { bytes = write(sockfd,message+sent,total-sent); if (bytes < 0) error("ERROR writing message to socket"); if (bytes == 0) break; sent+=bytes; } while (sent < total); printf("write %d bytes\n",sent); }else break; }//for loop END: /* close the socket */ close(sockfd); /* process response */ printf("Response:\n%s\n",response); return 0; } /* $ ./smpt.exe smtp.xyz.edu.tw Starting...mymail.xyz.edu.tw Starting...mymail.xyz.edu.tw:25 Step 0 Step 0: Recv 99 bytes RECV form server:220 Mymail ESMTP Service(Mail2000 ESMTP Server V6.00) ready Sat, 23 Feb 2019 14:16:24 +0800 (CST) SEND[17]:HELO xyz.edu.tw write 17 bytes Step 1 Step 1: Recv 12 bytes RECV form server:250 Mymail SEND[29]:MAIL FROM: kkxyz@xyz.edu.tw write 29 bytes Step 2 Step 2: Recv 34 bytes RECV form server:250 Sender <kkxyz@xyz.edu.tw> OK SEND[27]:RCPT TO: kkxyz@xyz.edu.tw write 27 bytes Step 3 Step 3: Recv 37 bytes RECV form server:250 Recipient <kkxyz@xyz.edu.tw> OK SEND[6]:DATA write 6 bytes Step 4 Step 4: Recv 35 bytes RECV form server:354 Enter mail, end <CRLF>.<CRLF> SEND[123]: Subject: test message From:< sender@mydomain.com> To:< kkkkxyz@gmail.com> Hello, This is a test. Goodbye. . write 123 bytes Step 5 Step 5: Recv 35 bytes RECV form server:250 Message accepted for delivery SEND[6]:QUIT write 6 bytes Step 6 Step 6: Recv 12 bytes RECV form server:221 Mymail Response: 221 Mymail laikc@laikcpc ~ $ */