udp raw socket progrmaing 질문드립니다.

sysmoon의 이미지

개발 환경은 linux 2.4 버젼입니다.
현재 내 아이피가 없는 상황에서 udp broadcasting을 할려고 합니다. setup 해서 ip 설정을 1.1.1.1 static 으로 해주고 아래 소스를 실행시키면 broadcasting이 되는데 setup에서 ip자동할당으로 선택을 하고(DHCP) 하면 network unreachable 이 됩니다. 현재 내 아이피가 없는 상황에서 udp broadcastingd을 할 수 있는 방법을 알려주세요..

소스는 아래와 같습니다..

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

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <netinet/in_systm.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <netinet/tcp.h>

#include <string.h>  //memset()
#include <unistd.h>

//-------  함수의 헤더를 선언한다.
// in_cksum --Checksum routine for Internet Protocol family headers (C Version)       

unsigned short in_cksum(unsigned short *addr, int len);

void ip_gen(char *packet,
                  unsigned char protocol,
                  struct in_addr saddr,           
                  struct in_addr daddr,
                  unsigned short length) ;                       

void udp_gen(char *packet,
             unsigned short sport,
             unsigned short dport,
             unsigned short length);
                
#define MESG "Beauty and Beast/ttongfly@hotmail.com"
#define MESG_LENGTH sizeof(MESG)

int main(int argc,char *argv[])
{
  unsigned char packet[
          sizeof(struct iphdr) +
        sizeof(struct udphdr) +
        MESG_LENGTH];
  struct in_addr saddr, daddr;  // 근원지 주소와 목적지 주소
  unsigned short sport, dport;  // 근원지 포트와 목적지 포트
  struct sockaddr_in mysocket;  // 소켓을 생성 
  struct udphdr *udphdr;        // UDP 헤더 생성 
  int sockd, on = 1;                // 소켓 기술자 
  
  if(argc < 5)  {
    fprintf(stderr,"usage: %s source_port source_address dest_port dest_address\n",
            argv[0]);
    exit(1);
  }
  
  sport = (unsigned short)atoi(argv[1]);
  saddr.s_addr = inet_addr(argv[2]);

  dport = (unsigned short)atoi(argv[3]);
  daddr.s_addr = inet_addr(argv[4]);
  
  //소켓을 생성한다.  socket(도메일 페밀리, 소켓 타입,프로토콜);
  if((sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0)  {
    perror("socket");
    exit(1);
  }
  
  //소켓 옵션을 변경 setsockopt(소켓기술자,프로토콜,옵션네임,옵션버퍼,사이즈);
  //소켓을 IP 프로토콜로 변경 ... 근뎅.... 왜 변경하징.. 몰것당..??
  if(setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0)  {
    perror("setsockopt");
    exit(1);
  }
  //IP를 생성   
  ip_gen(packet,IPPROTO_UDP,saddr,daddr,sizeof(packet));

  udphdr = (struct udphdr *)(packet + sizeof(struct iphdr));

  memset((packet+sizeof(struct udphdr)+sizeof(struct iphdr)),
         '0',MESG_LENGTH);  /* Just zero out the message content. */

  strcpy(packet+sizeof(struct iphdr) + sizeof(struct udphdr),MESG);
          
  udp_gen((char *)udphdr,sport,dport,(sizeof(struct udphdr) + MESG_LENGTH));

  memset(&mysocket,'\0',sizeof(mysocket));
  
  mysocket.sin_family = AF_INET;
  mysocket.sin_port = htons(dport);
  mysocket.sin_addr = daddr;
  
  if(sendto(sockd,&packet,sizeof(packet),0x0,(struct sockaddr *)&mysocket,
            sizeof(mysocket)) != sizeof(packet))  {
    perror("sendto");
    exit(1);
  }
  
  exit(0);
}


// in_cksum -- Checksum routine for Internet Protocol family headers (C Version)    
unsigned short in_cksum(unsigned short *addr,int len)
{
        register int sum = 0;                                                   
        u_short answer = 0;                                                     
        register u_short *w = addr;                                             
        register int nleft = len;                                               
                                                                                
        /*                                                                      
         * Our algorithm is simple, using a 32 bit accumulator (sum), we add    
         * sequential 16 bit words to it, and at the end, fold back all the     
         * carry bits from the top 16 bits into the lower 16 bits.              
         */                                                                     
        while (nleft > 1)  {                                                    
                sum += *w++;                                                    
                nleft -= 2;                                                     
        }                                                                       
                                                                                
        /* mop up an odd byte, if necessary */                                  
        if (nleft == 1) {                                                       
                *(u_char *)(&answer) = *(u_char *)w ;                           
                sum += answer;                                                  
        }                                                                       
                                                                                
        /* add back carry outs from top 16 bits to low 16 bits */               
        sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */       
        sum += (sum >> 16);                     /* add carry */                 
        answer = ~sum;                          /* truncate to 16 bits */       
        return(answer);                                                         
}                        

// in_gen -- IP 데이터 그램을 해더를 생성한다.
void ip_gen(char *packet,
                 unsigned char protocol,
                 struct in_addr saddr,           
                 struct in_addr daddr,
                 unsigned short length)                         
{                                                                               

#define IPVERSION 4
#define DEFAULT_TTL 60  // Just hard code the ttl in the ip header.

  struct iphdr *iphdr;

  iphdr = (struct iphdr *)packet;
  //void  *memset(void *s,int c, size_t n);
  // 일정한 문자 c로 n길이 만큼 s를 채운다.
  memset((char *)iphdr,'\0',sizeof(struct iphdr));

  iphdr->ihl = 5;                                                              
  iphdr->version = IPVERSION;                                                   

  iphdr->tot_len = htons(length);                                               
  iphdr->id = htons(getpid());                                                  
  iphdr->ttl = DEFAULT_TTL;                                                     
  iphdr->protocol = protocol;                                                   
  iphdr->check = (unsigned short)in_cksum((unsigned short *)iphdr,              
                                          sizeof(struct iphdr));                
  iphdr->saddr = saddr.s_addr;   
  iphdr->daddr = daddr.s_addr;                                                  

  return;
} 


void udp_gen(char *packet,
             unsigned short sport,
             unsigned short dport,
             unsigned short length)
{
  struct udphdr *udp;

  udp = (struct udphdr *)packet;
  udp->source = htons(sport);
  udp->dest = htons(dport);
  udp->len = htons(length);
  udp->check = 0;

  return;
}

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.