게이트웨이 IP알아내는 방법?

young93의 이미지

안녕하세요.

프로그램에서 게이트웨이 IP를 알아내는 방법을 찾고 있습니다.
자기 IP와 넷마스크는 ioctl()를 이용해서 알아낼 수 있는데,
게이트웨이 IP는 어떻게 알아내는지....

ioctl()로는 안되는 것 같고,
/proc/net/route 파일을 보니 라우팅정보가 있더군요.
이걸 읽어 게이트웨이를 추출해야 하나.....

조언 부탁드립니다.

purewell의 이미지

자신의 IP와 NM값 어떻게 알아내셨나요~?

공유 좀~ 해주세요.

_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz

young93의 이미지

purewell wrote:
자신의 IP와 NM값 어떻게 알아내셨나요~?

공유 좀~ 해주세요.

보통은 gethostbyname을 이용하라고 나온 자료가 많은데,
그것 보다는 ioctl()을 이용하는 것이 좋은 것 같습니다.
소스 올립니다.

int get_ipconfig(uint *ipaddr, uint *netmask)
{
    int i, sock, ret;
    struct ifreq ifr;

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0) {
        printf("socket() error\n");
        return -1;
    }

    strcpy(ifr.ifr_name, "eth0");

    // Get IP Adress
    ret = ioctl(sock, SIOCGIFADDR, &ifr);
    if (ret < 0) {
        printf("get_ipconfig(), ioctl() error\n");
        close(sock);
        return -1;
    }
    *ipaddr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;

    // Get Netmask
    ret = ioctl(sock, SIOCGIFNETMASK, &ifr);
    if (ret < 0) {
        printf("get_ipconfig(), ioctl() error\n");
        close(sock);
        return -1;
    }
    *netmask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;

    close(sock);
}

/usr/include/sockios.h 파일을 보시면
ioctl() 옵션이 모두 나와있습니다.

pynoos의 이미지

int get_ipconfig(uint *ipaddr, uint *netmask)
{
    int i, sock, ret;
    struct ifreq ifr;

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0) {
        printf("socket() error\n");
        return -1;
    }

    strcpy(ifr.ifr_name, "eth0");

    // Get IP Adress
    ret = ioctl(sock, SIOCGIFADDR, &ifr);
    if (ret < 0) {
        printf("get_ipconfig(), ioctl() error\n");
        close(sock);
        return -1;
    }
    *ipaddr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;

    // Get Netmask
    ret = ioctl(sock, SIOCGIFNETMASK, &ifr);
    if (ret < 0) {
        printf("get_ipconfig(), ioctl() error\n");
        close(sock);
        return -1;
    }
    *netmask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;

    close(sock);
}

비슷한 코드인데, 이것은 network interface 카드를 뒤져가며, 모두 돌려주는 것입니다. HP에서는 잘 안되는 경향이 있어서 살펴보니, Address family가 internet이 아닌것도
나오더군요.. AF_INET 인것만 추출하도록 하였습니다.

제가 테스트한것은 gcc 로 하였고

linux, solaris 2.5.1, aix 4.3, hpux10.x 입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stropts.h>

#if defined(sun)
#include <sys/sockio.h>
#endif

#include <net/if.h>
#if defined(linux)
#include <linux/sockios.h>
#endif

#define BUFFERSIZE 1024
const char * localip = "0.0.0.0";

const char * myip()
{
        const int MAX_NIC = 10;
        struct ifconf ifc;
        struct ifreq ifr[MAX_NIC];

        int s;
        int nNumIFs;
        int i;
        int count;
        int max=2;
        static char ip[BUFFERSIZE];
        int cmd = SIOCGIFCONF;

        max++;

        ifc.ifc_len = sizeof ifr;
        ifc.ifc_ifcu.ifcu_req = ifr;

        if( (s=socket(AF_INET,SOCK_STREAM,0)) < 0)
        {
                perror("socket"); 
                exit(1);
        }

#if defined(_AIX)
        cmd = CSIOCGIFCONF;
#endif

        if( ioctl(s, cmd, &ifc) < 0)
        {
                perror("ioctl");
                exit(1);
        }
        close(s); 

        nNumIFs = ifc.ifc_len / sizeof ( struct ifreq );
        count = 0;
        strcpy( ip, localip );
        for( i=0; i<nNumIFs; i++ )
        {
                struct in_addr addr;
                if( ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_addr.sa_family != AF_INET)
                {
                        continue;
                }

                addr = ((struct sockaddr_in *) & ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_addr)->sin_addr;
                if( addr.s_addr == htonl( 0x7f000001 ) )
                {
                        continue;
                }
                strcpy( ip, inet_ntoa( addr ) );
                printf( "IP: %s\n", ip );
        }
        return ip;
}

int main()
{
        printf("One of my IP is %s\n", myip() );
        return 0;
}

--

2년만에 resource leak 부분을 수정하여 올립니다.
http://bbs.kldp.org/viewtopic.php?t=50279
여기를 참고하세요 :)

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.