본문 바로가기

IT/Linux(Unix)

리눅스 프로그래밍 - 커널 소스 분석 ( 네트워크 기초 )

반응형

오랜만에 초심으로 돌아가 리눅스 프로그램을 까보았습니다. 사실 선생님 한분이 도와주셨어요. 네트워크 전공 이신지 네트워크 위주로 시작했습니다.


1. 리눅스 커널 소스 가져오기

The Linux Kernel Archives

kernel.org

$ wget으로 웹에서 데이터 가져옴


2. 커널 소스 태깅하기
$ make tags

3. iphdr : ip 프로토콜
struct iphdr {
__u8 ihl:4, // 길이 : 5*4 byte
version:4;
__u8 tos; // type of service - 현재 미사용
__be16 tot_len; // byte 단위, data length = tot_len -ihl*4
__be16 id; // 패킷을 나눴을 때 동일한 패킷임을 확인하는 Id
__be16 frag_off; // 패킷을 나눈 경우 순서 확인용, 위치값을 넣는다.*
__u8 ttl; // time to live 생존 타임, 루프 돌게 되는 경우 자동 폭파~
__u8 protocol; // 상위 레이어 명시
__sum16 check;
__be32 saddr;
__be32 daddr;
};

* frag_off를 순서로 기입한 것이 아니라 떨어진 위치를 기입한 이유가 무엇일까.
-> 최초에 패킷이 조각 난 후, 또 다시 조각 날 수도 있다. 이때 순서 값을 사용했다면 코드 더러워졌을 듯. 그냥 떨어진 거리, 위치로 하면 또 다시 위치 값을 넣어주면 그만이다.
-> NF도 frag_off에 존재한다. 0이면 마지막 패킷.

* ARP
IP는 알고, 상대편 Mac Addr를 모를때 전송하는 방법.
1. Mac 브로드캐스트
2. IP가 맞는 경우 응답
-> 관련 데이터(맵핑)를 계속 업데이트 하여 속도를 빠르게 함 $ arp -a

* Ip 라우팅
1. 직접 전달 - 동일 네트워크 안에서 전달
2. 간접 전달 - 나와 너가 서로 다른 네트워크, 여러 라우터를 통해서 전달 ( 가장 적은 hop을 가진 경로로.)

4. tcphdr : tcp 프로토콜
-> ip 프로토콜의 업그레이드 버전

struct tcphdr {
__be16 source; // my port num
__be16 dest; // your port num
__be32 seq;
__be32 ack_seq;
__u16 doff:4,
res1:4,
cwr:1, // 각 비트들이 유효한지 아닌지 알려주는 값들(아래들도)
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
__be16 window;
__sum16 check;
__be16 urg_ptr;
};

TCP는 유실이 없음 -> seq를 주기 때문에 가능. -> 3way handshaking통해 첫 seq를 주고 받음
window : 남은 버퍼 사이즈를 알려주는 용. 상대방은 이 만큼(윈도우크기)만 나에게 전달한다. tcp 수신버퍼가 busy 할 때 사용. 버퍼 유실을 막음.

5. udphdr

struct udphdr {
__be16 source;
__be16 dest;
__be16 len;
__sum16 check;
};

초간단.
tcp의 기능을 다 뺀 것이 udp, 단 빠르다.

6. ip addr setting - endian

인텔 - little endian ( 순서가 거꾸로 저장 됨 -> 현재 많이 사용)
IBM - big endian ( 정순으로 저장 -> 표준 )

인텔을 정순(big endian)으로 바꾸어줘야 한다.
#define htonl(ip) ((ip<<24)&0xff000000|(ip<<8)&0xff0000|(ip>>8)&0xff00|(ip>>24)&0xff)

7. IP addr conversion

Domain name -> 32bit : getthostbyname()
32bit -> domain name : gethostbyaddr()
dotted decimal -> 32bit : inet_addr(), inet_aton()
32bit -> dotted decimal -> inet_ntoa()

#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

extern int h_errno;

int main(int argc, char **argv)
{
    if (argc != 2 )
    {
        printf ("err arg");
        return 0;
    }
    int i;
    struct hostent *he;
    struct in_addr addr;
    he = gethostbyname(argv[1]);
    printf ("h_name : %s\n",he->h_name);
    for ( i = 0; he->h_aliases[i]; i++)
    {
        printf("[%d]h_aliases : [%s]\n",i,he->h_aliases[i]);
    }
    for ( i = 0; he->h_addr_list[i]; i++)
    {
        addr.s_addr = *(unsigned *)he->h_addr_list[i];
        printf("[%d]h_addr : [%s]\n",i,inet_ntoa(addr));
    }
    return 0;
}



참고

* 이진수 : 1111 = 10진수 15
* 16진수 : 0000 = 이진수 4자리 * 4개 즉, 이진수 0000 0000 0000 0000
* 8bit = 1byte
* port : 어플리케이션을 구분하게 해줌, 21 : ftp, 22 : ssh 등등. 다 확인하고 싶다면 /etc/services
* 책 : 유닉스 네트워크 프로그래밍 Vol.1 - 네트워크의 대가 리차드.(안에 소스가 good)
* http://www.kohala.com/ - 리차드 씨 추모 사이트. 소스가 존재

Kohala Software: Home Page

October 3, 1999 After being out of service for several weeks, I'm pleased to announce that www.kohala.com is back. The site has been relocated with minimal changes to the content. The material that was previously located at Rich's Home page (http://www.koh

www.kohala.com

* 네트워크에 대한 기본적인 내용들은 아래 사이트에 정리되어 있음.
1. 면접 단기 -> 네크워크
2. 네크워크

GitHub - youn16/ComputerScience: Computer Science Study Note

Computer Science Study Note. Contribute to youn16/ComputerScience development by creating an account on GitHub.

github.com

반응형