앞서 사용자 인증 부분에 대하여 제작을 하였습니다.

풀 소스 공개는 차후 정리가 되는 대로 올리도록 하겠습니다.

여기서는 리눅스 보드에 web을 이용한 네트워크 설정 기능을 만들어 보도록 하겠습니다.

우리가 실생활에서 많이 사용되는 공유기를 보면 대부분 192.168.0.1 이런식으로 접속하여 사용자 인증 을 한 후 공유기 설정을 건드릴 수 있었습니다.

dhcp 기능을 활성화 시킨다던지 고정아이피 세팅을 한다던지 vlan 을 설정한다던지 이런식으로 말이지요.

여기서 제가 구현하고자 하는 기능은 간단히 cgi webserver를 이용한 아이피 및 서브넷 설정 게이트웨이 설정 등의 부분 입니다. 제가 시간이 많지 않은 관계로 짬이 날때마다 글을 이어 올리도록 하겠습니다.

일단 제가 생각하는 webserver를 이용한 아이피 설정의 기능 구현은 이런 형식으로 할 생각합니다.

 

사용자로부터 입력을 받을 폼을 만듭니다. ip 나 sebnet gateway 등의 정보를 입력 받을 수 있으며 리눅스 보드로 부터 현재 설정되어 있는 네트워크 정보를 받아 폼에 표시를 해 줍니다.

사용자로부터 새로운 아이피 및 여타 변경된 네트워크 정보를 받아 submit 버튼을 통하여 cgi 로 넘어온 정보를 파싱하여 제가 만든 배열에 정보를 담아 놓습니다.

그 후 현재 변경하고자 하는 부분의 이더넷 링크를 다운 시킨 후 새로운 네트워크 정보를 입력하여 다시 업링크 시켜 줍니다. 다시 사용자에게 변경된 정보를 폼으로 하여금 보여질 수 있도록 정보를 받아와 표시해줍니다.

==================

2009년 02월 10일

==================

여기까지 제가 구현하고자 하는 부분에 대한 알고리즘을 생각해보았습니다.  다음으로 하나하나 구현을 해보도록 하겠습니다.

리눅스상에서 아이피 확인 및 설정을 하기 위해서는 ifconfig 라는 명령어를 자주 접하게 될 것입니다.

ifconfig 를 통하여 각 이더넷 모듈별로 설정된 아이피 확인 및 서브넷마스크 확인 전송된 패킷량 등 여러 정보를 접하실 수 있습니다.

일단 구현하고자 하는 네트워크 설정 페이지를 만듭니다. html 로 만들게 된다면 초기 현재 설정되어 있는 정보를 받아오지 못하므로 cgi 를 이용하여 c로 만들어야 합니다.

 

networkset.c 라는 파일을 vi 에디터로 생성하여 기본 인클루드 파일 선언 후 cgi 페이지로 인식 할 수 있도록 해줍니다. 다음 c에서 바로 정보를 보기엔 힘든 부분이 있어 시스템함수를 이용하여 따로 작성한 쉘스크립을 불러왔습니다.

쉘스크립의 내용은 다음과 같습니다.

 

ifconfig eth0 > network.info

chmod 4777 network.info

sleep 1

 

쉘스크립이 시작되면 ifconfig eth0 의 명령에 대한 출력을 network.info 라는 파일로 저장합니다.

그 후 network.info 에 4777의 권한을 줍니다.( 유저권한에서 실행 가능할 정도면 될 듯 합니다만 임베디드 시스템에 들어갈 부분이기에 보안에 대한 내용은 잠시 접어두겠습니다 ;;;)

다음 sleep 명령을 이용하여 1초간의 딜레이를 주었습니다.

 

이런식으로 네트워크 정보를 받아오며 생성된 network.info 파일을 c에서 파싱합니다.

akw 를 이용하여 shell 에서 파싱하는 방법이 쉽습니다만.. 제작한 하드웨어의 커널에 awk 를 포함하지 않아  그냥 진행하며 다른 방법을 사용한 것 입니다 ㅡㅡ;;;

