아래와 같은 코드를 짜서 실행중입니다.

(물론 실제 소스코드는 여기서 수정하여 사용중입니다.)

여기서 주석친 //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));

}