2008-09-16 17 views
19

Tôi là người khởi đầu lập trình C++/quản trị viên mạng, nhưng tôi có thể tìm hiểu cách thực hiện việc này nếu ai đó chỉ cho tôi đúng hướng. Hầu hết các hướng dẫn được thể hiện bằng cách sử dụng mã cũ mà không còn hoạt động vì một số lý do.Làm cách nào để tạo các gói RAW TCP/IP trong C++?

Vì tôi đang sử dụng Linux, tất cả những gì tôi cần là giải thích về cách viết ổ cắm Berkeley thô. Ai đó có thể cho tôi chạy nhanh không?

+1

Ổ cắm RAW rất phức tạp và có một chút khác biệt trên các hệ thống khác nhau. Tôi chỉ biết những người sử dụng chúng để mã hóa những kẻ đánh hơi (như 'wireshark') và một số chẩn đoán khá phức tạp. Họ chắc chắn không phải là một nơi tốt để bắt đầu học lập trình socket. Trong hầu hết các trường hợp "Tôi là một lập trình viên C++/quản trị mạng" có nghĩa là "tránh xa SOCK_RAW". –

+0

@ChuckKollars, tôi không đồng ý. Tôi nghĩ rằng học ổ cắm nguyên là một cách tuyệt vời để học C++, và đặc biệt là C. Sử dụng một thư viện là một điều, nhưng các ổ cắm thô với Linux là một trải nghiệm rất sâu sắc. C++ có thể làm rất nhiều điều độc đáo. Tôi nghĩ tránh được nỗi đau mà bạn ám chỉ là một sai lầm. – motoku

+0

Bạn có chính xác hệ thống nào? Việc triển khai socket "Raw" khác nhau đáng kể từ một hệ thống đến hệ thống tiếp theo, do đó những gì bạn học (thực sự chủ yếu là về hệ thống, chứ không phải về C++) không có ở nơi khác. –

Trả lời

5

Một nơi tốt để bắt đầu sẽ là sử dụng Asio là thư viện đa nền tảng (bao gồm Linux) tuyệt vời để liên lạc mạng.

+1

Bạn không bao giờ có thể thực hiện giao diện gói UDP hoặc hoạt động giống như gói TCP - các tiêu đề gói IP cho cả hai loại trừ lẫn nhau. –

13

Bắt đầu bằng cách đọc Beej's guide on socket programming. Nó sẽ mang lại cho bạn tốc độ làm thế nào để bắt đầu viết mã mạng. Sau đó, bạn sẽ có thể nhận được nhiều thông tin hơn từ việc đọc các trang của người đàn ông.

Hầu hết nội dung sẽ bao gồm việc đọc tài liệu cho thư viện yêu thích của bạn và hiểu biết cơ bản về các trang của người đàn ông.

1

Có rất nhiều tài liệu tham khảo về điều này (tất nhiên, cuốn sách của Stevens xuất hiện trong đầu), nhưng tôi thấy số Beej guide là cực kỳ hữu ích để bắt đầu. Đó là đủ thịt mà bạn có thể hiểu những gì đang thực sự xảy ra, nhưng nó đơn giản là nó không đưa bạn vài ngày để viết một 'hello world' udp client/server.

1

dễ dàng:

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

int socket(int protocolFamily, int Type, int Protocol) 
// returns a socket descriptor 

int bind(int socketDescriptor, struct sockaddr* localAddress, unsigned int addressLength) 
// returns 0 

... vv.

đó là tất cả trong sys/socket.h

3

Bạn làm điều này một cách chính xác mà bạn sẽ thường xuyên trong C, không có C++ cách cụ thể để làm điều này trong thư viện chuẩn.

Hướng dẫn tôi đã sử dụng để tìm hiểu điều này là http://beej.us/guide/bgnet/. Đó là hướng dẫn tốt nhất mà tôi tìm thấy sau khi nhìn xung quanh, nó đưa ra những ví dụ rõ ràng và giải thích tốt về tất cả các chức năng mà nó mô tả.

6

Đối với phụ TCP client:

Sử dụng GetHostByName để tra cứu tên dns sang IP, nó sẽ trả về một cấu trúc hostent. Hãy gọi máy chủ lưu trữ giá trị trả về này.

hostent *host = gethostbyname(HOSTNAME_CSTR); 

Điền cấu trúc địa chỉ socket:

sockaddr_in sock; 
sock.sin_family = AF_INET; 
sock.sin_port = htons(REMOTE_PORT); 
sock.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr; 

Tạo một ổ cắm và gọi kết nối:

s = socket(AF_INET, SOCK_STREAM, 0); 
connect(s, (struct sockaddr *)&sock, sizeof(sock)) 

Đối với máy chủ TCP dụng phụ:

