VPN termux about China.net

Friday, 29 August 2025

sip.cpp

 
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/select.h>
#define DO 0xfd
#define WONT 0xfc
#define WILL 0xfb
#define DONT 0xfe
#define CMD 0xff
#define CMD_ECHO 1
#define CMD_WINDOW_SIZE 31
#define BUFLEN 20096
//#define BUFLEN 20
int len;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
#include <pthread.h>
#define RESET   "\033[0m"
#define RED     "\033[1;31m"
#define GREEN   "\033[1;32m"
#define YELLOW  "\033[1;33m"
#define BLUE    "\033[1;34m"
#define CYAN    "\033[1;36m"
#define BOLD    "\033[1m"
// Kolorowe printf-y
#define info(...)  printf(GREEN __VA_ARGS__); printf(RESET)
#define warn(...)  printf(YELLOW __VA_ARGS__); printf(RESET)
#define err(...)   fprintf(stderr, RED __VA_ARGS__); fprintf(stderr, RESET)
#define debug(...) printf(CYAN __VA_ARGS__); printf(RESET)
#define START_PORT 1
#define END_PORT 1024
#define TIMEOUT_SEC 0
#define TIMEOUT_USEC 200000  // 200ms
const char *target_ip;
void *scan_port(void *arg) {
    int port = *(int *)arg;
    free(arg);
    int sockfd;
    struct sockaddr_in target;
    struct timeval timeout;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) pthread_exit(NULL);
    timeout.tv_sec = TIMEOUT_SEC;
    timeout.tv_usec = TIMEOUT_USEC;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
    setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
    target.sin_family = AF_INET;
    target.sin_port = htons(port);
    target.sin_addr.s_addr = inet_addr(target_ip);
    int result = connect(sockfd, (struct sockaddr *)&target, sizeof(target));
    if (result == 0) {
        printf("Port %d jest OTWARTY\n", port);
    }
    close(sockfd);
    pthread_exit(NULL);
}
int scan(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Użycie: %s <IP>\n", argv[0]);
        return 1;
    }
    target_ip = argv[1];
    printf(GREEN,"Skanowanie hosta %s w zakresie portów %d-%d...\n", target_ip, START_PORT, END_PORT);
    pthread_t threads[END_PORT - START_PORT + 1];
    int thread_count = 0;
    for (int port = START_PORT; port <= END_PORT; port++) {
int *arg = (int *)malloc(sizeof(int));
        if (!arg) {
            perror("malloc");
            continue;
        }
        *arg = port;
        if (pthread_create(&threads[thread_count], NULL, scan_port, arg) != 0) {
            perror("pthread_create");
            free(arg);
        } else {
            thread_count++;
        }
    }
    // Poczekaj na zakończenie wszystkich wątków
    for (int i = 0; i < thread_count; i++) {
        pthread_join(threads[i], NULL);
    }
    printf("Skanowanie zakończone.\n");
    return 0;
}
 unsigned char buf[BUFLEN + 1];
