[Spring Framework ③] Aspect Oriented Programming (AOP)

개발 노트 2008. 7. 10. 16:57 posted by 무병장수권력자


Aspect Oriented Programming (AOP) in Spring Framework

작성자 : 김문규
최초 작성일 : 2008. 7.10

1. 정의
AOP는 Spring Framework의 중요한 특징 중 하나입니다.
AOP란, 기능을 핵심 비지니스 로직과과 공통 모듈로 구분하고, 핵심 로직에 영향을 미치지 않고 사이사이에 공통 모듈을 효과적으로 잘 끼워넣도록 하는 개발 방법입니다.
공통 모듈은 보안 인증, 로깅 같은 요소들이 해당됩니다.

예를 들어 다시 설명하면, 로그를 찍기위해 로그 출력 모듈을 만들어서 직접 코드 사이사이에 집어 넣을 수 있겠지요? 이런건 AOP 적이지 않은 개발입니다.
반면에 로그 출력 모듈을 만든 후에 코드 밖에서 이 모듈을 비지니스 로직에 삽입하는 것이 바로 AOP 적인 개발입니다. 코드 밖에서 설정된다는 것이 핵심입니다.

2. 예제
1) AOP스럽지 못한 코드
public class InventoryController implements Controller {
    protected final Log logger = LogFactory.getLog(getClass());
    private ProductManager productManager;
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
        return new ModelAndView("hello", "model", myModel);
    }
    public void setProductManager(ProductManager productManager) {
        this.productManager = productManager;
    }
}
로그를 찍고 싶은 지점에 로깅 코드를 직접 삽입하는 방법입니다. 물론 이렇게 하는 것이 효율적일 수도 있습니다. 하지만, 클래스 진입 시점마다 로그를 찍는 것과 같이 동일한 패턴이 있는 경우에는 rule을 정의하고 여기에 따라서 동일한 모듈이 호출된다고 하면 매우 직관적이고 간결하면서 유지 보수가 편하게 구현이 될것으로 생각됩니다. 이것을 지원하는 것이 바로  AOP이며 spring에서는 이를 지원하고 있습니다.

2) Spring에서 AOP를 사용하는 방법
Spring에서는 크게
 - Spring API를 이용하는 방법
 - XML schema을 이용하는 방법
 - Annotation 기능을 이용한 방법
이 있습니다.
여기서는 2번째 XML schema를 이용하는 방법의 예제를 소개합니다.
전체 소스를 첨부합니다.

springapp - aop.zip


loggingaspect.java

package springapp.common;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
public class LoggingAspect {
 protected final Log logger = LogFactory.getLog(getClass());
// pointcut method 호출 전에 실행 시킬 로깅 함수
public String beforeLogging(JoinPoint joinPoint) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("calling: " + methodName);
  return methodName;
 }

// pointcut method 결과 리턴 후에 실행 시킬 로깅 함수
 public void returningLogging(JoinPoint joinPoint, Object ret) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("called successfully: " + methodName + " returns " + ret);
 }

// pointcut method에서 예외 발생시에 실행 시킬 로깅 함수
 public void throwingLogging(JoinPoint joinPoint, Throwable ex) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("exception occured: " + methodName + " throws "
     + ex.getClass().getName());
 }

// pointcut method 종료 후에 실행 시킬 로깅 함수
 public void afterLogging(JoinPoint joinPoint) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("finish call: " + methodName);
 }
}

applicationContext.xml

.... (다른 설정 생략)

<bean id="logging" class="springapp.common.LoggingAspect" />
 
<aop:config>
  <aop:pointcut id="publicMethod" expression="execution(public * springapp.service..*.*(..))" />
  <aop:aspect id="loggingAspect" ref="logging">
      <aop:before pointcut-ref="publicMethod" method="beforeLogging" />
      <aop:after-returning pointcut-ref="publicMethod" method="returningLogging" returning="ret" />
      <aop:after-throwing pointcut-ref="publicMethod" method="throwingLogging" throwing="ex" />
      <aop:after pointcut-ref="publicMethod" method="afterLogging" />
  </aop:aspect>
</aop:config>

.... (다른 설정 생략)

먼저 AOP 관련 용어를 설명하도록 하겠습니다.
 - advice : 
여러 객체에 공통으로 적용되는 공통 관심 사항
 - joinpoint : 공통 기능 적용 가능 지점 (spring에서는 메서드 호출만이 가능합니다.)
 - pointcut : joinpoint 중에 실제로 적용할 지점
 - weaving : 핵심 로직에 공통 로직을 삽입하는 것
 - aspect : 
언제 어떤 기능을 적용할 지에 대한 정의

설정 정보는 아래의 구조로 생성합니다.
<aop:config>
    <aop:aspect> : aspect를 설정
        <aop:before> : method 실행 전
        <aop:after-returning> : method 정상 실행 후
        <aop:after-throwing> : method 예외 발생 시
        <aop:after> : method 실행 후 (예외 발생 예부 상관 없음)
        <aop:around> : 모든 시점 적용 가능
    <aop:pointcut> : pointcut 설정

pointcut 설정은 AspectJ의 표현식에 따릅니다.
execution( 수식어패턴 리턴타입패턴 패키지패턴.메소드이름패턴(파라미터패턴) )

이제 모든 설정은 끝났습니다. 그닥 힘들이지 않고 설정할 수 있습니다. 하지만 joinpoint에 해당되는 지점만 적용이 가능하기 때문에 사용해야 할 시점을 잘 선택해야 할 듯 합니다.

3. 맺음말
지금까지 필터같은 기술을 이용해서 이와 비슷한 기능을 구현 했었지요. 실제 대형 과제를 할 경우에는 더욱더 필요한 기능이 아닌가 싶습니다. 아무리 모듈화를 하고 그 모듈을 적용한다 하더라도 일일이 코드에 적용하는 것은 정말 귀찮은 일일뿐 아니라 오류의 소지도 많아지게 됩니다. 그렇기 때문에 AOP는 정말 유용한 기능이 아닐 수 없습니다. 개인적인 생각으로는 이거 하나만으로도 spring을 써야할 이유가 아닐까 합니다. 제가 드린 예제를 기반으로 꼭 여러분의 과제에 적용해 보시길 바랍니다. 감사합니다.

4. 참조
마지막으로 AOP를 이해하는 것에 많은 도움을 준 칼럼을 소개하고자 합니다. 한빛미디어에 김대곤님이 기고하신 글입니다.





'개발 노트' 카테고리의 다른 글

Function Pointer란?  (0) 2008.07.14
Javascript Object Oriented Programming  (1) 2008.07.14
[Spring Framework ②] Inversion of Control  (2) 2008.07.10
CPPTooltip 사용 예제  (0) 2008.07.01
X11에서 Pointer를 이동하는 예제  (0) 2008.07.01


[Spring Framework ②] Inversion of Control

개발 노트 2008. 7. 10. 16:41 posted by 무병장수권력자