Thiết lập một ổ cắm

Liên kết địa chỉ của bạn với ổ cắm đó bằng cách sử dụng liên kết.

Bắt đầu nghe trên ổ cắm đó với nghe

Gọi chấp nhận để có được một khách hàng được kết nối. < - tại thời điểm này, bạn sinh ra một chuỗi mới để xử lý kết nối trong khi bạn thực hiện một cuộc gọi khác để chấp nhận để có được ứng dụng khách được kết nối tiếp theo.

giao tiếp chung:

Sử dụng gửi và recv để đọc và viết giữa client và server.

Source code ví dụ về socket BSD:

Bạn có thể tìm thấy một số mã ví dụ tốt về điều này tại wikipedia.

Đọc thêm:

tôi khuyên bạn nên this bookthis online tutorial:

alt text

4:

+2

gethostbyname không còn được sử dụng cho một dự án mới: nó được gắn với phiên bản IP (IPv4). Bây giờ, phần còn lại của địa chỉ IPv4 là [nhanh chóng cạn kiệt] (http://www.potaroo.net/tools/ipv4/index.html), bạn thực sự nên sử dụng getaddrinfo là phiên bản độc lập (làm việc với v4 và v6) . – bortzmeyer

1

Poster, xin vui lòng làm rõ câu hỏi của bạn.

Hầu như tất cả các phản hồi dường như nghĩ rằng bạn đang yêu cầu hướng dẫn về ổ cắm; Tôi đọc câu hỏi của bạn để có nghĩa là bạn cần phải tạo ra một ổ cắm nguyên có khả năng gửi các gói tin IP tùy ý. Như tôi đã nói trong câu trả lời trước của tôi, một số hệ điều hành hạn chế việc sử dụng các ổ cắm thô.

http://linux.die.net/man/7/raw "Chỉ các quy trình có ID người dùng hiệu quả là 0 hoặc khả năng CAP_NET_RAW mới được phép mở ổ cắm thô".

10

Đối với người mới bắt đầu, sẽ hữu ích nếu bạn làm rõ ý mình là "thô". Theo truyền thống, điều này có nghĩa là bạn muốn tạo tất cả tiêu đề lớp 4 (tiêu đề TCP/UDP/ICMP ...), và có lẽ một số tiêu đề IP của riêng bạn. Đối với điều này, bạn sẽ cần nhiều hơn hướng dẫn của beej đã được đề cập đến nhiều của tôi ở đây rồi. Trong trường hợp này, bạn muốn các ổ cắm IP thô thu được bằng cách sử dụng đối số SOCK_RAW trong lời gọi tới socket (xem http://mixter.void.ru/rawip.html đối với một số vấn đề cơ bản).

Nếu những gì bạn thực sự muốn chỉ để có thể thiết lập kết nối TCP tới một số máy chủ từ xa như cổng 80 trên stackoverflow.com, thì có thể bạn không cần ổ cắm "thô" và hướng dẫn của beej sẽ phục vụ bạn tốt .

Để có tài liệu tham khảo có thẩm quyền về chủ đề này, bạn nên thực sự chọn Lập trình mạng Unix, Tập 1: API mạng ổ cắm (Phiên bản thứ 3) của Stevens et al.

1

Đọc Unix Network Programming bởi Richard Stevens. Đó là điều phải. Nó giải thích cách nó hoạt động, cung cấp cho bạn mã, và thậm chí cung cấp cho bạn các phương thức trợ giúp. Bạn có thể muốn xem một số sách khác của mình. Advanced Programming In The Unix Enviernment là phải cho lập trình cấp thấp hơn trong Unix là chung. Tôi thậm chí không làm công cụ trên ngăn xếp Unix nữa, và stuf từ những cuốn sách này vẫn giúp tôi viết mã.

1

Libpcap sẽ cho phép bạn tạo các gói hoàn chỉnh (lớp 2 đến lớp 7) và gửi chúng qua dây. Như vui vẻ như âm thanh đó, có một số cảnh báo với nó. Bạn cần tạo tất cả các tiêu đề thích hợp và tự mình kiểm tra tất cả. Tuy nhiên, Libnet có thể giúp bạn thực hiện điều đó.

Nếu bạn muốn thoát khỏi hồ sơ lập trình C++, có scapy cho python. Nó làm cho nó tầm thường để thủ công và truyền các gói TCP/IP.

2

Tôi đã phát triển libtins trong năm qua.Đó là một thư viện crafting và sniffing.

Trừ khi bạn muốn phát minh lại bánh xe và thực hiện mọi giao thức nội bộ của giao thức, tôi khuyên bạn nên sử dụng một số thư viện cấp cao hơn mà đã làm điều đó cho bạn.

Các vấn đề liên quan