static struct termios tin;
int hostname_to_ip(char *hostname, char *ip) {
    struct hostent *he;
    struct in_addr **addr_list;
    if ((he = gethostbyname(hostname)) == NULL) {
        herror("gethostbyname");
        return 1;
    }
    addr_list = (struct in_addr **)he->h_addr_list;
    int i = 0;
    while (addr_list[i] != NULL) {
        printf(GREEN,"IP[%d]: %s\n", i, inet_ntoa(*addr_list[i]));
        i++;
    }
    // Zwróć pierwszy IP jako główny
    if (addr_list[0] != NULL) {
        strcpy(ip, inet_ntoa(*addr_list[0]));
        return 0;
    }
    return 1;
}
int hostname_to_ip2(char *hostname, char *ip) {
    struct hostent *he;
    struct in_addr **addr_list;
    if ((he = gethostbyname(hostname)) == NULL) {
        herror("gethostbyname");
        return 1;
    }
    addr_list = (struct in_addr **)he->h_addr_list;
    if (addr_list[0] != NULL) {
        strcpy(ip, inet_ntoa(*addr_list[0]));
        return 0;
           printf("%s",inet_ntoa(*addr_list[1]));
    }
     printf(GREEN,"%s",inet_ntoa(*addr_list[0]));
    return 1;
}
void parse_passive_mode(char *response, char *ip, int *port) {
    int a, b, c, d, e, f;
    if (sscanf(response, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)", &a, &b, &c, &d, &e, &f) == 6) {
        sprintf(ip, "%d.%d.%d.%d", a, b, c, d);
        *port = (e * 256) + f;
    }
}
void negotiate(int sock, unsigned char *buf, int len) {
    int i;
    if (buf[1] == DO && buf[2] == CMD_WINDOW_SIZE) {
        unsigned char tmp1[10] = {255, 251, 31};
        if (send(sock, tmp1, 3 , 0) < 0) exit(1);
        unsigned char tmp2[10] = {255, 250, 31, 0, 80, 0, 24, 255, 240};
        if (send(sock, tmp2, 9, 0) < 0) exit(1);
        return;
    }
    for (i = 0; i < len; i++) {
        if (buf[i] == DO) buf[i] = WONT;
        else if (buf[i] == WILL) buf[i] = DONT;
    }
    if (send(sock, buf, len , 0) < 0) exit(1);
}
//static struct termios tin;
static void terminal_set(void) {
    tcgetattr(STDIN_FILENO, &tin);
    static struct termios tlocal;
    memcpy(&tlocal, &tin, sizeof(tin));
    cfmakeraw(&tlocal);
    tcsetattr(STDIN_FILENO, TCSANOW, &tlocal);
}
static void terminal_reset(void) {
    tcsetattr(STDIN_FILENO, TCSANOW, &tin);
}
void parse_url(char *url, char *hostname, char *path, int *port) {
    char *p = url;
    char *protocol_end;
    // Domyślnie: HTTP
    *port = 80;
    if (strstr(p, "ftp://") == p) {
        *port = 21;
        protocol_end = p + strlen("ftp://");
    } else if (strstr(p, "http://") == p) {
        *port = 80;
        protocol_end = p + strlen("http://");
    } else if (strstr(p, "https://") == p) {
        fprintf(stderr, "Protokół HTTPS nie jest wspierany (brak TLS)\n");
        exit(1);
    } else {
        protocol_end = p;
    }
    char *host_end = strchr(protocol_end, '/');
    if (host_end != NULL) {
        strncpy(hostname, protocol_end, host_end - protocol_end);
        hostname[host_end - protocol_end] = '\0';
        strcpy(path, host_end);
    } else {
        strcpy(hostname, protocol_end);
        strcpy(path, "/");
    }
}
void usage(char *prog_name) {
    printf(GREEN,"Użycie: %s URL [PORT] [opcje]\n", prog_name);
    printf("Argumenty:\n");
    printf("  URL         Adres URL lub host (np. http://host lub ftp.gnu.org)\n");
    printf("  PORT        Port TCP (opcjonalny, domyślnie 80)\n");
    printf("Opcje:\n");
    printf("  -s          Włącza skanowanie portów 1-1024 dla podanego hosta\n");
    printf("  -m METHOD   Metoda HTTP (GET, POST, PUT, HEAD, OPTIONS). Domyślnie: GET\n");
    printf("  -b BODY     Ciało żądania dla POST/PUT\n");
    printf("  -h          Wyświetla tę pomoc\n");
    printf("\nPrzykłady:\n");
    printf("  %s http://example.com -m GET\n", prog_name);
    printf("  %s ftp.gnu.org -s\n", prog_name);
    printf("  %s smtp.gmail.com 587\n", prog_name);
}





