레이블이 upnp인 게시물을 표시합니다. 모든 게시물 표시
레이블이 upnp인 게시물을 표시합니다. 모든 게시물 표시

2009년 10월 1일 목요일

벨킨 공유기 UPnP AddPortMapping 문제

upnp 를 위해 덩치큰 라이브러리를 가져다 쓰지 않고 직접 짰는데 이게 테스트에 쓴 다른 공유기들(Intel UPnP SDK  기반) 에선 문제 없지만 벨킨 공유기에서는 문제가 생기더라.

결론만 적자면 내가 평소 http 프로토콜을 직접 짜야 할 경우 보통 1.0 기반으로 만드는 편인데 이번에도 역시 1.0 기반으로 리퀘스트를 했고 벨킨 공유기는 이걸 에러로 취급해준것.

SOAP 이 HTTP 1.1 위에서 돌아야만 했던가? 흠 지금껏 이런 문제는 본적이 없는데
나중에 이것좀 찾아보자.


어 참고로 지금 UPnP 로 포트매핑 하는거 대강 순서나 적어둘까
  1. 디스커버리
  2. 찾았으면 디스크립션 읽어오고
  3. 그중에서 컨트롤 URL 을 파싱해서
  4. 먼저 DeletePortMapping 으로 이전 포트포워딩 정보가 있으면 지워주고
  5. AddPortMapping 으로 포트매핑 추가
음. 몇몇 공유기는 AddPortMapping 을 반복해서 불러도, 즉 기존에 뚫린거 또 뚫어 달라고 해도 별말없이 뚫어주는놈도 있고 어떤놈은 이미 뚫었다고 에러주는 경우도 있다. 따라서 뚫기전에 뚫은것 지워달라는 패킷을 추가한것.

정석대로라면 먼저 뚫어보고 이미 뚫려있다고 응답해오면 상황판단을 해서 뚫은것 지우고 다시 뚫거나 등등의 처리를 해야 하겠지만 흠. 일단 걍 막무가내로 뚫어버렸다.


아..
문제가 생긴 공유기는 벨킨 F5D8236-4 v2 였다.
지금은 꺼놔서 펌웨어 버전은 못적겠군.







2008년 11월 11일 화요일

UPNP 로 공유기 찾고 포트매핑 추가하기. lisp(SBCL 전용) 예제

아 시바 정말 귀찮네.
이넘들이 망할 soap 을 쓰는 바람에 C 로 짜긴 귀찮은 존재구나.
libupnp 까지 붙이고 싶지는 않고.. 내가 지금 하려는거에 굳이 soap 결과를 파싱까지 하고 싶지는 않고.. 그래서 간단히 upnp 기능만 돌려보는 테스트 스크립트를 만들어봤다. slime 상에서 여러가지 경우로 테스트 해보기 위해서 lisp 으로 만들었고 lisp 으로 udp 쏘는건 처음이라 소스를 적어둔다.

아래 소스 로딩하고 (discover-gateway) 부르면 같은 망 내의 공유기를 찾아서(하나라고 가정) control url 을 *control-url* 에 담기게 되고, 그상태에서 (test/blahblah) 함수들을 적절히 불러가면서 공유기가 무슨짓을 하는지 보면 된다.

그런데 포트매핑을 추가한상태에서 또 추가한다거나, 다른 어플리케이션이 이미 포트 뚫어논 상태에서 내가 같은 포트로 뚫으려고 한다거나.. 내 어플이 뒤지고 다시 깨서 이미 뚫린걸 다시 뚫으려고 한다거나.. 내가 뚫어논걸 다른 색히가 가로챈다거나.. 음.. 테스트할 경우의수가 좀 많구나... 아무래도 문서를 읽어봐야 할거 같군. 걍 미리 만들어둔 xml 뿅 쏘고 넘길려고 했는데 그리 쉽게는 안되겠네?? 지금 아래 구현체는 upnp 하나도 모르고 그냥 빗토런트의 upnp 구현체를 보고 따라친거 뿐인데 이정도 테스트 만으로 넘어가긴 좀 그렇구나.

문서좀 읽고 libupnp 를 검토해봐야겠구나.. 후랄.

아 그리고 당연한 말이지만 아래 코드는 테스트용으로 만든거라 여러 가정을 깔고 있고 환경이 바뀌면 안돌아갈수 있다.. 나중에 기억못할테니 적어두자면.. 로컬 IP 가 *local-ip-address* 에 상수로 박혀있고 udp 쏘고 소켓 읽는 부분이 블러킹으로 리딩하기 때문에 만약 같은 망 내에 공유기가 없으면 마냥 블러킹 되고.. find-location-blahblah 함수내의 정규식 패턴에 ^M 이 \r 제어문자 라는거.. 이맥스에서는 C-Q C-M 으로 입력이 가능한데 다른 에디터는 모르겠다. 나중에 다시 필요하면 여기서 긁어붙일텐데 이때 ^M 주의하자.



소스보기..





2008년 11월 5일 수요일

upnp 로 공유기 디스커버리 하는 예제 python

전에도 잠깐 해본적 있는데 다시 읽어보니 병신같이 적어뒀네...

# -*- coding: utf-8 -*-
#
# 헐 사무실에 공유기가 안보여서 집에 원격접속해서 간단히 upnp 테스트
# 코드를 돌려봤다. 걍 버리긴 그렇고 해서 적어둔다.
#
from socket import socket,AF_INET,SOCK_DGRAM

s = socket(AF_INET, SOCK_DGRAM)
discovery = "M-SEARCH * HTTP/1.1\r\n" + \
"Host:239.255.255.250:1900\r\n" + \
"ST:urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n" + \
"Man:\"ssdp:discover\"\r\n" + \
"MX:3\r\n" + \
"\r\n"
if s.sendto(discovery, ("239.255.255.250", 1900)) != len(discovery):
print "send error"
else:
print "send done"

print "try recvfrom"
(data,addr) = s.recvfrom(8192)
s.close()

print addr
print data

디스크립션을 보려면 위의 응답으로 떨어지는 location 에 그냥 브라우저 열고 GET 때려보면 된다.
SOAP 으로 제어하는건... 이전 위키에 있으니 생략.. 음 혹시나 테스트코드를 또 만들게되면 적어두자.