Inversion of Control in Spring Framework

작성자 : 김문규
최초 작성일 : 2008. 7.10

IoC는 Spring Framework의 장점을 꼽으라면 가장 먼저 언급되는 개념입니다. 한국어로 변역하면 '제어의 역행'! 한국어가 더 어려워 보입니다. 비슷한 말로 Dependency Injection(DI)라는 말도 있습니다. 한국말로는 의존성 삽입! 아하~ 조금 이해가 되시나요?

간단하게 이해하기 쉽게 같이 알아보지요.

1. 개념
 객체 간의 의존관계를 객체 내부에 선언 또는 정의하지 않고, 외부의 조립기를 이용하여 의존 관계를 설명한다는 것

2. 예제
객체간의 연관성을 선언하는 3가지 방법을 보고, 문제점이 어떻게 IoC(DI)를 이용해서 해결되는 지 알아보지요.

1) 직접 선언하는 방법

public class WriteArticleServiceImpl {
    private ArticleDao articleDao = new MysqlArticleDao();
    ...
}

 - 쉽습니다.
 - 하지만, 이를 테스트하기 위해서는 MySqlArticleDao가 정상적으로 동작해야 합니다. 어렵습니다.
 - 또한, OracleArticleDao를 사용하기로 바뀌었다면 코드를 고쳐야 하지요~ 물론 컴파일도 다시요. 귀찮습니다.

2) Factory 패턴, JNDI를 이용하는 방법

public class WriteArticleServiceImpl {
    private ArticleDao articleDao = ArticleDaoFactory.create();
    ...
}

 - 조금 나아졌나요? 최소한 Oracle로 바뀌어도 코드 수정은 안해도 되겠네요~ ^^
 - 근데 테스트 측면에서는 전혀! 나아진게 없어 보입니다. 올바르게 동작하는 Factory와 JNDI에 등록된 객체가 필요합니다.

3) 외부 조립자를 이용하는 방법

public class WriteArticleServiceImpl {
    private ArticleDao articleDao;
    public WriteArticleServiceImpl(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }
    ...
}

외부 설정 파일 (applicationContext.xml)
<bean name="writeArticleService" class="com.sec.service.WriteArticleServiceImpl">
    <constructor-arg><ref-bean="articleDao"></constructor-arg>
</bean>

<bean name="articleDao" class="com.sec.dao.OracleArticleDao" />

 - 외부 설정(applicationContext.xml)에서 객체간의 의존성을 설명하고 있다는 감이 오시지요? 바로 이겁니다. 외부에서 객체 의존성을 정의하고 있는 것이지요. 책에서는 조립한다고 설명하더군요. (Nice!)
 - 여기서는 생성자를 이용한 방법을 사용하지만 setter를 이용하는 방법도 있습니다. 요건 나중에 차차..
 - 이제 위에서 말한 2가지 문제점이 다 해결되어 보이지요? 아하~ 굳입니다. ^^

3. 참조
1) 웹 개발자를 위한 스프링 2.5 프로그래밍
2)
http://martinfowler.com/articles/injection.html
 - 다음은 IoC 설명의 정석으로 불려지는 Martin Fowler의 글입니다. 시간이 되시면 읽어보세요. 위의 설명이 좀 더 잘 이해되실 겁니다.



[REST ③] Security and REST Web Services by Richard Mooney

웹, 인터넷 2008. 7. 9. 16:37 posted by 무병장수권력자


VORDEL의 Senior Solution Architect인 Richard Mooney가 X-Tech Conference 2007에서 발표한 자료이다.

일반적으로 REST는 보안에 취약하다고 생각하기 때문에 보안이 요구되는 경우에는 사용이 꺼려지는 것이 사실이다. 하지만, 구글, 아마존에서는 이미 REST 방식을 사용하여 상업 서비스를 제공 중이다.

아래의 첨부는 REST에서의 보안에 대한 개괄적인 설명을 한 프리젠테이션 자료이다. 아주 자세한 기술은 기대하지 말 것! 하지만, 도움이 될 것은 확실하니 관심이 있다면 한 번 쯤 읽어보도록....

마지막으로 아래는 Richard Mooney가 REST의 보안에 있어 제시한 키워드 들이다. 자세한 내용은 자료를 참조하길 바란다.

Applying security to REST 
• Applying ACLs to REST methods (GET, POST, PUT, DELETE) <- 너무 순진한 방법
• Filtering QueryStrings <- SQL Injection과 비슷한 공격을 막기 위한 처리, 매우 중요함
• Logging and keeping an audit trail of REST data
• How Google and Amazon apply security to their REST interfaces <- token을 이용한 방법 소개



Windows Rally Program - Web Service on Device

Microsoft 2008. 7. 9. 09:12 posted by 무병장수권력자


Windows Rally Program - Web Service on Device

작성자 : 김문규
최초 작성일 : 2008. 7. 9

¨
무엇인가?

-       네트워크에 연결된 모든 device를 제어하는 protocol set을 정의하는 MS의 대규모 프로젝트

-       network device, PC 서로 간에 connectivity를 제공하기 위한 framework

-       web service에 기반한 데이터 통신 기능 제공 (SOAP, WSDL, XML 기술 적용)

-       effortless, reliable, more secure way to connect each other

 

¨ 기능

-       device의 검색, 이벤트 처리 등 RM적인 기능 제공 (device 세부 규격 정의)

-       device, PC 간의 데이터 교환 기능 제공

-       device상의 좀 더 유연한 구현을 지원하는 기능 제공

-       Windows Vista printer, scanner profile specification 구현됨 (WDK에 포함)

¨ 핵심 스펙 (영어가 의미 전달이 쉬워서 그냥 둔다.)

-       Sending secure messages to and from a Web service

-       Dynamically discovering a Web service

-       Describing a Web service

-       Subscribing to, and receiving events from, a Web service


¨
Protocol Stacks (MS recommendation)

Application Specific Protocol

WS-Discovery

WS-Eventing

WS-MetadataExchange, WS-Transfer

WS-Security, WS-Policy, WS-Addressing

SOAP-over-UDP, SOAP, WSDL, XML Schema

UDP

HTTP

TCP

IPv4 / IPv6 / IP Multicast


'Microsoft' 카테고리의 다른 글

Microsoft OneApp 을 소개합니다.  (2) 2009.08.25
윈도 7 열풍!  (0) 2009.07.30
웹조각 (Web Slice)  (0) 2009.06.16
마이크로소프트가 생각하는 미래의 홈  (0) 2009.05.20
WWT, WorldWide Telescope  (0) 2009.03.31


Google Code Jam

Google 2008. 7. 9. 08:55 posted by 무병장수권력자


사용자 삽입 이미지

간단하게 요약하자면,