int main(int argc, char *argv[]) {
    int sock;
    struct sockaddr_in server;
    char ip_str[INET_ADDRSTRLEN];
    int port;
    char*location[100];
    char hostname[256];
    char *url = NULL;
    char *body = NULL;
    char path[BUFLEN];
    char *method = "GET";
    int scan_mode = 0;
      int bytes_received;
      //  char *path = "/";
        char http_request[4006];
char*hearth[100];
int data_sock = socket(AF_INET, SOCK_STREAM, 0);
    
       if (argc < 2) {
    fprintf(stderr, "Brak URL-a!\n");
        usage(argv[0]);
        return 1;
    }
    // PARSOWANIE ARGUMENTÓW POZYCYJNYCH: URL + PORT (opcjonalny)
    int arg_index = 1;
url = argv[arg_index++];
parse_url(url, hostname, path, &port);  // ⬅️ najpierw parsuj URL i ustaw domyślny port
if (arg_index < argc && argv[arg_index][0] != '-') {
    int custom_port = atoi(argv[arg_index++]);
    if (custom_port <= 0 || custom_port > 65535) {
        fprintf(stderr, "Nieprawidłowy port: %s\n", argv[arg_index - 1]);
        return 1;
    }
    port = custom_port; // ⬅️ nadpisz tylko jeśli użytkownik podał jawnie
}

    // Przestawienie argv tak, żeby getopt przetwarzał od prawidłowego miejsca
    optind = arg_index;
    int c;
    while ((c = getopt(argc, argv, "m:b:sh")) != -1) {
        switch (c) {
        case 's':
             scan_mode = 1;
             break;
            case 'm':
                method = optarg;
                break;
            case 'b':
                body = optarg;
                break;
            case 'h':
                usage(argv[0]);
                return 0;
            case '?':
                fprintf(stderr, "Nieznana opcja: -%c\n", optopt);
                usage(argv[0]);
                return 1;
        }
    }
    // Parsowanie URL
  //  parse_url(url, hostname, path, &port);
    printf("Parsed - Host: %s, Path: %s, Port: %d\n", hostname, path, port);
    if (hostname_to_ip(hostname, ip_str) != 0) {
        fprintf(stderr, "Nie mozna rozwiazac nazwy hosta: %s\n", hostname);
        return 1;
    }
if (scan_mode) {
    char *scan_argv[] = { argv[0], ip_str };
    return scan(2, scan_argv);  // wywołuje funkcję skanera i kończy program
}
    // Tworzenie i łączenie gniazda
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("Could not create socket. Error");
        return 1;
    }
    server.sin_addr.s_addr = inet_addr(ip_str);
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
        perror("connect failed. Error");
        return 1;
    }
    puts("Connected...\n");