c에서 파일을 파싱하여 ip 및 subnetmask 정보를 얻은 후 gateway 정보를 얻어야 합니다. 여러 방법이 있겠지만 실력이 미천한 저는 route 쉘스크립을 만들어 파일로 저장 후 위와 같은 방법으로 파싱하여 정보를 얻어 냈습니다;;

다 끝내고 생각한 방법이지만 이렇게 할바에 커널에 awk 를 올리는 것이 한결 간편했을 거라는 생각이 드는군요 ㅠㅠ 뭐같은 linux gcc 때문에 몇번의 짜증이 솟구쳤지만 이차저차 기본 기능은 구현이 되는군요 -_-

 

===================

2009년 02월 11일

===================

어제에 이어 오늘도 작업을 시작하였습니다.

먼저 ip 정보 및 subnetmask 정보를 ifconfig 를 이용하여 파싱하였습니다.

먼저 ip 정보를 sed 를 이용하여 파싱하였습니다. sed에 대한 사용설명은 여기를 참조하시면 됩니다.

http://stone.backrush.com/sunfaq/ljs007.html 

 

먼저 ifconfig 와 sed 를 이용하여 ip 주소를 파싱해보도록 하겠습니다.

간단히 쉘 스크립을 하나 만듭니다.

#> vi getinfo.s

 

/sbin/ifconfig | sed '/^ *$/d' | sed -ne 's/inet addr:\([0-9.]*\).*/\1/p;' > ip.info

 

이 명령어는 ifconfig 의 실행 결과 중 inet 이라는 문자열을 담고있는 열을 삭제 후 addr을 제외한 그 이후 값을 화면에 출력하며 ip.info 라는 파일로 저장하는 커맨드 입니다.

실행을 시켜보면

xxx.xxx.xxx.xxx

xxx.xxx.xxx.xxx

라고 ip 주소 및 local host 의 주소가 표시될 것 입니다.

이 중 우리가 필요한 값은 ip주소 값 입니다. 일단 냅두고..

다음으로 필요한 값은 subnetmask 값 입니다.

subnetmask 는 ip 주소가 나온 줄 바로 아래줄에 있군요

이것도 역시 ifconfig 와 sed, grep 를 이용하여 파싱하여 보겠습니다.

 

/sbin/ifconfig eth0 | grep Mask | sed "s/^.*Mask://g" > subnet.info

 

위 커맨드는 ifconfig eth0 의 결과 값중 grep를 이용하여 mask 문자열이 들어간 줄을 파싱하여 sed 를 이용 Mask: 다음에 나오는 subnet mask 값을 파싱하여 subnet.info 라는 파일로 저장하게 하는 커맨드 입니다.

저 역시 리눅스는 익숙치 않아 sed 에 대하여 약 20분 정도 공부를 한 후 만들었습니다 -_-;;

 

다음으로 우리가 필요로 하는 ip값고 subnetmask 값이 파일 두개로 출력이 되었습니다.(물론 처음 파일에 필요없는 호스트 정보도 포함되었군요) 이 파일을 하나로 합쳐 c언어로 파싱하기 좋게 하나로 만들겠습니다.

cat 커맨드를이용하면 쉽게 가능 할 것 같네요..

cat subnet.info ip.info | sort | uniq > ifinfo.info

두개의 파일을 하나로 합쳐 ifinfo.info 파일에 저장을 하도록 합니다.

여기까지 우리가 얻고자 하는 ip subnetmask gateway address, remote ip 중 두가지를 구하였습니다.

다음은 gateway address 를 구해보도록 하겠습니다.

gateway address 는 route 라는 커맨드를 이용하여 확인 및 설정 가능 합니다.

#> route | grep default > gw.info

게이트웨이 정보 중 default 라는 문자열이 들어있는 줄을 필터링하여 얻어냅니다. 몇몇 쓰레기 값도 들어가는 군요.(필요없는 값)

다음 아까 만들었던 ifinfo.info 라는 파일과 gateway 정보가 담긴 파일을 cat 커맨드를 이용하여 파일을 합칩니다.

 

cat ifinfo.info gw.info | sort | uniq > network.info

 

두개의 파일을 하나로 합쳐 network.info 라는 파일에 저장을 합니다.

 