구글에서 코딩 컨테스트를 개최한다.
룰은 아래와 같다.
3~6개의 주어진 알고리즘을 구현해야 하고
테스트 케이스를 적용하여 그 적합성을 검증해야 한다.
요구되는 테스트 케이스의 종류는 복잡도에 따라 2종류가 있으며 이에따라 주어지는 제한시간과 배점이 다르다. 간단한 것은 4분, 복잡한 것은 8분이 주어진다.

솔직히 해보고 싶은데, 두렵다. ㅋㅋ (물론 최근들어서는 그럴시간도 없거니와.... ^^ 핑계~)
개발자에게 가장 두려운 것은 자신이 생각하는 것보다 자신의 실력이 그 이하일때가 아닌가 한다.

if you are interested in it, please visit http://code.google.com/codejam/contest

'Google' 카테고리의 다른 글

시덥잖은 Google App Engine 튜토리얼  (0) 2008.08.21
Google App Engine 계정을 드디어 받았습니다.  (2) 2008.08.20
Google's Master Plan  (0) 2008.07.24
Google App Engine Overview  (0) 2008.06.11
Google 사투리 번역 서비스 출시  (0) 2008.04.01


Authentication, Authorization, Acountability, Access Control

보안, 암호화 2008. 7. 8. 16:55 posted by 무병장수권력자


Authentication, Authorization, Acountability, Access Control

작성자 : 김문규
최초 작성일 : 2008. 7. 8

Authentication, Authorization, Accountability, Access Control 이들의 개념은 너무나 유사하고 헷갈린다.
해당 포스트에서는 해당 개념의 유사성과 차이점을 알아보도록 한다.

1. Authentication (인증)
출처 :
http://www.terms.co.kr/authentication.htm
인증이란 어떤 사람이나 사물이 실제로 신고된 바로 그 사람(또는 바로 그 것)인지를 판단하는 과정이다. 개별 또는 인터넷을 포함한 공공 네트웍에서의 인증은 대개 로그온시 암호의 사용을 통해 이루어진다. 암호를 알고 있는 사람은 일단 믿을만한 사용자라고 간주된다. 모든 사용자는 처음에 자신이 원하는 암호를 등록하고, 이후 계속 사용할 때마다, 사용자는 이전에 신고된 암호를 잊지 않고 사용해야만 한다. 그러나, 자금 교환 등이 수반되는 중요한 거래에서 이 시스템의 약점은, 암호가 종종 도난 당하거나, 우연히 알려지거나 또는 잊혀질 수 있다는데 있다.
이러한 이유 때문에, 인터넷 비즈니스와 많은 다른 거래들에서는 좀더 엄중한 인증 과정을 필요로 하는 것이다. 공개키 기반구조의 일부인 인증기관에 의해 발급되고 검증된 디지털 증명의 사용은 인터넷 상에서 인증을 수행하는 표준적인 방법이 되어가고 있다. 필연적으로, 인증은 권한부여에 우선한다 (종종 두 개가 결합된 것처럼 보이더라도).

2. Authorization (권한 부여)
출처 : http://www.terms.co.kr/authorization.htm
Authorization은 누구에게 무엇을 할 수 있거나, 가질 수 있는 권한을 부여하는 과정이다. 다중 사용자 컴퓨터 시스템에서, 시스템 관리자는 어떤 사용자가 그 시스템을 액세스할 수 있는지, 그리고 부여된 사용권한은 어디까지인지(파일 디렉토리의 접근 범위, 허용된 액세스 시간, 할당된 저장 공간의 크기 등)를 그 시스템을 위해 정의한다. 어떤 사람이 컴퓨터 운영체계나 응용프로그램에 로그온 했을 때, 그 시스템이나 응용프로그램은 그 세션 동안 그 사용자에게 어떤 자원의 이용을 허락해야하는지 확인한다. 그러므로, authorization이라고 표현되는 권한부여는, 때로 시스템관리자에 의해 미리 설정되는 권한들과 사용자가 액세스를 해 왔을 때 미리 설정된 권한을 실제로 확인하는 일 모두를 지칭하기도 한다.

3. Accountability (감사, 책임)
출처 :
http://en.wikipedia.org/wiki/Access_control
Accountability는 audit 기록이나 log들을 분석하여 시스템 상의 개체들의 동작의 정당성을 확인하는 과정이다. 주로 보안 위반을 감지하고 위반 사태를 재연하는 데에 audit 기록과 log 정보들이 사용되기 때문에 중요하다. 만일 주기적으로 이런 정보들이 감시되어 지고 관리되어 지지 않는다면 해당 시스템은 안전하고 일관된 방법으로 관리되고 있다고 할 수 없겠다.
대부분의 시스템은 미리 정의된 기준을 넘어서는 이벤트 발생 시에 자동으로 관련 리포트를 제공하는 기능을 제공한다. 이는 clipping level이라고 부른다. 예를 들면 수차례 로그인 실패를 거듭하는 경우난 특정 계정을 삭제하려는 행위등이 여기에 해당된다.

4. Access Control (접근 제어)
출처 :
http://en.wikipedia.org/wiki/Access_control
Access Control은 특정한 개체(사용자)가 어떤 자원을 사용하고자 할 때 이를 허용하거나 거부하는 기능이다. 개인적인 생각으로는 위에 언급된 모든 개념을 포함하고 있는 상위의 개념이다. 어떤 시스템을 안전하게 보호하기 위해서 위와 같은 개념이 잘 정의되고 구현되어 있어야 하는 것이다. 이러한 목표를 이루기 위한 일련의 과정 또는 기술을 Access Control이라고 한다.
주로 다음과 같은 대표적인 기술이 알려져 있다.
 -
Discretionary Access Control
 - Mandatory Access Control
 -
Role Based Access Control

 





IPv6

네트워크 2008. 7. 7. 12:10 posted by 무병장수권력자


IPv6

출처 : http://ko.wikipedia.org/wiki/IPv6

