Ir para o conteúdo
Cr4zYPT

obter IP externo

Mensagens Recomendadas

Cr4zYPT

Ora como nome do topico indica, preciso de obter o IP externo do computador em que estou a executar o programa. Ja consegui obter o IP interno neste caso ate é 192.168.1.75 mas nao consigo obter o externo.

Pensei em pedir o index.php do site www.omeuip.com e analisar o codigo html, mas de certeza que existe outra formas mas eficazes

Cumpz,

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

2) cria um socket UDP; liga-te algures (externo), usa getsockname()

Por exemplo, para sistemas POSIX (IPv6 nao testado; se puderes testar, testa e diz qualquer coisa)

#define _POSIX_C_SOURCE 200809L
#include <arpa/inet.h>  /* inet_ntop() */
#include <netdb.h>      /* [get,free]addrinfo() */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>     /* memset() */
#include <sys/socket.h> /* [get,free]addrinfo(), socket(), connect(), getsockname() */
#include <unistd.h>     /* close() */

#define MYSERVER "sapo.pt" /* IPv6 "2001:8a0:2104:ff:213:13:146:140" */
#define MYPORT "80"

int main(void) {
  int status;
  int sockfd;
  struct addrinfo inf;
  struct addrinfo *res, *cur;
  struct sockaddr sa;
  socklen_t ss;
  size_t portsize;
  char buf[iNET6_ADDRSTRLEN];
  const char *result;

  /* initialize */
  memset(&inf, 0, sizeof inf);
  inf.ai_family = AF_UNSPEC;    /* IPv4 or IPv6 */
  inf.ai_socktype = SOCK_DGRAM; /* UDP */
  status = getaddrinfo(MYSERVER, MYPORT, &inf, &res);
  if (status != 0) {
    perror("getaddrinfo");
    exit(EXIT_FAILURE);
  }

  /* find an address and connect to it */
  cur = res;
  while (cur) {
    sockfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
    if (sockfd != -1) {
      if (connect(sockfd, cur->ai_addr, cur->ai_addrlen) == 0) {
        break;
      }
      perror("connect"); /* print error but continue */
      close(sockfd);
    } else {
      perror("socket"); /* print error but continue */
    }
    cur = cur->ai_next;
  }
  freeaddrinfo(res);
  if (cur == NULL) {
    fprintf(stderr, "Error: unable to connect\n");
    exit(EXIT_FAILURE);
  }

  /* get address in network form */
  ss = sizeof sa;
  if (getsockname(sockfd, &sa, &ss) == -1) {
    perror("getsockname");
    exit(EXIT_FAILURE);
  }
  close(sockfd);

  /* convert and print the address */
  portsize = sizeof (in_port_t);
  result = inet_ntop(sa.sa_family, sa.sa_data + portsize, buf, sizeof buf);
  if (result == NULL) {
    perror("inet_ntop");
    exit(EXIT_FAILURE);
  }
  printf("family: ");
  switch (sa.sa_family) {
    default:       printf("(UNKNOWN)"); break;
    case AF_INET:  printf("IPv4");      break;
    case AF_INET6: printf("IPv6");      break;
  }
  printf("; address: %s\n", buf);

  return 0;
}


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cr4zYPT

Depois de fazer umas alteraçoes ao teu codigo e adaptar para windows eu obtenho o ip do do destino neste caso sapo. O que queria era o meu ip

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Estou com gripe em casa. Nao tenho Windows para experimentar. Talvez amanha va trabalhar e possa adaptar o codigo.

Por acaso nao mudaste o getsockname() para getpeername()?


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cr4zYPT

Esta versao e diferente da tua e da me o ip do destino

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>

#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")


#define DEFAULT_BUFLEN 512
#define PORT "80"
#define SERVER "www.sapo.pt"


int main()

{

            WSADATA wsaData;



            struct addrinfo hints, *res, *p;

            int status;

   
            char ipstr[iNET6_ADDRSTRLEN];

            char ipstr2[iNET6_ADDRSTRLEN];

            // Initialization

            if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0)

            {

                        printf("Erro no wsa. Id: %ld\n", WSAGetLastError());

                        return 1;

            }

            memset(&hints, 0, sizeof hints);

            hints.ai_family = AF_UNSPEC; 
            hints.ai_socktype = SOCK_STREAM;



            if ((status = getaddrinfo(SERVER, NULL, &hints, &res)) != 0)

            {

                        printf("getaddr falhou. ID: %ld\n", WSAGetLastError());

                        WSACleanup();

                        return 1;

            }


            for(p = res;p != NULL; p = p->ai_next)

            {

                        void *addr;

                        char *ipver;

                        if (p->ai_family == AF_INET)

                        {

                                    // IPv4

                                    struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;

                                    addr = &(ipv4->sin_addr);

                                    ipver = "IPv4";

                        }

                        else

                        {

                                    // IPv6

                                    struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;

                                    addr = &(ipv6->sin6_addr);

                                    ipver = "IPv6";

                        }

                        inet_ntop(p->ai_family, addr, (PSTR)ipstr, sizeof(ipstr));

                        printf(" %s: %s\n", ipver, ipstr);


            }

            freeaddrinfo(res);
            WSACleanup();
		system("Pause");
            return 0;

}