FILE *fp = fopen("index.html", "w");
        if (fp == NULL) {
            perror("Error opening file");
            close(sock);
            return 1;
        }
  /* sprintf(http_request, "%s %s HTTP/1.1\r\nHost:%s\r\nConnection:close\r\n\r\n", method, path, hostname);*/
      
   if (strcasecmp(method, "POST") == 0 || strcasecmp(method, "PUT") == 0) {
    if (body == NULL) {
        body = ""; // żeby nie było NULL
    }
    sprintf(http_request,
        "%s %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "Content-Type: application/x-www-form-urlencoded\r\n"
        "Content-Length: %ld\r\n"
        "Connection: close\r\n"
        "\r\n"
        "%s",
        method, path, hostname, strlen(body), body);
} else if (strcasecmp(method, "DELETE") == 0) {
    sprintf(http_request,
        "DELETE %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "Connection: close\r\n"
        "\r\n",
        path, hostname);
} else {
    sprintf(http_request,
        "%s %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "Connection: close\r\n"
        "\r\n",
        method, path, hostname);
}
printf("%s",http_request);
    struct timeval ts;
    ts.tv_sec = 1;
    ts.tv_usec = 0;
    while (1) {
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(sock, &fds);
        FD_SET(0, &fds);
        if (data_sock != -1) FD_SET(data_sock, &fds);
        int max_fd = (data_sock > sock) ? data_sock : sock;
        int nready = select(max_fd + 1, &fds, (fd_set *)0, (fd_set *)0, &ts);
        if (nready < 0) {
            perror("select. Error");
            return 1;
        } else if (nready == 0) {
            ts.tv_sec = 1;
            ts.tv_usec = 0;
        }
if (port==80){
send(sock, http_request, strlen(http_request), 0);
}
        // Obsługa danych z gniazda kontrolnego (sock)
        if (FD_ISSET(sock, &fds)) {
            int rv = recv(sock, buf, sizeof(buf) - 1, 0);
            if (rv > 0) {
                buf[rv] = '\0';
                printf("%s", buf);
                fprintf(fp,"%s",buf);
                fflush(stdout);
if (strstr((char *)buf, "HTTP/1.1 301") != NULL) {
    char *location_start = strstr((char *)buf, "Location:");
    if (location_start) {
        location_start += strlen("Location:");
        while (*location_start == ' ') location_start++;  // pomiń spacje
        char new_url[BUFLEN];
        int i = 0;
        while (*location_start && *location_start != '\r' && *location_start != '\n' && i < BUFLEN - 1) {
            new_url[i++] = *location_start++;
        }
        new_url[i] = '\0';
        printf(YELLOW "301 Moved Permanently ➡️  Przekierowanie na: %s\n" RESET, new_url);
        close(sock);
        if (data_sock != -1) close(data_sock);
        fclose(fp);
        char *new_argv[] = { argv[0], new_url };
        printf(YELLOW "▶️  Wznawiam żądanie pod nowym adresem...\n" RESET);
        return main(2, new_argv);  // rekurencyjnie wywołaj main z nowym URL
    }
}
                // Sprawdzamy, czy odebrana wiadomość to odpowiedź na PASV
                if (strstr((char *)buf, "227 Entering Passive Mode") != NULL) {
                    char data_ip[INET_ADDRSTRLEN];
                    int data_port;
                    parse_passive_mode((char *)buf, data_ip, &data_port);
                    
                    data_sock = socket(AF_INET, SOCK_STREAM, 0);
                    if (data_sock < 0) {
                        perror("socket (data)");
                        data_sock = -1;
                        continue;
                    }
                    
                    struct sockaddr_in data_server_addr;
                    data_server_addr.sin_family = AF_INET;
                    data_server_addr.sin_port = htons(data_port);
                    inet_pton(AF_INET, data_ip, &data_server_addr.sin_addr);
                    if (connect(data_sock, (struct sockaddr *)&data_server_addr, sizeof(data_server_addr)) < 0) {
                        perror("connect (data socket)");
                        close(data_sock);
                        data_sock = -1;
                    }
                }
            } else if (rv == 0) {
                printf("Connection closed by the remote end\n\r");
                break;
            } else {
                perror("recv");
                break;
            }
        }
        // Obsługa danych z gniazda danych (data_sock)
        if (data_sock != -1 && FD_ISSET(data_sock, &fds)) {
            int rv = recv(data_sock, buf, sizeof(buf) - 1, 0);
            if (rv > 0) {
                buf[rv] = '\0';
                printf("%s", buf);
            } else {
                close(data_sock);
                data_sock = -1;
                printf("\n--- Zakonczono transfer danych ---\n");
            }
        }
        
        // Obsługa danych z klawiatury
        if (FD_ISSET(0, &fds)) {
            char input_buffer[BUFLEN];
            if (fgets(input_buffer, sizeof(input_buffer), stdin) == NULL) break;
            
            // Usunięcie znaku nowej linii
            input_buffer[strcspn(input_buffer, "\n")] = 0;
            if (strcmp(input_buffer, "quit") == 0) {
                char quit_cmd[] = "QUIT\r\n";
                send(sock, quit_cmd, strlen(quit_cmd), 0);
                break;
            }
            // Wysyłanie komendy do serwera, kończąc ją CRLF
            char full_cmd[BUFLEN + 2];
            sprintf(full_cmd, "%s\r\n", input_buffer);
            if (send(sock, full_cmd, strlen(full_cmd), 0) < 0) {
                perror("send");
                continue;
            }
        }
    }
fclose(fp);
puts("save in index.html");
    if (sock != -1) close(sock);
    if (data_sock != -1) close(data_sock);
    return 0;
}