1. IPv4와의 차이점
IPv6와 기존 IPv4 사이의 가장 큰 차이점은 바로 IP 주소의 길이가 128비트로 늘어났다는 점이다. 이는 폭발적으로 늘어나는 인터넷 사용에 대비하기 위한 것이다. 또한 IPv6는 여러가지 새로운 기능을 제공하는 동시에 기존 IPv4와의 호환성을 최대로 하는 방향으로 설계되었다. 때문에 몇몇 예외(
FTP, NTPv3 등)를 제외하고 대부분의 네트워크 수준 상위 프로토콜들은 큰 수정 없이 IPv6 상에서 동작할 수 있다. IPv6 프로토콜은 다음과 같은 특성을 지니는 프로토콜로 개발되었다.

  • IP 주소의 확장 : IPv4의 기존 32 비트 주소공간에서 벗어나, IPv6는 128 비트 주소공간을 제공한다.
  • 호스트 주소 자동 설정 : IPv6 호스트는 IPv6 네트워크에 접속하는 순간 자동적으로 네트워크 주소를 부여받는다. 이는 네트워크 관리자로부터 IP 주소를 부여받아 수동으로 설정해야 했던 IPv4에 비해 중요한 이점이다.
  • 패킷 크기 확장 : IPv4에서 패킷 크기는 64킬로바이트로 제한되어 있었다. IPv6의 점보그램 옵션을 사용하면 특정 호스트 사이에는 임의로 큰 크기의 패킷을 주고받을 수 있도록 제한이 없어지게 된다. 따라서 대역폭이 넓은 네트워크를 더 효율적으로 사용할 수 있다.
  • 효율적인 라우팅 : IP 패킷의 처리를 신속하게 할 수 있도록 고정크기의 단순한 헤더를 사용하는 동시에, 확장헤더를 통해 네트워크 기능에 대한 확장 및 옵션기능의 확장이 용이한 구조로 정의하였다.
  • 플로우 레이블링(Flow Labeling) : 플로우 레이블(flow label) 개념을 도입, 특정 트래픽은 별도의 특별한 처리(실시간 통신 등)를 통해 높은 품질의 서비스를 제공할 수 있도록 한다.
  • 인증 및 보안 기능 : 패킷 출처 인증과 데이터 무결성 및 비밀 보장 기능을 IP 프로토콜 체계에 반영하였다. IPv6 확장헤더를 통해 적용할 수 있다.
  • 이동성 : IPv6 호스트는 네트워크의 물리적 위치에 제한받지 않고 같은 주소를 유지하면서도 자유롭게 이동할 수 있다. 이와 같은 모바일 IPv6는 RFC 3775RFC 3776에 기술되어 있다. (그러나, IPv4에도 모바일 IP가 정의되어 있지만 아직 많이 사용되지 않는다는 것을 밝혀둔다.)

그림 1. IPv4 헤더 : 20byte

그림 2. IPv6 헤더 : 40byte

보면 알겠지만 헤더가 훨씬 단순해졌음을 볼수 있다

2. 주소 표현
IPv6의 128비트 주소공간은 다음과 같이 32자리의
16진수를 4자리씩 끊어 나타낸다.

2001:0db8:85a3:08d3:1319:8a2e:0370:7334

그러나 32자리의 16진수는 사람이 읽고 쓰기에 불편하고, 대부분의 자리가 0의 숫자를 갖게 되므로, 4자리가 모두 0의 숫자를 가질 경우 하나의 0으로 축약하거나, 혹은 아예 연속되는 0의 그룹을 없애고 ':' 만을 남길 수 있다. 따라서 아래의 IPv6 주소들은 모두 같은 주소를 나타낸다.
2001:0DB8:0000:0000:0000:0000:1428:57ab
2001:0DB8:0000:0000:0000::1428:57ab
2001:0DB8:0:0:0:0:1428:57ab
2001:0DB8:0::0:1428:57ab
2001:0DB8::1428:57ab

3. IPv4 주소의 IPv6 형태
기존 네트워크와의 호환성을 위해, IPv4 주소는 다음과 같은 세 가지 방법을 통해 IPv6 주소로 나타낼 수 있다.

  • 표준 IPv6 표기 : IPv4 주소 192.0.2.52는 16진수로 표시하면 0xC0000234가 된다. 이를 그대로 IPv6 주소로 변경하면 0000:0000:0000:0000:0000:0000:C000:0234가 되고, 줄이면 ::C000:234가 된다.
  • IPv4 호환 주소 : IPv4와의 호환성과 가독성을 위해 기존 표기에 '::' 만을 붙여 ::192.0.2.52와 같이 쓸 수 있다. 그러나 이 방법은 더 이상 사용되지 않아 폐기될 예정이다.
  • IPv4 매핑 주소 : IPv6 프로그램에게 IPv4와의 호환성을 유지하기 위해 사용하는 다른 방법으로, 처음 80비트를 0으로 설정하고 다음 16비트를 1로 설정한 후, 나머지 32비트에 IPv4 주소를 기록하는 IPv4 매핑 주소가 존재한다. 이 주소공간에서는 마지막 32비트를 10진수로 표기할 수 있다. 따라서 192.0.2.52::ffff:192.0.2.52와 같이 쓸 수 있다.

4. 특수 주소 공간

  •  ::/128 - 이 주소는 모든 값을 0으로 세팅한 특수한 주소이다. 가상적으로만 사용된다.
  •  ::1/128 - 자기 자신의 주소를 가리키는 루프백 주소이다. 프로그램에서 이 주소로 패킷을 전송하면 네트워크는 전송자에게로 패킷을 반송한다. IPv4의 127.0.0.1과 동일하다.
  •  ::/96 - IPv4 호환 주소를 위해 사용되는 주소공간이다.
  •  ::ffff:0:0/96 - IPv4 매핑 주소를 위해 사용되는 주소공간이다.
  • fc00::/7 - IPv6 유니캐스트를 위한 주소공간이다.
  • fe00::/10 - link-local address를 위한 주소공간이다. IPv4의 자동 설정 IP 주소인 169.254.x.x 에 해당한다.
  • fec0::/10 - site-local address를 위한 주소공간이다. 네트워크 내부에서만 유효한 주소이며, 2004년 10월 RFC3879에서 폐기되어 더 이상 사용되지 않는다.
  • ff00::/8 - IPv6 멀티캐스트를 위한 주소공간이다. IPv4의 브로드캐스트는 더 이상 지원되지 않으며, IPv6에서는 대신 멀티캐스트를 사용해야 한다.


SNMP (Simple Netwok Management Protocol)

네트워크 2008. 7. 7. 11:02 posted by 무병장수권력자


SNMP

윤 상배

dreamyun@yahoo.co.kr

교정 과정
교정 0.8 2003년 4월 20일 21시
최초 문서작성

1절. 소개

개인적으로 최근들어 SNMP에 관심을 가지게 되었다. (실은 상당히 오래되었지만) 그래서 앞으로 몇부? 에 걸쳐서 SNMP관련 강좌를 개설하고자 한다. 강좌는 SNMP개요및 설치운용에서 부터 시작해서 프로그래밍을 통해서 SNMP응용 애플리케이션을 제작하고, 확장 MIB(뒤에 설명한다)를 작성하는 것 까지를 다룰것이다.

이번글은 그중 첫번째 글로 SNMP개요와 설치및 운용에 대한 글이다. 설치및 운용은 실제 어떻게 작동되는지 눈으로 확인하는 차원의 수준에서 이루어질 것이며, 설치되는 snmp애플리케이션의 상세설치와 높은 수준에서의 운용에 대해서는 언급하지 않을것이다. 이러한 것들은 (필요할경우)해당 snmp애플리케이션의 메뉴얼을 참고해서 개인적으로 학습해야만 할것이다.

여기에서 얻은 지식은 나중에 SNMP애플리케이션을 제작하는 밑거름이 될것이다.


2절. SNMP개요

2.1절. SNMP란 무엇인가

