udp raw socket progrmaing 질문드립니다.
글쓴이: sysmoon / 작성시간: 일, 2005/08/28 - 12:11오후
개발 환경은 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;
}
Forums:


댓글 달기