Esta versao so adaptei para windows mas nao funciona

o ip da sempre 240.240.240.240 que nao meu ip

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>


// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")


#define DEFAULT_BUFLEN 512
#define MYPORT "80"
#define MYSERVER "www.google.pt"

int main(void)
{
  int status=0;
  int sockfd;
  struct addrinfo inf;
  struct addrinfo *res, *cur;
  struct sockaddr sa;
  socklen_t ss;
  WSADATA wsaData;
  size_t portsize;
  char buf[iNET6_ADDRSTRLEN];
  const char *result;


  // Initialize Winsock
    status = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (status != 0) {
        printf("WSAStartup failed with error: %d\n", status);
        return 1;
    }

  /* initialize */
  memset(&inf, 0, sizeof inf);
  inf.ai_family = AF_UNSPEC;    /* IPv4 or IPv6 */
  inf.ai_socktype = SOCK_DGRAM; /* UDP */
  status = getaddrinfo(MYSERVER, MYPORT, &inf, &res);
  if (status != 0)
  {
    perror("getaddrinfo");
system("pause");
    exit(EXIT_FAILURE);
  }

  /* find an address and connect to it */
  cur = res;
  while (cur) 
  {
    sockfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
    if (sockfd != -1) 
{
      if (connect(sockfd, cur->ai_addr, cur->ai_addrlen) == 0) 
  {
        break;
      }
      perror("connect"); /* print error but continue */
      closesocket(sockfd);
    } else {
      perror("socket"); /* print error but continue */
    }
    cur = cur->ai_next;
  }
  freeaddrinfo(res);
  if (cur == NULL) {
    fprintf(stderr, "Error: unable to connect\n");
system("pause");
    exit(EXIT_FAILURE);
  }

  /* get address in network form */
  ss = sizeof sa;
  if (getsockname(sockfd, &sa, &ss) != 0) {
    perror("getsockname");
system("pause");
    exit(EXIT_FAILURE);
  }
  closesocket(sockfd);

  /* convert and print the address */
  portsize = 16;
  result = InetNtop(sa.sa_family, sa.sa_data + portsize, buf, sizeof buf);
  if (result == NULL) {
    perror("inet_ntop");
system("pause");
    exit(EXIT_FAILURE);
  }
  printf("family: ");
  switch (sa.sa_family) {
    default:       printf("(UNKNOWN)"); break;
    case AF_INET:  printf("IPv4");      break;
    case AF_INET6: printf("IPv6");      break;
  }
  printf("; address: %s\n", buf);

  system("pause");
  return 0;
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Nao sei qual a versão que vis-te mas a tua alterada é a segunda. Troquei as quando fiz o post

Pois ... reparei agora mesmo que tinhas trocado as versoes. Apaguei a minha resposta e vou olhar para a versao que usaste. Se nao achar nada so a olhar para ela, talvez amanha ...


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg
  /* convert and print the address */
  portsize = 16;

Porque 16? ??? O original era sizeof (in_port_t). Ainda se fosse 2 :)

Este portsize serve para usar o struct sockaddr como se fosse um struct sockaddr_in sem fazer casts.

As definicoes dessas estruturas sao

struct sockaddr {
    sa_family_t  sa_family; //  Address family. 
    char         sa_data[]; //  Socket address (variable-length data).
};

struct sockaddr_in {
    sa_family_t     sin_family; //   AF_INET. 
    in_port_t       sin_port;   //   Port number. 
    struct in_addr  sin_addr;   //   IP address. 
};

Sobrepondo as duas estruturas (com casts), assumindo que in_port_t usa 2 bytes, temos sa_family igual a sin_family; sa_data[0] e sa_data[1] igual a sin_port; sa_data[2] e seguintes igual a sin_addr.

É este sa_data[2] e seguintes (sin_addr, sa_data + 2) que é preciso passar para inet_ntop().


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Isso é porque estas atras de NAT.

Isoladamente, a tua maquina nao tem maneira de saber o IP que o router te assignou.

1) tens que pedir a um site externo (o icanhazip, por exemplo)

2) ou, se podes comunicar com o router, pedir-lhe a informacao com SNMP (goolga snmpwalk ou netsnmp)

Deve ser possivel obter os sources de programas que usam SNMP e copiar (e alterar) para uso proprio dentro dum programa maior ...


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.