SNMP는 Simple Network Management Protocol의 약자이다. 해석을 해보자면 간단한 네트워크관리를 위한 규약 인데, 말그대로 SNMP는 네트워크관리를 위한 용도로 사용되는 프로토콜이다. 가장 앞에 Simple라는 단어가 붙어있는데, 진짜로 간단한 프로토콜인지 아닌지는 사람에 따라 약간씩 차이가 있을수 있다. 필자가 보기엔 그리 복잡한 프로토콜은 아닌것 같은데, 어떤 사람들은 매우 복잡한 프로토콜 이라고 말하는 사람들도 있다.

그럼 먼저 SNMP가 나타난 배경에 대해서 알아보도록 하겠다. SNMP가 쓰이기 전에 일반적으로 사용되는 네트워크 관리는 ICMP에 의존했었다. ICMP는 Network계층의 프로토콜로써, 운영체제에 관계없이 사용할수 있는 간단한 프로토콜이였다. 이 프로토콜을 이용해서 우리는 네트워크로 연결된 각각의 호스트가 작동하고 있는지, 작동한다면 어느정도의 응답시간을 가지고 작동하는지 등의 간단한 정보를 얻을수 있었으며, 초기에는 이정도로도 필요한 네트워크 관리가 가능했었다. ICMP를 이용한 가장 유용한 도구는 아마도 ping 프로그램일 것이다.

그러나 인터넷의 사용이 보편화되고 네트워크에 연결된 호스트의 수가 증가하자 거기에 따라서 네트워크 구성역시 복잡해지고, ICMP만을 가지고는 이러한 네트워크의 관리를 효율적으로 할수 없게 되었다.

그래서 몇가지 프로토콜에 대한 연구가 진행되었고, SGMP, HIMS, CMIP/CMIS등이 제안되게 되었다. 이중에서 SGMP를 발전시킨 SNMP가 사실상 네트워크 관리를 위한 표준적인 프로토콜로 자리잡게 되었다. 다른 프로토콜들이 사용되지 않은데에는 몇가지 이유가 있었다. CMIP/CMIS는 너무 방대하고 너무 복잡했으며, HEMS의 경우에는 실제 적용사례가 적었기 때문이다.

어쨋든 SNMP는 거의 대부분의 운영체제에서 사용되어 지고 있다. 여러분이 사용하는 Linux, 그밖의 대부분의 유닉스와, 윈도우계열 운영체제는 기본적으로 SNMP프로토콜을 사용하는 도구들을 제공하고 있다. 그외에도 router등 TCP/IP를 네트워크 프로토콜로 사용되는 운영체제들 역시 SNMP는 필수적으로 제공하고 있다.


2.2절. SNMP로 할수 있는 것들

SNMP를 이용해서 할수 있는 것들은 다음과 같다.

네트워크 구성관리

네트워크상의 호스트들이 어떤 구조를 이루고 있는지 지도를 그리는게 가능하다.

성능관리

각 네트워크 세그먼트간 네트워크 사용량, 에러량, 처리속도, 응답시간 등 성능 분석에 필요한 통계정보를 얻어낼수 있다.

장비관리

SNMP의 주목적이 네트워크관리관리 이기는 하지만 SNMP특유의 유연한 확장성을 이용하여서 시스템정보(CPU, MEMORY, DISK 사용량)의 정보를 얻어올 수 있도록 많은 부분이 확장되었다. 이 정보는 네트워크문제를 해결하는데 큰도움을 준다. 예를들어 특정 세그먼트의 네트워크 사용량이 갑자기 급증했는데, 특정 호스트의 CPU사용율까지 갑자기 증가했다면, 우리는 해당 호스트에서 문제가 발생했을것이란걸 유추해낼수 있을것이다.

보안관리

정보의 제어 및 보호 기능, 최근버젼인 SNMP3는 특히 정보보호를 위한 기능이 향상되었다.


2.3절. SNMP를 통한 망의 구성

SMTP는 인터넷상에서 메시지를 교환하기 위한 프로토콜로 사용되며, 주로 전자메일 교환을 위해서 사용되는 프로토콜이다. 그러나 SMTP는 어디까지나 프로토콜일 뿐이며, 실제 메시지를 인터넷상에서 주고 받기 위해서는 SMTP프로토콜을 사용하는 SMTP서버(Sendmail같은)와 SMTP클라이언트(mutt, pine같은)가 준비되어 있어야만 한다.

SNMP역시 그자체로는 프로토콜일 뿐이며 SNMP프로토콜을 활용해서 실제 네트워크 관리 정보를 얻어오기 위해서는 응용 애플리케이션이 준비되어있어야만 한다. 보통의 네트워크프로토콜을 사용하는 애플리케이션이 서버/클라이언트 모델로 구성되듯이 SNMP역시 서버와 클라이언트로 구성된다.

그림 1. SNMP망 관리 시스템

사용자 삽입 이미지

일반적으로 SNMP망 에서는 서버/클라이언트라고 부르지 않고 snmp manager/snmp agent라고 부른다. snmp agent는 관리대상이 되는 시스템에 설치되어서 필요한 정보(네트워크 혹은 시스템)를 수집하기 위한 snmp 모듈(혹은 애플리케이션) 이며, snmp manager은 snmp agent가 설치된 시스템에 필요한 정보를 요청하는 snmp 모듈이다. snmp agent는 서버, snmp manager은 클라이언트로 생각하면 이해하기가 좀더 수월할 것이다(그러나 반드시 agent가 서버, manager이 클라이언트가 되는건 아니다. 그냥 개념적으로 이해만 하고 있도록 하자).

2.4절. MIB에 대해서

SNMP는 네트워크를 관리하기 위한 프로토콜이다. 그렇다면 무엇을 관리할 것인가(관리객체)를 결정해야 할것이다. 관리객체를 결정했다면, 이러한 관리객체를 효과적으로 관리하기 위해서 이를 분류해야 할것이다. 이게 바로 MIB이다.

MIB는 Man In Black의 줄임말이 아니다. Management Information Base의 줄임말인데, 관리되어야할 자원 객체의 분류된 정보를 말한다. 관리되어야할 객체는 시스템정보, 네트워크사용량, 네트워크 인터페이스정보 등이 된다.

이 MIB객체들은 관리하기 편하도록 Tree구조를 가지게 된다. 다음은 MIB의 일반적인 구조이다.

그림 2. MIB계층 구조

사용자 삽입 이미지

MIB는 위에서 처럼 계층적인(디렉토리) 구조를 가지게 된다(위의 그림은 MIB를 설명하기 위해 일부만을 표시하고 있다). 예를들어서 agent가 설치되어 있는 시스템으로 부터 시스템부가정보(sysDescr)를 얻어오길 원한다면 ISO.org.dod.internet.mgmt.mib-2.system.sysDescr과 같은 식으로 manger에서 데이타를 요청하면 된다.

