?login_element?

Subversion Repositories NedoOS

Rev

Rev 416 | Blame | Compare with Previous | Last modification | View Log | Download

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include "net.h"
  6. unsigned char buf_rx[2048];
  7.  
  8.  
  9. #ifdef _WIN32
  10. WSADATA wsaData;
  11. #else
  12. #include <fcntl.h>
  13. #endif
  14.  
  15. int net_init(void){
  16. #ifdef _WIN32
  17.         WORD wVersionRequested = MAKEWORD(2, 2);
  18.         int err = WSAStartup(wVersionRequested, &wsaData);
  19.         if (err != 0) {
  20.                 fprintf(stderr,"WSAStartup failed with error: %d\n", err);
  21.                 exit(1);
  22.         }
  23. #endif
  24.         return 0;
  25. }
  26.  
  27. int net_dispose(void){
  28. #ifdef _WIN32
  29.         WSACleanup();
  30. #endif
  31.         return 0;
  32. }
  33.  
  34.  
  35. struct in_addr find_yad(char * name){
  36.         struct in_addr yadip;
  37.         int sock;
  38.     sock = socket(AF_INET,SOCK_DGRAM,0);
  39. #ifdef _WIN32
  40.         u_long non_blocked = 1;
  41.         ioctlsocket(sock, FIONBIO, &non_blocked);
  42.     char broadcast = '1';
  43. #else
  44.         fcntl(sock, F_SETFL, O_NONBLOCK);
  45.     int broadcast = 1;
  46. #endif
  47.         puts("Find Yad...");
  48.     if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&broadcast,sizeof(broadcast)) < 0)
  49.     {
  50.         puts("Error in setting Broadcast option");
  51.         return yadip;
  52.     }
  53.         struct sockaddr_in Recv_addr;  
  54.     struct sockaddr_in Sender_addr;
  55.  
  56.     int Recv_addr_len = sizeof(struct sockaddr_in);
  57.  
  58.         const char sendMSG[] = "Who is Yad?";
  59.         const char rplyMSG[] = "I'M YAD";
  60.  
  61.  
  62.     char recvbuff[50] = "";
  63.     int recvbufflen = 50;
  64.        
  65.     Recv_addr.sin_family       = AF_INET;        
  66.     Recv_addr.sin_port         = htons(16729);  
  67.         Recv_addr.sin_addr.s_addr  = INADDR_BROADCAST;
  68.        
  69.         while(1){
  70.                 int len;
  71.  
  72.                 sendto(sock,sendMSG,strlen(sendMSG)+1,0,(const struct sockaddr *)&Recv_addr,sizeof(Recv_addr));
  73.                 sleep(1);
  74.                 len = recvfrom(sock,recvbuff,sizeof(recvbuff)-1,0,(struct sockaddr *)&Recv_addr,&Recv_addr_len);
  75.                 if(len>0){
  76.                         recvbuff[len] = 0x00;
  77.                         if( len>=strlen(rplyMSG) && !strcmp(recvbuff,rplyMSG) ){
  78.                                 //puts(recvbuff);
  79.                                 break;
  80.                         }
  81.                 }
  82.                 sleep(2);
  83.         }
  84. #ifdef _WIN32
  85.         non_blocked = 0;
  86.         ioctlsocket(sock, FIONBIO, &non_blocked);
  87.         shutdown(sock, SD_BOTH);
  88.         closesocket(sock);
  89. #else
  90.         fcntl(sock, F_SETFL, 0);
  91.         shutdown(sock, SHUT_RDWR);
  92.         close(sock);
  93. #endif
  94.         return Recv_addr.sin_addr;
  95. }
  96.  
  97.  
  98. struct in_addr net_resolve(char * name)
  99. {
  100.         struct hostent * h;
  101.         struct in_addr a;
  102.  
  103.         if(name[0] == '?'){
  104.                 a = find_yad(name);
  105.         }else{
  106.                 h = gethostbyname(name);
  107.                
  108.                 if( !h )
  109.                 {
  110.                         fprintf(stderr,"%s: Can't resolve name <%s>\n",__PRETTY_FUNCTION__,name);
  111.                         exit(1);
  112.                 }
  113.  
  114.                 if( h->h_addrtype != AF_INET || h->h_length != 4 )
  115.                 {
  116.                         fprintf(stderr,"%s: Name <%s> doesn't resolve into IPv4 address!\n",__PRETTY_FUNCTION__,name);
  117.                         exit(1);
  118.                 }
  119.  
  120.                 a = *((struct in_addr *)h->h_addr_list[0]);
  121.         }
  122.         return a;
  123. }
  124.  
  125.  
  126. int net_connect(struct in_addr resolved_address)
  127. {
  128.         int sock = socket(AF_INET, SOCK_STREAM, 0);
  129.         struct sockaddr_in addr;
  130.  
  131.  
  132.         sock = socket(AF_INET, SOCK_STREAM, 0);
  133.        
  134.         if( sock==(-1) )
  135.         {
  136.                 fprintf(stderr,"%s: Can't create socket!\n",__PRETTY_FUNCTION__);
  137.                 exit(1);
  138.         }
  139.  
  140.         memset(&addr,0,sizeof(addr));
  141.  
  142.         addr.sin_family = AF_INET;
  143.         addr.sin_port   = htons(AY_PORT);
  144.         addr.sin_addr   = resolved_address;
  145.  
  146.         if( connect(sock,(const struct sockaddr *)&addr, sizeof(addr)) )
  147.         {
  148.                 fprintf(stderr,"%s: Can't connect()!\n",__PRETTY_FUNCTION__); // TODO: add more diagnostics depending on errno
  149.                 exit(1);
  150.         }
  151.  
  152.        
  153.         // set TCP_NODELAY option for sending to ZX
  154. #ifdef _WIN32
  155.         char dummy = 1;
  156.         u_long non_blocked = 1;
  157.         ioctlsocket(sock, FIONBIO, &non_blocked);
  158.         setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &dummy, sizeof(dummy));
  159. #else
  160.         int dummy = 1;
  161.         setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &dummy, sizeof(dummy));
  162. #endif
  163.  
  164.  
  165.         return sock;
  166. }
  167.  
  168.  
  169. void net_disconnect(int sock)
  170. {
  171. #ifdef _WIN32
  172.         u_long non_blocked = 0;
  173.         ioctlsocket(sock, FIONBIO, &non_blocked);
  174.         shutdown(sock, SD_BOTH);
  175.         closesocket(sock);
  176. #else
  177.         shutdown(sock, SHUT_RDWR);
  178.         close(sock);
  179. #endif
  180. }
  181.  
  182.  
  183. // receive exactly the given number of bytes, which must be >0.
  184. // works only with a blocking socket (EAGAIN or EWOULDBLOCK currently terminate the program)
  185. // returns 0 if connection is closed, otherwise 1
  186. // any error (recv() returns (-1)) currently terminates the program
  187. int net_recv_bytes(int sock, uint8_t * ptr, size_t recv_size)
  188. {
  189.         if( !recv_size )
  190.         {
  191.                 fprintf(stderr,"%s: Requested size to receive is zero!\n",__PRETTY_FUNCTION__);
  192.                 exit(1);
  193.         }
  194.  
  195.         ssize_t curr_size;
  196.        
  197.  
  198.         while( recv_size )
  199.         {
  200. #ifdef _WIN32
  201.                 while(1){
  202.                         curr_size=recv(sock, ptr, recv_size, 0);
  203.                         if(curr_size > 0)break;
  204.                         if(WSAGetLastError() != WSAEWOULDBLOCK) break;
  205.                 }
  206. #else
  207.                 curr_size=recv(sock, ptr, recv_size, 0);
  208. #endif
  209.                 if( curr_size==0 ) // connection closed
  210.                 {
  211.                         return 0;
  212.                 }
  213.                 else if( curr_size<0 )
  214.                 {
  215. #ifdef _WIN32
  216.                         fprintf(stderr,"%s: recv() returned (-1), WSAGetLastError() gave: %d!\n",__PRETTY_FUNCTION__,WSAGetLastError());
  217.                         net_dispose();
  218. #else
  219.                         fprintf(stderr,"%s: recv() returned (-1), strerror() gave: %s!\n",__PRETTY_FUNCTION__,strerror(errno));
  220. #endif
  221.                         exit(1);
  222.                 }
  223.                 else if( curr_size > recv_size )
  224.                 {
  225.                         fprintf(stderr,"%s: recv() received more bytes than requested!\n",__PRETTY_FUNCTION__);
  226.                         exit(1);
  227.                 }
  228.  
  229.                 recv_size -= curr_size;
  230.                 ptr       += curr_size;
  231.         }
  232.  
  233.        
  234.         return 1;
  235. }
  236.  
  237.