A messenger application for Raspberry Pi Zerofor A.U.TH (Real time Embedded systems).
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

112 lignes
3.1 KiB

  1. /*!
  2. * \file client.c
  3. *
  4. * \author Christos Choutouridis AEM:8997 <cchoutou@ece.auth.gr>
  5. */
  6. #include <sys/socket.h>
  7. #include <arpa/inet.h>
  8. #include <netinet/ip_icmp.h>
  9. #include <sys/time.h>
  10. #include <unistd.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include "client.h"
  14. // Calculating the Check Sum
  15. static unsigned short _checksum(void *b, int len) {
  16. unsigned short *buf = b;
  17. unsigned int sum=0;
  18. unsigned short result;
  19. for ( sum = 0; len > 1; len -= 2 )
  20. sum += *buf++;
  21. if ( len == 1 )
  22. sum += *(unsigned char*)buf;
  23. sum = (sum >> 16) + (sum & 0xFFFF);
  24. sum += (sum >> 16);
  25. result = ~sum;
  26. return result;
  27. }
  28. static void _mk_ping_pkt (ping_pkt_t* pkt) {
  29. memset ((void*)&pkt->hdr, 0, sizeof(pkt->hdr));
  30. //memset ((void*)&pkt->msg, '0', sizeof(pkt->msg));
  31. pkt->msg[PING_MSG_S -1] = 0;
  32. pkt->hdr.type = ICMP_ECHO;
  33. pkt->hdr.un.echo.id = getpid();
  34. pkt->hdr.un.echo.sequence = 0;
  35. pkt->hdr.checksum = _checksum (&pkt, sizeof(pkt));
  36. }
  37. bool ping (device_t* dev) {
  38. static int sockfd =-1;
  39. int ttl_val =64;
  40. struct timeval tv_out = { 1, 0 };
  41. if (sockfd == -1 && dev) {
  42. // create socket and set options at ip to TTL and value to 64 and timeout of recv
  43. if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
  44. log_error ("Error: Can not create raw socket for icmp\n");
  45. return false;
  46. }
  47. #ifndef NO_DEBUG
  48. log_debug("Debug: Raw socket for icmp created\n");
  49. #endif
  50. int ret = setsockopt(sockfd, SOL_IP, IP_TTL, &ttl_val, sizeof(ttl_val));
  51. ret |= setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv_out, sizeof(tv_out));
  52. if (ret == -1) {
  53. log_error ("Error: Can not set options to socket\n");
  54. close (sockfd);
  55. sockfd =-1;
  56. return false;
  57. }
  58. #ifndef NO_DEBUG
  59. log_debug("Debug: Raw socket options set\n");
  60. #endif
  61. }
  62. if (!dev) {
  63. // Close socket
  64. close (sockfd);
  65. sockfd =-1;
  66. #ifndef NO_DEBUG
  67. log_debug ("Debug: Raw socket closed\n");
  68. #endif
  69. return true;
  70. }
  71. else {
  72. // ping packet structure
  73. ping_pkt_t pkt;
  74. _mk_ping_pkt (&pkt);
  75. int st;
  76. //send packet
  77. struct sockaddr_in ping_addr = {
  78. .sin_family = AF_INET,
  79. .sin_addr = { htonl (device2addr (dev)) }
  80. };
  81. if ((st=sendto (sockfd, &pkt, sizeof(pkt), 0, (struct sockaddr*)&ping_addr, sizeof(ping_addr))) <= 0)
  82. return false;
  83. #ifndef NO_DEBUG
  84. log_debug ("Debug: Echo send to %s\n", inet_ntoa(ping_addr.sin_addr));
  85. #endif
  86. //receive packet
  87. struct sockaddr_in r_addr;
  88. socklen_t addr_len =sizeof(r_addr);
  89. if ((st=recvfrom (sockfd, &pkt, sizeof(pkt), 0, (struct sockaddr*)&r_addr, &addr_len)) <= 0)
  90. return false;
  91. #ifndef NO_DEBUG
  92. log_debug ("Debug: Echo received from %s\n", inet_ntoa(ping_addr.sin_addr));
  93. #endif
  94. return (pkt.hdr.type == 69 && pkt.hdr.code == 0) ? true: false;
  95. }
  96. return false;
  97. }