아래와 같은 코드를 짜서 실행중입니다.
(물론 실제 소스코드는 여기서 수정하여 사용중입니다.)
여기서 주석친 //iphdr -> daddr = dest_address.s_addr; 부분이 없더라도 값이 자동으로 할당이 되며
값을 변경하더라도 변경한 줄에서만 변경이 된 후 다시 saddr의 값으로 돌아가버립니다.
뭐가 잘못되었고 어떻게 해야 할까요?
P.S.) 어느채널이 이 주제와 맞는 채널인지 모르겠어서 컴공채널과 코딩채널 양쪽에 작성합니다
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
struct hypohdr{
u_int32_t saddr; // 발신자의 IP.
u_int32_t daddr; // 수신자의 IP.
u_int8_t useless; // 아직 사용되지 않음.
u_int8_t protocol; // 프로토콜.
u_int16_t tcplength; // TCP 헤더의 길이.
};
unsigned short in_cksum(u_short *addr, int len)
{
int sum=0; // 총 합계.
u_short *w=addr; // 인자로 받은 addr의 주소를 저장.
u_short answer=0; // 최종적으로 리턴되는 값.
// len만큼 sum에 *w의 값을 더함.
while (len > 1){
sum += *w++;
len -= 2;
}
// len이 홀수라서 값이 남을 경우 추가로 더해줌.
if (len == 1){
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff); // 상위 16비트와 하위 16비트를 더함.
sum += (sum >> 16); // carry bit 값을 더함.
answer = ~sum; // 값을 반전 시킴.
return(answer); // 리턴.
}
void main()
{
u_char packet[100];
int raw_socket;
int err_buf = 1;
struct iphdr* iphdr;
struct tcphdr* tcphdr;
struct in_addr source_address, dest_address;
struct sockaddr_in address;
struct hypohdr *hypo_header;
source_address.s_addr = inet_addr("192.168.1.123");
dest_address.s_addr = inet_addr("192.168.111.100");
raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
setsockopt( raw_socket, IPPROTO_IP, IP_HDRINCL, (char*)&err_buf, sizeof(err_buf));
// ip헤더가 tcp헤더의 앞에 있으므로 20바이트를 비워둔다.
tcphdr = (struct tcphdr*)(packet + 20);
// tcp헤더 초기화
memset((char*)tcphdr, 0, 20);
// ip헤더 생성 및 초기화
iphdr = (struct iphdr*)packet;
memset((char*)iphdr, 0, 20);
//가상 헤더 생성
hypo_header = hypo_header = (struct hypohdr *)((char*)tcphdr-sizeof(struct hypohdr));
hypo_header -> saddr = source_address.s_addr;
hypo_header -> daddr = dest_address.s_addr;
hypo_header -> protocol = IPPROTO_TCP;
hypo_header -> tcplength = htons( sizeof(struct tcphdr) );
// 수,발신자 포트 및 seq, ack 임의지정
tcphdr -> source = htons(777);
tcphdr -> dest = htons(12345);
tcphdr -> seq = htonl(92929292);
tcphdr -> ack_seq = htonl(12121212);
tcphdr -> doff = 5;
tcphdr -> syn = 1;
tcphdr -> window = htons(512);unsigned short in_cksum(u_short *addr, int len);
tcphdr -> check = in_cksum((u_short*)hypo_header, sizeof(struct hypohdr) + sizeof(struct tcphdr));
iphdr -> version = 4;
iphdr -> ihl = 5;
iphdr -> protocol = IPPROTO_TCP;
iphdr -> tot_len = 40;
iphdr -> id = htons(777);
iphdr -> ttl = 60;
iphdr -> saddr = source_address.s_addr;
//iphdr -> daddr = dest_address.s_addr;
iphdr -> check = in_cksum((u_short*)iphdr, sizeof(struct iphdr));
printf("%s : %s\n", inet_ntoa(source_address), inet_ntoa(dest_address));
//소켓 패킷 받을사람 지정
address.sin_family = AF_INET;
address.sin_port = htons(12345);
address.sin_addr.s_addr = inet_addr("192.168.111.100");
//패킷 전달
sendto(raw_socket, &packet, sizeof(packet), 0x0, (struct sockaddr*)&address, sizeof(address));
}