위의 MIB계층 구조를 보면 각 MIB옆에 숫자가 있는것을 볼수 있다. 이 숫자가 OID번호이다. 즉 sysDescr의 OID값은 1.3.6.1.1.2.1.1.1 이 될것이다. OID번호를 이용하는 이유는 MIB고유 문자열을 통해서 원하는 데이타를 가져오기위해서는 아무래도 요청이 길어질수가 있기 때문이다.

MIB는 IANA(Internet Assigned Number Authority)라는 단체에서 관리하며 표준적으로 사용되고 있다. 그럼으로 표준적인 MIB구현을 위해서는 IANA에서 OID를 부여받아야만 한다. 그래야 전체네트워크상에서 다른 여러가지 MIB와 중복되지 않고 사용이 가능할것이다.

작은 정보: cisco과 같은 대중적인(거의 표준이나 마찬가지인) 제품들은 모두 자체적인 MIB를 구현해서 IANA에 등록하여 사용하고 있다. 여러분이 cisco 라우터등의 SNMP정보를 접근할수 있다면 cisco MIB가 등록되어 있음을 확인할수 있을것이다. 확인하는 방법은 다음 강좌에서 따로 언급하도록 하겠다.

MIB는 계층적 구조를 가짐으로 필요에 따라서 확장해서 사용이 가능하며, (물론 프로그래밍 능력이 있어야 하지만)때에 따라서는 자체 회사내에서만 사용가능하거나 제한된 네트워크 영역의 네트워크상황을 관제하는 제품을 위한 MIB를 추가해야 하는경우가 생길수 있을것이다. 그래서 사설로 MIB를 만들어서 사용할수 있는 여지를 남겨두었다. (마치 독립된 지역네트워크를 위해 사설IP를 사용하는 것처럼) 이러한 사설 MIB는 private(4)의 enterprises(1)에 정의해서 사용할수 있다. 여러분이 그리 대중적이지 않은 그래서 IANA에 등록되지 않은 어떤 장비의 고유 SNMP정보를 얻어오고 싶다면 업체에 문의하거나, 메뉴얼을 확인하는 정도로 쉽게 SNMP정보를 얻어올수 있다.

현재 MIB는 버젼 2까지나와 있으며, 버젼의 구분을 위해서 MIB-1, MIB-2로 부르고 있다. MIB-2는 MIB-1의 확장판으로 MIB-1의 모든 객체를 포함하여 약 171개의 객체들을 더 포함하고 있다. 최근의 제품들은 대부분 MIB-2를 지원하고 있다. 물론 위에서 말했듯이 독자적인 MIB를 만들어서 사용할수 있으며, 이를 확장 MIB라고 부른다.


2.5절. SNMP 프로토콜의 동작과 구성

현재 SNMP는 버전 3가지 나와있는 상태이지만 아직까지는 버젼2가 가장 널리 사용 되고 있다. 필자역시 SNMP 버젼 2에 대한 경험이 많은 관계로 버젼2를 기준으로 설명하도록 하겠다.

SNMP는 기본적으로 네트워크 정보를 수집하는데 그 목적이 있는데, 수집하는 몇가지 각각 다른 방법이 있다. 일반적으로 생각해서 우리가 생활중에 얻게 되는 정보는 우리가 요구해서 발생하는 정보와(신문을 구입한다든지, 인터넷으로 서핑을 하는등) 뉴스속보와 같은 형식으로 중요한 일이 있을때 발생하는 정보가 있을것이다. 또한 단지 정보를 얻는데 그치지 않고 정보를 입력하기도 한다.

SNMP정보수집역시 기본적으로 위의 일상생활에서의 정보수집과 같은 방식으로 이루어진다. 이하 snmp manager은 manager로 snmp agent는 agent로 부르도록 한다.

GET

manager에서 agent로 특정 정보를 요청하기 위해서 사용한다.

GET NEXT

기본적으로는 GET과 같은일을 한다. 그러나 SNMP에서 각정보들은 계층적 구조로 관리된다. 위의 MIB계층 구조를 나타낸 이미지에서 우리는 system(1)계층밑에 있는 모든 정보를 가져오고 싶을 때가 있을것이다. 그럴경우 GET NEXT를 사용할수 있다.

SET

manager에서 agent로 특정 값을 설정하기 위해서 사용한다.

TRAP

agent에서 통보해야될 어떤 정보가 발생했을때(임계치를 넘는네트워크자원 사용등) manager에게 해당 상황을 알리기 위해서 사용한다. 위의 다른 요청들이 동기적 요청이라면 이것은 비동기적 사건을 알리기 위해서 사용되어진다.

SNMP프로토콜은 기본적으로 어떤 정보를 요청하는 메시지와 이에 대한 응답메시지로 이루어지며 다음과 같은 구조를 가지고 있다.

표 1. SNMP 메시지

Version Community name SNMP PDU
Version은 말이 필요없다. SNMP프로토콜의 버젼번호를 나타낸다. Community name은 메니저와 에이전트간의 관계를 나타내는데, 인증, 접근통제등의 목적으로 사용된다. 보통은 간단하게 public을 사용한다. PDU 는 Physical Data Unit의 줄임말인데, 실제 전송되는 필요한 정보들을 담고 있는 Unit이다. Unit 이라고 하는 이유는 실제 전송되는 정보들의 부가 속성을 나타내기 위한 몇가지 값들을 포함하고 있기 때문이다. PDU는 PDU 타입(GET인지 Set인지 GET Next인지, TRAP인지등)과, Request-id, 실제보내고자 하는 데이타등(OID와 OID에 대한 값들)으로 구성되어 있다.

SNMP를 통해서 전달되는 메시지들은 기본적으로 UDP를 이용하게 된다. 바로위에서 PDU는 Request-id를 포함하고 있다고 했는데, 데이타그램처리방식인 UDP의 단점을 극복하기 위해서 사용되는 값으로, 각 메시지의 요청번호를 표시한다. 그래야만 수신된 SNMP메시지가 어떤 요청에 대해서 수신된 메시지인지 확인이 가능할것이기 때문이다.


3절. SNMP 설치 및 운용

그럼 실제로 시스템에 SNMP(agent와 manager 애플리케이션)을 설치해서 정보를 가져오는걸 간단히 테스트 해보도록 하겠다.

설치는 Linux(Kernel-2.4.x)에서 ucd-snmp로 할것이다. 위에서 설명했듯이, SNMP는 manager과 agent로 운영되게 되는데, 테스트의 편의를 위해서 하나의 시스템(localhost)에서 manager와 agent를 운용하도록 하겠다.


3.1절. ucd-snmp 설치