이 파일에는 지금까지 우리가 얻으려 하였던 ip 와 subnet, gateway 정보 등이 들어 있습니다.

 

이 파일을 이용 할 c언어로 돌아옵니다.

 

파일을 열고 network.info 파일을 fscanf()를 이용하여 전체 읽어들인 후 문자열 배열에 넣고

원하는 값을 호출하여 사용하면 됩니다.

저는 폼을 만들어 밸류값에 들어가도록 하여 사용 하였습니다.

아래는 sorce 입니다.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define TRUE 1
#define FALSE 0
#define ON 1
#define OFF 0
#define MAX 12000;

int main(int argc, char *argv[])
{
 
 
 FILE *fp;

 printf("Content-type:text/html \n\n");
 int i = 0;
 int index = 0;
 int r = 0;
 unsigned int delay = MAX;
 char ipinfo = 0;
 char subnetinfo = 0;
 char gwinfo = 0;
 char remote = 0;
 char std[100][100];
 char tmp;
 
 setuid(0);   // 유저에게 루트권한을 부여합니다.
 printf("<html>");
 printf("<head> <center>PLANETINT Network Setting </center></head>");
 printf("<body>");
 
 //printf("<h1>get network info</h1>");
 r == system("./getinfo.s"); //시스템 함수를 이용하여 getinfo.s 스크립(각 정보를 파싱하는 스크립)을 실행합니다.
 if( r == -1 )
 {
 printf("<h1> Fail the get network info</h1>");
 }
 else
 {
 //printf("<h1> Success get Network info </h1>");
 }
 
 //printf("REMOTE_ADDR = %s \n", getenv("REMOTE_ADDR"));
 
 fp = fopen("./network.info" , "rt");  // 파싱한 정보들을 모아놓은 network.info 파일을 엽니다.
 
 if(fp == NULL)
 {
 printf("<h1>DB ERROR</h1>");
 return;
 }
 
 while(feof(fp) == 0)
 {
  fscanf(fp,"%s", &std[index][0]);  // 배열에 파일을 모두 읽어 저장합니다.
  //printf("<h1> %s </h1>", std[index]);
  index++;
 }
 sleep(0.5);  // 0.5초간의 딜레이 --;; 가끔 컴퓨터가 느려져 스크립이 제대로 실행되지 않은 상태에서 값을 읽어오는 경우가 있어 0.5초의 딜레이를 줬습니다.
 //printf("<p> <h1> Host : %s</h1></p>",std[0]);
 //printf("<p> <h1> I  P : %s</h1></p>",std[1]);
 //printf("<p> <h1> SUB : %s</h1></p>",std[2]);
 //printf("<p> <h1> G  W : %s</h1></p>",std[4]);
 printf("<center><form name=\"nset\" action=./cgi-bin/netset.cgi method=\"post\">");
 printf("<p> IP ADDR <br> <input type=\"text\" name = \"ipset\" maxlength=\"15\" value=\"%s\"> </p>",std[1]); // 각 정보를 폼에 뿌려줍니다.
 printf("<p> SUBNET  <br> <input type=\"text\" name = \"sebnet\" maxlength=\"15\" value=\"%s\"> </p>",std[2]);
 printf("<p> GATEWAY <br> <input type=\"text\" name = \"gateway\" maxlength=\"15\" value=\"%s\"> </p>",std[4]);
 printf("<p> SystemIP <br> <input type=\"text\" name = \"systemip\" maxlength=\"15\" value=\"%s\"> </p>",getenv("REMOTE_ADDR")); // 환경변수를 이용하여 리모트 주소를 구해 폼에 뿌려줍니다.
 printf(" <input type=\"submit\" name=\"networkchange\" value=\"Change\">");
 printf("<input type=\"reset\" name=\"netinit\" value=\"Reset\">");
 printf("</form>");
 printf("</center> </body>");
 printf("</html>");
 fclose(fp);
 return 0;
 }

 

아주 간단한 소스로 값을 파싱하여 만들 수 있었습니다.

여기에 변경된 값을 받아 처리를 해주는 함수를 만들면 웹상에서 네트워크 설정 기능이 완성이 됩니다.

+ Recent posts