|
- /*!
- * \file client.c
- *
- * \author Christos Choutouridis AEM:8997 <cchoutou@ece.auth.gr>
- */
-
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netinet/ip_icmp.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
-
- #include "client.h"
-
-
- // Calculating the Check Sum
- static unsigned short _checksum(void *b, int len) {
- unsigned short *buf = b;
- unsigned int sum=0;
- unsigned short result;
-
- for ( sum = 0; len > 1; len -= 2 )
- sum += *buf++;
- if ( len == 1 )
- sum += *(unsigned char*)buf;
- sum = (sum >> 16) + (sum & 0xFFFF);
- sum += (sum >> 16);
- result = ~sum;
- return result;
- }
-
- static void _mk_ping_pkt (ping_pkt_t* pkt) {
- memset ((void*)&pkt->hdr, 0, sizeof(pkt->hdr));
- //memset ((void*)&pkt->msg, '0', sizeof(pkt->msg));
- pkt->msg[PING_MSG_S -1] = 0;
-
- pkt->hdr.type = ICMP_ECHO;
- pkt->hdr.un.echo.id = getpid();
- pkt->hdr.un.echo.sequence = 0;
- pkt->hdr.checksum = _checksum (&pkt, sizeof(pkt));
- }
-
- bool ping (device_t* dev) {
- static int sockfd =-1;
- int ttl_val =64;
- struct timeval tv_out = { 1, 0 };
-
-
- if (sockfd == -1 && dev) {
- // create socket and set options at ip to TTL and value to 64 and timeout of recv
- if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
- log_error ("Error: Can not create raw socket for icmp\n");
- return false;
- }
- #ifndef NO_DEBUG
- log_debug("Debug: Raw socket for icmp created\n");
- #endif
- int ret = setsockopt(sockfd, SOL_IP, IP_TTL, &ttl_val, sizeof(ttl_val));
- ret |= setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv_out, sizeof(tv_out));
- if (ret == -1) {
- log_error ("Error: Can not set options to socket\n");
- close (sockfd);
- sockfd =-1;
- return false;
- }
- #ifndef NO_DEBUG
- log_debug("Debug: Raw socket options set\n");
- #endif
- }
-
- if (!dev) {
- // Close socket
- close (sockfd);
- sockfd =-1;
- #ifndef NO_DEBUG
- log_debug ("Debug: Raw socket closed\n");
- #endif
- return true;
- }
- else {
- // ping packet structure
- ping_pkt_t pkt;
- _mk_ping_pkt (&pkt);
- int st;
-
- //send packet
- struct sockaddr_in ping_addr = {
- .sin_family = AF_INET,
- .sin_addr = { htonl (device2addr (dev)) }
- };
- if ((st=sendto (sockfd, &pkt, sizeof(pkt), 0, (struct sockaddr*)&ping_addr, sizeof(ping_addr))) <= 0)
- return false;
- #ifndef NO_DEBUG
- log_debug ("Debug: Echo send to %s\n", inet_ntoa(ping_addr.sin_addr));
- #endif
- //receive packet
- struct sockaddr_in r_addr;
- socklen_t addr_len =sizeof(r_addr);
- if ((st=recvfrom (sockfd, &pkt, sizeof(pkt), 0, (struct sockaddr*)&r_addr, &addr_len)) <= 0)
- return false;
- #ifndef NO_DEBUG
- log_debug ("Debug: Echo received from %s\n", inet_ntoa(ping_addr.sin_addr));
- #endif
- return (pkt.hdr.type == 69 && pkt.hdr.code == 0) ? true: false;
- }
- return false;
- }
-
-
|