Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.23 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <netinet/ip.h>
  6. #include <netinet/udp.h>
  7. #include <arpa/inet.h>
  8. #include <netdb.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include <error.h>
  12. #include "checksum.h"
  13.  
  14. #define SOURCE_PORT 5050
  15. #define SOURCE_ADDRESS "fc10:0:0:0:0:0:0:111"
  16.  
  17. /* Struktura pseudo-naglowka (do obliczania sumy kontrolnej naglowka UDP): */
  18. struct phdr {
  19.     struct in_addr ip_src, ip_dst;
  20.     unsigned char unused;
  21.     unsigned char protocol;
  22.     unsigned short length;
  23. };
  24.  
  25. int main(int argc, char **argv) {
  26.  
  27.     int                     sockfd; /* Deskryptor gniazda. */
  28.     int                     socket_option; /* Do ustawiania opcji gniazda. */
  29.     int                     retval; /* Wartosc zwracana przez funkcje. */
  30.  
  31.     /* Struktura zawierajaca wskazowki dla funkcji getaddrinfo(): */
  32.     struct addrinfo         hints;
  33.  
  34.     /*
  35.      * Wskaznik na liste zwracana przez getaddrinfo() oraz wskaznik uzywany do
  36.      * poruszania sie po elementach listy:
  37.      */
  38.     struct addrinfo         *rp, *result;
  39.  
  40.     /* Zmienna wykorzystywana do obliczenia sumy kontrolnej: */
  41.     unsigned short          checksum;
  42.  
  43.     /* Bufor na naglowek IP, naglowek UDP oraz pseudo-naglowek: */
  44.     unsigned char           datagram[sizeof(struct ip) + sizeof(struct udphdr)
  45.                                      + sizeof(struct phdr)] = {0};
  46.  
  47.     /* Wskaznik na naglowek IP (w buforze okreslonym przez 'datagram'): */
  48.     struct ip               *ip_header      = (struct ip *)datagram;
  49.  
  50.     /* Wskaznik na naglowek UDP (w buforze okreslonym przez 'datagram'): */
  51.     struct udphdr           *udp_header     = (struct udphdr *)
  52.             (datagram + sizeof(struct ip));
  53.     /* Wskaznik na pseudo-naglowek (w buforze okreslonym przez 'datagram'): */
  54.     struct phdr             *pseudo_header  = (struct phdr *)
  55.             (datagram + sizeof(struct ip)
  56.              + sizeof(struct udphdr));
  57.     /* SPrawdzenie argumentow wywolania: */
  58.     if (argc != 3) {
  59.         fprintf(
  60.             stderr,
  61.             "Invocation: %s <HOSTNAME OR IP ADDRESS> <PORT>\n",
  62.             argv[0]
  63.         );
  64.  
  65.         exit(EXIT_FAILURE);
  66.     }
  67.  
  68.     /* Wskazowki dla getaddrinfo(): */
  69.     memset(&hints, 0, sizeof(struct addrinfo));
  70.     hints.ai_family = AF_INET6;      /* Domena komunikacyjna (IPv6). */
  71.     hints.ai_socktype = SOCK_RAW;    /* Typ gniazda. */
  72.     hints.ai_protocol = IPPROTO_UDP; /* Protokol. */
  73.  
  74.     retval = getaddrinfo(argv[1], NULL, &hints, &result);
  75.     if (retval != 0) {
  76.         fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(retval));
  77.         exit(EXIT_FAILURE);
  78.     }
  79.  
  80.     /* Opcja okreslona w wywolaniu setsockopt() zostanie wlaczona: */
  81.     socket_option = 1;
  82.  
  83.     /* Przechodzimy kolejno przez elementy listy: */
  84.     for (rp = result; rp != NULL; rp = rp->ai_next) {
  85.  
  86.         /* Utworzenie gniazda dla protokolu UDP: */
  87.         sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  88.         if (sockfd == -1) {
  89.             perror("socket()");
  90.             continue;
  91.         }
  92.  
  93.         int offset = 6;
  94.         retval = setsockopt(sockfd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset));
  95.         if (retval == -1) {
  96.             perror("setsockopt()");
  97.             exit(EXIT_FAILURE);
  98.         } else {
  99.             /* Jezeli gniazdo zostalo poprawnie utworzone i
  100.              * opcja IPV6_CHECKSUM ustawiona: */
  101.             printf("Utworzono socket\n");
  102.             break;
  103.         }
  104.     }
  105.  
  106.     /* Jezeli lista jest pusta (nie utworzono gniazda): */
  107.     if (rp == NULL)
  108.     {
  109.         fprintf(stderr, "Client failure: could not create socket.\n");
  110.         exit(EXIT_FAILURE);
  111.     }
  112.  
  113.     /*********************************/
  114.     /* Wypelnienie pol naglowka UDP: */
  115.     /*********************************/
  116.  
  117.     /* Port zrodlowy: */
  118.     udp_header->uh_sport            =       htons(SOURCE_PORT);
  119.     /* Port docelowy (z argumentu wywolania): */
  120.     udp_header->uh_dport            =       htons(atoi(argv[2]));
  121.  
  122.     /* Rozmiar naglowka UDP i danych. W tym przypadku tylko naglowka: */
  123.     udp_header->uh_ulen             =       htons(sizeof(struct udphdr));
  124.  
  125.     /************************************/
  126.     /* Wypelnienie pol pseudo-naglowka: */
  127.     /************************************/
  128.  
  129.     /* Zrodlowy adres IP: */
  130.     pseudo_header->ip_src.s_addr    =       inet_addr(SOURCE_ADDRESS);
  131.     /* Docelowy adres IP: */                            
  132.     pseudo_header->ip_dst.s_addr    =       ((struct sockaddr_in *)rp->ai_addr)->sin_addr.s_addr;
  133.     /* Pole wyzerowane: */
  134.     pseudo_header->unused           =       0;
  135.     /* Identyfikator enkapsulowanego protokolu: */                                                          
  136.     pseudo_header->protocol         =       IPPROTO_UDP;
  137.     /* Rozmiar naglowka UDP i danych: */                                              
  138.     pseudo_header->length           =       udp_header->uh_ulen;                                        
  139.     /* Obliczenie sumy kontrolnej na podstawie naglowka UDP i pseudo-naglowka: */
  140.     udp_header->uh_sum              =       0;
  141.     checksum                        =       internet_checksum(
  142.                                                 (unsigned short *)udp_header,
  143.                                                 sizeof(struct udphdr)
  144.                                                 + sizeof(struct phdr)
  145.                                             );
  146.  
  147.     udp_header->uh_sum              =       (checksum == 0) ? 0xffff : checksum;
  148.  
  149.     fprintf(stdout, "Sending IPv6 UDP...\n");
  150.  
  151.     /* Wysylanie datagramow co 1 sekunde: */
  152.     for (;;) {
  153.  
  154.         /*
  155.          * Prosze zauwazyc, ze pseudo-naglowek nie jest wysylany
  156.          * (ale jest umieszczony w buforze za naglowkiem UDP dla wygodnego
  157.          * obliczania sumy kontrolnej):
  158.          */
  159.         retval = sendto(
  160.                     sockfd,
  161.                     datagram,
  162.                     sizeof(struct udphdr),
  163.                     0,
  164.                     rp->ai_addr, rp->ai_addrlen
  165.                 );
  166.         if (retval == -1) {
  167.             perror("sendto()");
  168.         } else {
  169.             printf("Packet Send \n");
  170.         }
  171.  
  172.         sleep(1);
  173.     }
  174.  
  175.     exit(EXIT_SUCCESS);
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement