시스템관리자의 쉼터 커피닉스 커피향이 나는 *NIX
커피닉스
시스템/네트웍/보안을 다루는 곳
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 

가입없이 누구나 글을 쓸 수 있습니다. 공지사항에 대한 댓글까지도..




BBS >> 설치, 운영 Q&A | 네트웍, 보안 Q&A | 일반 Q&A || 정보마당 | AWS || 자유게시판 | 구인구직 || 공지사항 | 의견제시
외부로 통신가능한 IP알아내기.

 
글 쓰기   답변 달기    커피닉스, 시스템 엔지니어의 쉼터 게시판 인덱스 -> 나도 한마디
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
minzkn



가입: 2003년 9월 16일
올린 글: 1
위치: 어?

올리기올려짐: 2003.9.16 화, 5:42 am    주제: 외부로 통신가능한 IP알아내기. 인용과 함께 답변

한자 적어봅니다.

음 이것이 무엇인고 설명하자면
우리 보통 Network card가 1개를 쓰지요?
그런데 안그러신분도 많을겁니다.
여러개의 IP사용하실때
어떤게 진짜로 외부로 나가는 IP인지 검출해볼 필요가 있죠?
그런때 없었나요?
이건 그때 외부로 나갈수 있는 IP를 검출하는겁니다.
물론 이것을 100% 신뢰할수는 없고
그렇게 신뢰를 하기 위해서는 ICMP가 구현되어야 합니다.
또한 Gateway가 한개가 아닐수도 있다는 점도 고려사항이 되고요.
eth0:0 eth0:1 등의 경우도 생각해봐야 하며
ifr로는 검출이 안되는 경우에 대해서는 /proc으로 보정할 필요도 있고요.

하지만 간략하게나마 이렇게 한번 만들어 봤습니다.
본래는 보강해야할곳이 한두군데가 아니라는 점은
알지만 그냥 원리구현이니까 도움이 될까해서
만들어봅니다.

코드:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>

int main(int s_Argc, char **s_Argv);

int main(int s_Argc, char **s_Argv)
{
 const char *c_Proc_Route = "/proc/net/route";
 int s_SocketHandle, s_Handle, s_ReadBytes, s_RequestCount = 10;
 struct ifconf s_ifconfig;
 struct ifreq *s_ifrequest;
 struct sockaddr_in *s_SockAddr_In;
 char *s_MyDevice;
 char *s_MyIP, *s_MyBroadcastIP, *s_MyNetmaskIP, *s_RouteIP, *s_RouteName;
 char s_Buffer[ 32 << 10 ];

 s_RouteIP = s_RouteName = (char *)0;
 s_Handle = open(c_Proc_Route, O_RDONLY);
 if(s_Handle >= 0)
 {
  s_ReadBytes = read(s_Handle, &s_Buffer[0], sizeof(s_Buffer) - 1);
  close(s_Handle);
  if(s_ReadBytes > 0)
  {
   unsigned long s_Destination, s_Gateway, s_Flags, s_RefCnt, s_Use, s_Metric, s_Mask;
   char *s_TraceBuffer;
   int s_Index;
   s_Buffer[ s_ReadBytes ] = '\0';
   s_Index = 0;
   s_TraceBuffer = (char *)(&s_Buffer[s_Index]);
   do
   {
    s_RouteName = (char *)0;
    if(s_Buffer[s_Index] == '\0' || s_Buffer[s_Index] == '\n')
    {
     s_Buffer[s_Index] = '\0';
     s_RouteName = s_TraceBuffer;
     while((*s_TraceBuffer) != ' ' && (*s_TraceBuffer) != '\t' && (*s_TraceBuffer) != '\0')s_TraceBuffer++;
     *(s_TraceBuffer++) = '\0';
     while(((*s_TraceBuffer) == ' ' || (*s_TraceBuffer) == '\t') && (*s_TraceBuffer) != '\0')s_TraceBuffer++;
     if(sscanf(s_TraceBuffer, "%lx%lx%lX%lu%lu%lu%lx", &s_Destination, &s_Gateway, &s_Flags, &s_RefCnt, &s_Use, &s_Metric, &s_Mask) == 7)   
     {
      if(s_Destination == 0lu)
      {
       /* fprintf(stdout, "Default route [%s:%s]\n", s_RouteName, s_TraceBuffer); */
       break;
      }
      /* else fprintf(stdout, "Normal route [%s:%s]\n", s_RouteName, s_TraceBuffer); */
     }
     /* else fprintf(stdout, "Non line [%s:%s]\n", s_RouteName, s_TraceBuffer);  */
     s_Index++;
     s_TraceBuffer = (char *)(&s_Buffer[s_Index]);
    }
    else if(s_Buffer[s_Index] == '\r')s_Buffer[s_Index++] = ' ';
    else s_Index++;
   }while(s_Index < s_ReadBytes);
  }
 }
 else fprintf(stderr, "Can not open \"%s\"\n", c_Proc_Route);

 if(s_RouteName == (char *)0)
 {
  return(-1);
 }
 
 s_SocketHandle = socket(AF_INET, SOCK_DGRAM, 0);
 if(s_SocketHandle >= 0)
 {
  memset((void *)&s_ifconfig, 0, sizeof(struct ifconf));
  do
  {
   if(s_ifconfig.ifc_buf)free(s_ifconfig.ifc_buf);
   s_ifconfig.ifc_len = sizeof(struct ifreq) * s_RequestCount;
   s_ifconfig.ifc_buf = malloc(s_ifconfig.ifc_len);
   if(s_ifconfig.ifc_buf)
   {
    if(ioctl(s_SocketHandle, SIOCGIFCONF, &s_ifconfig) == 0)
    {
     if(s_ifconfig.ifc_len < (sizeof(struct ifreq) * s_RequestCount))
     {
      s_ifrequest = s_ifconfig.ifc_req;
      if(s_ifrequest)
      {
       for(s_RequestCount = 0;s_RequestCount < s_ifconfig.ifc_len;s_RequestCount += sizeof(struct ifreq), s_ifrequest++)
       {
   s_MyDevice = strdup(s_ifrequest->ifr_name);
   
   ioctl(s_SocketHandle, SIOCGIFADDR, s_ifrequest);       
   s_SockAddr_In       = (struct sockaddr_in *)(&s_ifrequest->ifr_addr);
        s_MyIP              = strdup(inet_ntoa(s_SockAddr_In->sin_addr));   
   ioctl(s_SocketHandle, SIOCGIFBRDADDR, s_ifrequest);       
   s_SockAddr_In       = (struct sockaddr_in *)&s_ifrequest->ifr_broadaddr;
        s_MyBroadcastIP     = strdup(inet_ntoa(s_SockAddr_In->sin_addr));   
   ioctl(s_SocketHandle, SIOCGIFNETMASK, s_ifrequest);       
   s_SockAddr_In       = (struct sockaddr_in *)&s_ifrequest->ifr_netmask;
        s_MyNetmaskIP       = strdup(inet_ntoa(s_SockAddr_In->sin_addr));   
   
   if(strcmp(s_MyDevice, "lo") != 0 && strcmp(s_RouteName, s_MyDevice) == 0)fprintf(stdout, "%s %s\n", s_MyDevice, s_MyIP);
   
   if(s_MyDevice     )free(s_MyDevice);
   if(s_MyIP         )free(s_MyIP);
   if(s_MyBroadcastIP)free(s_MyBroadcastIP);
   if(s_MyNetmaskIP  )free(s_MyNetmaskIP);
       }
      }
      break;
     }
     else s_RequestCount += 10;
    }
    else break;
   }
   else break;
  }while(1); 
  if(s_ifconfig.ifc_buf)free(s_ifconfig.ifc_buf);
  close(s_SocketHandle);    
 }
 else fprintf(stderr, "Can not open socket !!!\n");
 return(0);
}

/* End of source */

_________________
<mailto:minzkn@infoeq.com>
<home: http://minzkn.wowdns.com:2744>
위로
사용자 정보 보기 비밀 메시지 보내기 글 올린이의 웹사이트 방문 MSN 메신저
이전 글 표시:   
글 쓰기   답변 달기    커피닉스, 시스템 엔지니어의 쉼터 게시판 인덱스 -> 나도 한마디 시간대: GMT + 9 시간(한국)
페이지 1 중 1

 
건너뛰기:  
새로운 주제를 올릴 수 없습니다
답글을 올릴 수 없습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다


Powered by phpBB © 2001, 2005 phpBB Group