ucd-snmp는 net-snmp.sourceforge.net에서 얻을수 있으며 애플리케이션 관련 정보들도 얻을수 있다. ucd-snmp는 현재 버젼 5.x대까지 진행되어 있는데, 5.x부터는 net-snmp로 이름을 바꾸고 개발되어지고 있으며, 4.x버젼까지를 ucd-snmp라고 부르고 있다. 필자는 익숙한 ucd-snmp(버젼 4.x)를 설치하도록 할것이다. 비록 net-snmp가 최신이긴 하지만 별로 다루어본적이 없고, 대부분의 경우 아직까지는 ucd-snmp가 많이 사용되어지고 있기 때문이다. 최신이 아니라고 불만을 가질 필요는 없다. 근본적으로 net-snmp와 ucd-snmp간의 차이는 없으며, 우리의 목적은 최신의 snmp애플리케이션을 테스트하는게 아닌 snmp의 기능과 원리를 이해하고 이를 이용해서 필요한 응용 애플리케이션을 작성하는 것이기 때문이다.

위의 URL에서 ucd-snmp를 다운받아서 압축을 풀고 컴파일 하도록 하자. 컴파일 하는중에는 아마도 아무런 문제가 없을것이다. 컴파일은 매우 일반적인 방법을 따른다. 적당한 디렉토리에 압축을 풀고 ./configure, make, make install 하면된다.

	
[root@localhost src]# tar -xvzf ucd-snmp-4.2.6.tar.gz 
[root@localhost src]# cd ucd-snmp-4.2.6 
[root@localhost ucd-snmp-4.2.6]# ./configure  
[root@localhost ucd-snmp-4.2.6]# make 
[root@localhost ucd-snmp-4.2.6]# make install
			
헤에... 너무 간단하지 않은가 ?


3.2절. SNMP AGENT 실행

make install 까지 했다면 agent와 manager프로그램이 모두 설치되어 있을 것이다. 그리고 여기에 더불어 개발자를 위한 각종 라이브러리와 헤더파일들도 설치된다. 이 라이브러리와 헤더파일들은 개발할때 필요하며 다음 강좌에서 다루게 될것이다.

ucd-snmp는 agent 프로그램으로 snmpd를 제공한다. agent환경을 제대로 만들려면 복잡해보이는(사실은 그리 복잡하다고 볼수없는) 설정파일을 만들어줘야 하지만 이것은 각자의 몫이다. net-snmp프로젝트 홈페이지에서 제공하는 메뉴얼을 참고하기 바란다. 어쨋든 현재로써는 단지 snmpd를 띄우는 정도로 snmp agent환경을 만들수 있다.

[root@localhost root]# snmpd
			
이것으로 snmp를 테스트할 최소한의 agent환경이 구축되었다.


3.3절. SNMP MANAGER 테스트

3.3.1절. 동기적인 데이타 요청 - snmp get, get next

GET과 GET NEXT는 동기적인 정보요청을 위해서 사용한다. manager에서 agent에 대해서 정보를 요청했을때 해당 정보를 agent에서 보내주는 방식이다. GET은 단일정보요청을 위해서 사용하며, GET NEXT는 해당 계층의 하위에 있는 모든 정보의 요청을 위해서 사용된다.

ucd-snmp는 이러한 정보요청을 위한 manager프로그램으로 snmpget과 snmpnext, snmpwalk를 제공한다.

snmpget은 이름에서 알수 있듯이 agent로부터 특정한 정보를 얻어내기 위해서 사용한다. 정보를 얻기 위해 필요한 기본정보는 agent가 설치되어 있는 서버의 주소(혹은 이름) 와 커뮤니티(권한을 위한)이름 그리고 얻기 원하는 정보의 OID번호 혹은 MIB의 계층이름이다. 예를들어서 localhost로부터 public권한을 가지고 sysDescr(시스템 부가정보)정보를 얻어오고 싶다면 아래와 같이 하면 된다.

 
[root@localhost /root]# snmpget localhost public system.sysDescr.0
system.sysDescr.0 = Linux localhost 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686
				
혹은 MIB이름대신에 OID번호를 사용해도 된다.
 
[root@localhost /root]# snmpget localhost public 1.1.0 
system.sysDescr.0 = Linux localhost 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686
				

snmpwalk는 해당 MIB의 하위계층에 있는 모든 정보를 요청한다. 예를들어 system MIB의 하위 계층에 있는 모든 OID에 대한 정보를 요청하길 원한다면 아래와 같이 하면된다. 이게 가능한 이유는 snmpwalk가 정보를 요청하기 위해서 snmp메시지를 만들때 PDU타입을 GET NEXT를 사용하기 때문이다. 나중에 직접구현하게 될것이다. 지금은 구현에 신경쓰지 말자.

[root@localhost /root]# snmpwalk localhost public system
system.sysDescr.0 = Linux localhost 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686
system.sysObjectID.0 = OID: enterprises.ucdavis.ucdSnmpAgent.linux
system.sysUpTime.0 = Timeticks: (2685699) 7:27:36.99
system.sysContact.0 = yundream@joinc.co.kr
system.sysName.0 = localhost
system.sysLocation.0 = myhome 
system.sysORLastChange.0 = Timeticks: (0) 0:00:00.00
....
				
system하위의 모든 OID에 대한 정보를 얻어오고 있음을 확인할수 있다.

snmpgetnext는 snmpwalk의 기능 축소판정도로 볼수 있을것이다. 즉 MIB계층구조에서 현재 요청한 OID의 다음 OID의 정보를 가져온다. 예를들어 system.sysDescr.0에 대한 정보를 요청하면 다음 OID인 system.sysObjectID.0의 정보를 요청하게 될것이다. 이게 가능한 이유는 snmpwalk와 마찬가지로 내부적으로 GET NEXT를 이용하고 있기 때문이다. snmpwalk가 더이상 얻을수 없을때까지 OID를 요청하는것과 달리 snmpgetnext 바로다음의 OID만을 요청한다.

 
[root@localhost /root]# snmpgetnext localhost public system system.sysDescr.0
system.sysDescr.0 = Linux localhost 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686
system.sysObjectID.0 = OID: enterprises.ucdavis.ucdSnmpAgent.linux
				


3.3.2절. 비동기적인 데이타 요청 - snmp trap

기본적으로 GET, GET NEXT를 통한 데이타요청은 일정한 polling시간을 가지고 manager에서 agent로 필요한 정보를 요청하는 방식이다. 그러나 이걸 이용해서는 비동기적으로 발생하는 정보를 수집할수가 없다.

이러한 비동기적인 정보는 여러가지가 될수 있다. 예를들면 특정 네트워크 세그먼트에 문제가 생겼다거나 디스크나 메모리용량을 과다하게 사용하고 있다거나(많은 운영체제의 경우 시스템정보까지도 snmp를 통해서 얻을수 있도록 허용하고 있다)하는 사건들은 비동기적으로 발생할것이다. 이럴경우에는 agent에서 manager측으로 사건을 통보해야 할것이다. 이렇게 agent에서 manager측으로 비동기적으로 사건을 통보하는 것을 SNMP TRAP라고 한다(간단히 말해서 경고메시지 보내는거다).

ucd-snmp에서는 이러한 trap정보를 전송하고 받기 위해서 snmptrapd와 snmptrap를 제공한다. snmptrapd는 agent에 제공되는 데몬프로그램으로 manager에서의 trap데이타 발생을 기다린다. snmptrap는 agent에 설치되어서 사용될수 있으며 trap데이타를 manager로 전송하는 일을한다.

이 snmptrap은 꽤 유용하게 사용할수 있다. 간단하게 스크립트로 만들어서 어떤 파일이 변조되었을경우 trap정보를 manager쪽으로 발생시킨다거나, 프로세스 갯수가 일정갯수 이상 초과했을때 이를 전송한다든지 하는 기능을 비교적 간단하게 추가시킬수 있을것이다.

다음은 ucd-snmp에서 제공하는 trap애플리케이션을 이용한 간단한 테스트이다. 먼저 snmptrapd를 manager측에서 실행시켜야 한다. 이 애플리케이션은 옵션없이 실행할경우 데몬모드로 실행되며 표준출력을 시키지 않음으로 다음과 같이 옵션을 주고 실행시켜서 일반모드(forground)에서 받은 trap정보를 표준출력하도록 실행시키도록 하자.

[root@localhost root]# snmptrapd -f -P
2003-04-23 00:13:34 UCD-snmp version 4.2.6 Started.
				
이제 agent측에서 snmptrap를 이용해서 trap정보를 manager로 전송해보도록 하자.
[root@localhost root]# snmptrap -v 2c -c public localhost "" ucdStart sysContact.0 s "yundream"
				
그러면 manager로 system.sysContact.0="yundream" 과 같은 정보가 전달되는걸 확인할수 있을것이다.

이들 ucd-snmp에서 제공하는 애플리케이션들의 자세한 사용법은 메뉴얼 페이지를 참고하기 바란다.


4절. 결론

이상 SNMP의 개념과 개념의 이해를 위해서 실제 사용되는 snmp애플리케이션을 설치해서 간단히 운영테스트까지 해보았다. 이러한 운영테스트를 위해서 ucd-snmp를 사용했는데, 다음 강좌는 ucd-snmp에서 제공하는 snmplib를 통해서 snmp애플리케이션을 만드는 법을 다루도록 하겠다.

출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/SNMP_%B0%B3%BF%E4

SNMP 정리 자료

출처 : coffeenix.net/doc/network/snmp.ppt


'네트워크' 카테고리의 다른 글

base64 인코딩 ,디코딩의 원리  (1) 2009.01.14
HTTP (Hyper-Text Transfer Protocol) 개요  (0) 2008.10.11
LDAP (Lightweight Directory Access Protocol)  (0) 2008.07.16
IPv6  (0) 2008.07.07


CPPTooltip 사용 예제

개발 노트 2008. 7. 1. 10:59 posted by 무병장수권력자


출처 : code project

Tooltip을 제공하기 위해 HTML을 사용할 수 있는 예제이다.
src 폴더 아래의 것을 사용하면 되고, 이에 대한 예제는 demo 폴더를 참조하길 바란다.

본 예제는 VC6에서 만들어 진것을 VS2008로 변환하였다. 컴파일시 참조하길 바란다.




X11에서 Pointer를 이동하는 예제

개발 노트 2008. 7. 1. 10:47 posted by 무병장수권력자


출처 : 기억 안남 (code project 였을 듯)

main.c
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
void
usage(const char *err, ...)
{
    va_list va;
    va_start(va, err);
    fprintf(stderr, "ERROR: ");
    vfprintf(stderr, err, va);
    va_end(va);
    fprintf(stderr, "\n"
"usage: xwarppointer <command> <args>\n\n"
" commands:\n"
"   screen <+/-> | <screen #>       Move cursor to specific screen, or        \n"
"                                   relative to current one. Does not change  \n"
"                                   the cursor's position on the screen.      \n"
"\n"
"   abspos <x|.> <y|.>              Moves cursor to given X and Y coordinates.\n"
"                                   If . is specified instead of a #, it      \n"
"                                   doesn't change that axis.                 \n"
"\n"
"   relpos <x offset> <y offset>    Move the cursor relative to its current   \n"
"                                   position.                                 \n"
"\n"
"   get                             Return the cursors position.              \n"
"\n");
    exit(1);
}
int
myatoi(const char *str, int *ret) {
    char *p;
    int i;
    i = strtod(str, &p);
    if (p == str)
 return 0;
    *ret = i;
    return 1;
}
int
main(int argc, char *argv[])
{
    Display *display;
    Window root;
   
    if ((display = XOpenDisplay(NULL)) == NULL) {
 fprintf(stderr, "Cannot open local X-display.\n");
 exit(1);
    }
    root = DefaultRootWindow(display);
    if (argc < 2) usage("wrong number of args");
    if (!strcasecmp(argv[1], "screen")) {
 Window fromroot, tmpwin;
 XWindowAttributes attr;
 int screen = -1, rot, x, y, tmp;
 if (argc != 3)
     usage("screen: wrong number of args");
 if (*argv[2] == '+')
     rot = 1;
 else if (*argv[2] == '-')
     rot = -1;
 else
     screen = atoi(argv[2]);
 XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp);
 if (screen == -1) {
     XGetWindowAttributes(display, fromroot, &attr);
     screen = XScreenNumberOfScreen(attr.screen);
     screen += rot;
     if (screen >= ScreenCount(display))
  screen -= ScreenCount(display);
     if (screen < 0)
  screen += ScreenCount(display);
 } else {
     if (screen >= ScreenCount(display) || screen < 0) {
  fprintf(stderr, "Cannot get root window of screen!\n");
  exit(1);
     }
 }
 root = RootWindow(display, screen);
 XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
 XFlush(display);
    } else if (!strcasecmp(argv[1], "abspos")) {
 int x, y, tmp;
 Window fromroot, tmpwin;
 if (argc != 4)
     usage("abspos: wrong number of args");
 XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp);
 if (argv[2][0] != '.')
     if (!myatoi(argv[2], &x))
  usage("abspos: invalid x pos: %s", argv[2]);
 if (argv[3][0] != '.')
     if (!myatoi(argv[3], &y))
  usage("abspos: invalid y pos: %s", argv[3]);
 XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
 XFlush(display);
    } else if (!strcasecmp(argv[1], "relpos")) {
 int x, y, tmp, x2, y2;
 Window fromroot, tmpwin;
 if (argc != 4)
     usage("relpos: wrong number of args");
 XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp);
 if (!myatoi(argv[2], &x2)) usage("relpos: invalid x pos: %s", argv[2]);
 if (!myatoi(argv[3], &y2)) usage("relpos: invalid y pos: %s", argv[3]);
 x += x2;
 y += y2;
 XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
 XFlush(display);
    } else if (!strcasecmp(argv[1], "get")) {
 int x, y, tmp;
 Window fromroot, tmpwin;
 if (argc != 2)
     usage("get: wrong number of args");
 XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp);
 printf("%d %d\n", x, y);
    } else {
 usage("invalid command: %s", argv[1]);
    }
    exit(0);
}