[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
20/04/2012 14:26:41 (+0700) | #1 | 261762 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Chuyện là thế này, hiện tại mình đang lập trình mạng cho chip set wifi modern là ZG2100 bằng ngôn ngữ C, mọi chuyện kết nối đã bình thường, nhưng IP mình đang sử dụng để thiết lập là IP tĩnh ngoài vùng DHCP.
Nay mình mày mò cách update lên cho em nó chạy được với DHCP Server. Tiến trình DHCP : Client gửi DISCOVER --> Server gửi lại Client OFFER --> Client xử lý OFFER gửi lại server gói REQUEST --> Server gửi gói ACK cho client để đồng ý..
Tiến trình là như vậy nhưng mình chỉ đến được giai đoạn đầu tiên. Broadcast gói tin DISCOVER packet, nhưng chờ mãi chả thấy DHCP server của mình trả lời.
Mình dùng Wireshark bắt gói tin thì thấy rất bình thường checksum điều đúng cả và rất giống với các gói tin DHCP khác.
Anh em nào có kinh nghiệm xin góp ý cho mình.
Xin cám ơn. |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
21/04/2012 01:14:29 (+0700) | #2 | 261785 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
Mấy cái hình không biết sao mình không xem đc, bạn cho lại mấy cái hình hoặc tóm bằng wireshark rồi tải lên mediafire đc không ?. |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
21/04/2012 12:57:31 (+0700) | #3 | 261792 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
chiro8x wrote:
Mấy cái hình không biết sao mình không xem đc, bạn cho lại mấy cái hình hoặc tóm bằng wireshark rồi tải lên mediafire đc không ?.
không biết sao mình nhúng hình trực tiếp vào không được, web không hiển thị nên mình để link.
http://www.mediafire.com/?ycxa459sng6ggu3
cái này là gói tin bắt được bằng WireShark, gồm 4 gói DHCPDISCOVER, (filter = bootp). Mình đã thử gửi DISCOVER với delay là 1 giây, 2 giây, 4 giây, 8 giây, nhưng vẫn không thấy DHCPOFFER từ server.
Bạn xem giúp mình.
Thanks đã reply.. |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 09:21:15 (+0700) | #4 | 261819 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
Mình xinh lỗi đã trả lời bạn chậm trể thế này hì hì . Giờ mình xin đi thẳng vào vấn đề nhé.
Như bạn thấy là gói tin của bạn field checksum của gói UDP, tầng transport đã bị lỗi rồi.
Code:
Checksum: 0xa4a8 [incorrect, should be 0xe0a8 (maybe caused by "UDP checksum offload"?)]
Check sum bị lỗi nên nó sẽ không được xử lí đâu, bạn thấy gói tin bình thường là do bạn chưa bật chế độ kiểm tra checksum với UDP packet.
Nhìn vào độ sai lệch checksum là 0xa4a8 và 0xe0a8 thì bị tính nhầm 1 byte thôi ( mình đoán thôi nhé ). Về việc tính toán checksum bạn có thể tìm hiểu ở đây.
/hvaonline/posts/list/41759.html
Mà network interface của bạn được cấp IP chưa ?.
|
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 09:35:45 (+0700) | #5 | 261820 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
P/S: may mà bồ gửi mấy cái "gói" này lên chứ bồ mà gửi mấy cái hình thì tớ cũng khóc thôi. Bạn lập trình với thư viện gì ? libpcap hay socket (rawsocket) ?. |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 10:33:34 (+0700) | #6 | 261826 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Oh, thì ra là vậy, đúng là mình không bậc kiểm tra checksum trong wireshark, nên mấy gói tin của mình trông rất bình thường nhìn như không bị lỗi gì. Cám ơn bạn đã kiểm tra giúp mình, chắc mình phải sửa lại hàm checksum rồi. Chipset của mình chưa được gán ip, nếu muốn gán ip tĩnh thì vẫn được nhưng mình muốn cho nó hoạt động được với dhcp.
Mình không sử dụng thư viện nào cả, mọi hàm mình tự viết hết do mấy thư viện kia không thể hoạt động được với chip của mình. Một lần nữa cám ơn bạn nha. Mình sẽ sửa lại checksum xong rồi sẽ report lại kết quả với bạn. Thanks |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 10:41:57 (+0700) | #7 | 261828 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
=m=! bạn nói mình không hiểu gì lắm . Thế bạn đang lập trình driver à ?. Cho mình xem source với please. |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 10:54:11 (+0700) | #8 | 261829 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Mình đang viết driver cho chipset wifi, các phần ICMP, ARP, đã xong còn phần DHCP này thôi, nhưng mới viết được mỗi hàm discover này thì bị lỗi rồi.hihi, về soucre code thì mình sẽ gửi cho bạn một phần vào ngày mai. Mình đang online bằng tablet nên không có mang theo dữ liệu. |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 10:57:43 (+0700) | #9 | 261830 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
He..he...giàu có thế ! tớ nghèo lắm thời buổi này vẫn xài con dual core cà tàng . Có gì cậu mail vào chiro8x@gmail.com nhé . Rất mong có một miếng bánh từ cậu ^^!. Mình xem nếu optimize đc mình sẽ cố cuối tuần vui vẻ nha bồ tèo. |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
22/04/2012 19:03:57 (+0700) | #10 | 261853 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Mình sẽ gửi cho bạn hàm dhcp discover do tự mình viết rất đơn giản và thích hợp với chipset. Skype của mình là ncphuc99. Hi vọng được tham khảo một vài ý kiến của bạn. |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 07:31:54 (+0700) | #11 | 261876 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
chiro8x wrote:
Check sum bị lỗi nên nó sẽ không được xử lí đâu, bạn thấy gói tin bình thường là do bạn chưa bật chế độ kiểm tra checksum với UDP packet.
Bạn nói bậc chế độ kiểm tra checksum với UDP Packet, như thế này đúng không, máy mình đã bậc lên rồi mà, sao vẫn không phát hiện lỗi checksum UDP vậy ?
/gnp.muskcehc/048/segami-ym/otohp/su.kcahsegami//:ptth
Vào Network connection -> sau đó config lại card mạng UDP Checksum offload (IPv4) và Enable lên đúng không ?
|
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 09:40:27 (+0700) | #12 | 261894 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
Đó là bạn tuỳ chỉnh cái checksum offload rồi.
Để có thể thấy packet bị lỗi checksum như mình làm bạn phải làm theo các bước sau:
WireShark > Edit > Preferences > Tree view > Protocol > UDP
Tíc vào check box.
Validate the UDP check sum if possible [x] |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 12:59:57 (+0700) | #13 | 261902 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Okie, mình đã bậc được mode checksum UDP.
Lay hoay sửa lại hàm checksum nhưng sao chạy mãi vẫn bị lỗi checksum.
Đây là hàm checksum của mình.
Code:
/******************************************************************************
* check sum
******************************************************************************/
unsigned int checksum(unsigned char *rxtx_buffer, unsigned int len, unsigned char type)
{
//type 0 = ip
// 1 = udp
// 2 = tcp
unsigned long sum = 0;
if (type ==1){
sum+= 17; // ip protocol = UDP
sum+= len - 8; // len - ip addr len
}
if (type == 2){
sum+= 6;// ip protocol = TCP
sum+= len - 8;
}
while(len>1)
{
sum += 0xFFFF & (*rxtx_buffer<<8|*(rxtx_buffer+1));
rxtx_buffer+=2;
len-=2;
}
if (len)
{
sum += (0xFF & *rxtx_buffer)<<8;
}
while (sum>>16)
{
sum = (sum & 0xFFFF)+(sum >> 16);
}
return( (unsigned int) sum ^ 0xFFFF);
}
Và đây là code gọi hàm checksum. packet len là : 313 bytes => udp len = 313 - 34 = 279 bytes.
//set UDP checksum
ck=checksum( &buf[26],8 + 279,1);// 1 : UDP type
buf[40]=ck>>8; // udp check sum hight byte
buf[41]=ck& 0xff;//udp check sum low byte |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 13:02:57 (+0700) | #14 | 261903 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Okie, mình đã bậc được mode checksum UDP.
Lay hoay sửa lại hàm checksum nhưng sao chạy mãi vẫn bị lỗi checksum.
Đây là hàm checksum của mình.
Code:
/******************************************************************************
* check sum
******************************************************************************/
unsigned int checksum(unsigned char *rxtx_buffer, unsigned int len, unsigned char type)
{
//type 0 = ip
// 1 = udp
// 2 = tcp
unsigned long sum = 0;
if (type ==1){
sum+= 17; // ip protocol = UDP
sum+= len - 8; // len - ip addr len
}
if (type == 2){
sum+= 6;// ip protocol = TCP
sum+= len - 8;
}
while(len>1)
{
sum += 0xFFFF & (*rxtx_buffer<<8|*(rxtx_buffer+1));
rxtx_buffer+=2;
len-=2;
}
if (len)
{
sum += (0xFF & *rxtx_buffer)<<8;
}
while (sum>>16)
{
sum = (sum & 0xFFFF)+(sum >> 16);
}
return( (unsigned int) sum ^ 0xFFFF);
}
Và đây là code gọi hàm checksum. packet len là : 313 bytes => udp len = 313 - 34 = 279 bytes.
Code:
//set UDP checksum
ck=checksum( &buf[26],8 + 279,1);// 1 : UDP type
buf[40]=ck>>8; // udp check sum hight byte
buf[41]=ck& 0xff;//udp check sum low byte
Lúc này kết quả tính được là checksum = 0x4a48 = 19016 trong khi đó wireshark báo lỗi và trả về kết quả là "Should be 0x4a47 = 19015" chỉ sai 1 đơn vị.
Không biết sai ở chổ nào mong bạn xem giúp mình. Thanks. |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 18:14:32 (+0700) | #15 | 261913 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
Mình chỉ đưa gợi ý cho bạn thôi ! Giờ mình lười táy máy quá.
Dây là pseudo header mà tớ đã trình bày trong bài của tớ.
Code:
struct pseudo_header
{
unsigned int s_addr;
unsigned int d_addr;
char reserved;
unsigned char protocol;
unsigned short length;
};
Mình không thấy bạn tính cái reserved & length ở đâu cả.
Code:
sum+= 17; // ip protocol = UDP
sum+= len - 8; // len - ip addr len
Như mình nói trước đó là có khả năng bạn tính thiếu 1 byte. Trong lập trình gọi là lỗi hụt một, về cơ bản đáng ra bạn tính toán tới n như bạn dừng lại ở n - 1. Bạn thử tăng len (unsigned int len) lên 1 hoặc giảm 1 xem có gì thay đổi không. Nếu bạn test thử và luôn cho kết quả là thiếu 1 thì bạn cộng thêm cho nó trước khi return (giải pháp tình thế thôi).
Code:
chổ này tớ thấy người ta thường khai báo nó với kiểu là size_t hơn là unsigned int.
|
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 18:40:30 (+0700) | #16 | 261915 |
TQN
Elite Member
|
0 |
|
|
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
|
|
Trời quơi, viết code được như vậy mà không biết debug, step, trace à ? Xem bị tràn số, sai thứ tự ưu tiên ở đâu. Chả lẽ cứ run là xong à ? |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 19:00:03 (+0700) | #17 | 261919 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Cám ơn chiro8x đã xem qua code của mình. Mình sẽ tiếp tục sửa xem sao.
TQN wrote:
Trời quơi, viết code được như vậy mà không biết debug, step, trace à ? Xem bị tràn số, sai thứ tự ưu tiên ở đâu. Chả lẽ cứ run là xong à ?
Bạn ah, mình lập trình cho chip làm gì có tool debug và trace hả bạn bạn biết IDE ICC AVR không? Mình đang dùng nó để viết cho chip AVR. Cách debug biến nhanh nhất là hiển thị lên màn hình LCD 2 line bé xíu.
|
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 19:15:36 (+0700) | #18 | 261921 |
TQN
Elite Member
|
0 |
|
|
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
|
|
Tại sao không mang đoạn code checksum function đó qua PC, Linux hay Windows, build 1 tiny app để test, debug thử code mình có đúng không chưa ?
Bất cứ các hàm nào có liên quan tới các phép toán modify trên bit, tui cũng phải debug, đưa ra 3 test case: bình thường, tràn trên, tràn dưới hết. Tại sao lại sai +1 ? while của bạn đúng chưa ?
Vd nhé, bạn hãy nhìn kỹ đoạn code sau của bạn, bạn có hiểu nó làm theo thứ tự nào không, làm cái gì không ? Cần quái gì mà code phải cho cao siêu, khó hiểu, rắm rối. Cứ viết rõ ràng, tường minh ra, cũng bao nhiêu code sau khi được compile thôi, còn dể bảo trì, nâng cấp, fix bug nữa.
Code:
while(len>1)
{
sum += 0xFFFF & (*rxtx_buffer<<8|*(rxtx_buffer+1));
rxtx_buffer+=2;
len-=2;
}
if (len)
{
sum += (0xFF & *rxtx_buffer)<<8;
}
while (sum>>16)
{
sum = (sum & 0xFFFF)+(sum >> 16);
}
Xor, shiff, or, and tá lã âm binh. Em giờ mà đọc đoạn code này thì em phải mở "heo" của C ra đọc lại, vừa đọc, vừa dò. Viết lại đi bạn ơi.
Đó là phương diện read code, về phương diện optimize code, em sẽ không cho đại ca dùng *rxtx_buffer tá lã vậy đâu. Em hỏi nhé, tại sao đại ca không khai báo:
Code:
int c0 = rxtx_buffer[0]; // thay vì *rxtx_buffer
int c1 = rxtx_buffer[1]; // thay vì *(rxtx_buffer + 1);
Cái nào dể đọc, dể bảo trì hơn ? Sau đó muốn inc rxtx_buffer thì cứ inc. Vì * <=> []
Sau khi hàm của ta đã chạy đúng, nếu có time, chúng ta mới optimize về độ ngắn của function. Cái này không cần thiết lắm. Em đã từng viết những function 20 dòng, chạy nhanh gấp trăm lần những đoạn code 5 dòng.
Vài lời nói thẵng, mong bạn đừng giận. Em mắc cái bệnh review code của coder # quen rồi ! |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 19:31:22 (+0700) | #19 | 261922 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
chiro8x wrote:
Code:
sum+= 17; // ip protocol = UDP
sum+= len - 8; // len - ip addr len
Như mình nói trước đó là có khả năng bạn tính thiếu 1 byte. Trong lập trình gọi là lỗi hụt một, về cơ bản đáng ra bạn tính toán tới n như bạn dừng lại ở n - 1. Bạn thử tăng len (unsigned int len) lên 1 hoặc giảm 1 xem có gì thay đổi không. Nếu bạn test thử và luôn cho kết quả là thiếu 1 thì bạn cộng thêm cho nó trước khi return (giải pháp tình thế thôi).
Code:
Thanks Chiro nhiều lắm. Mình sửa lại chỉ cần cộng thêm 1 byte reserved và kết quả em server DHCP đã trả lời OFFER cho mình.
Code:
if (type ==1){
sum+= 17; // ip protocol = UDP
sum+= len - 8; // len - ip addr len
sum+=1;
}
Đây là link packet của mình đã DISCOVER thành công.
http://www.mediafire.com/?h2eva1hccogb0ob
Giờ bước tiếp theo chỉ là đơn giản xử lý gói tin e nó trả về thôi. |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 19:34:56 (+0700) | #20 | 261924 |
TQN
Elite Member
|
0 |
|
|
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
|
|
Hì hì, lại workaround mà không hiểu hết vấn đề rồi. Tối kỵ trong nghề coder.
sum += 1; // comment vô đây giùm tui cái, sau này thằng nào đọc, bảo trì mà hiểu được, why ? |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 20:08:51 (+0700) | #21 | 261928 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
TQN wrote:
Hì hì, lại workaround mà không hiểu hết vấn đề rồi. Tối kỵ trong nghề coder.
sum += 1; // comment vô đây giùm tui cái, sau này thằng nào đọc, bảo trì mà hiểu được, why ?
Hì hì ! anh TQN có nhiều kinh nghiệm mà chia sẽ có chút chút hà. Đúng là một người lập trình cần tập cho mình những thói quen tốt, trình bày code của mình mạch lạc như việc hành văn và sử dụng từ ngữ của nhà văn vậy.
Rất mong được anh chỉnh thêm nhiều.
Em sẽ cố gắng thấm những gì anh truyền đạt. |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 20:28:47 (+0700) | #22 | 261931 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Cám ơn bạn TQN đã góp ý cho code của mình nhiều lắm.
Đoạn code trên đầu tiên chạy được là ok rồi, mình còn customize lại nữa bạn ah, phải tiến hành đo thời gian và tần số thực thi của chip nữa và tiếp theo sẽ quyết định lựa chọn phép toán nào có tốc độ thực thi nhanh hơn, việc này sẽ do partner của mình chuyên về Điện tử thực hiện, chứ không phải nhiêu đấy là đập vào cho em chip ngay được.
Nhiêu đây cũng mất 3 ngày tìm hiểu DHCP của mình rồi. Một lần nữa cám ơn chiro8x nha. Bạn mà có ở đây là đãi bạn một chầu nhậu rồi ... . |
|
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 20:34:26 (+0700) | #23 | 261932 |
|
chiro8x
Member
|
0 |
|
|
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
|
|
Cheer ! cụng li nào bồ tèo .
Chúc bồ tèo viết được đoạn mã ưng ý và optimize cho nó ^^!. Bồ đừng trách anh TQN, anh ấy nghiêm khắc, nhưng những đòi hỏi yêu cầu của anh ấy rất hợp lí và chuẩn. Phải trách bản thân mình trước thôi. |
|
while(1){} |
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 20:42:46 (+0700) | #24 | 261934 |
|
Mrnguyenphuc
Member
|
0 |
|
|
Joined: 05/05/2008 16:14:45
Messages: 40
Offline
|
|
Cheer..
Có được người góp ý cho mình thì mình phải vui chứ. Mình làm chưa tốt mà phải biết sai sót ở đâu mà còn sửa nữa chứ. Đúng không anh TQN ?
Thanks nha chiro8x ak sao không thấy ông bạn online skype vậy. Thỉnh thoảng trao đổi kinh nghiệm nữa chứ. Mình có viết driver (language c), Android app (java), iOS app (C Object). Rất mong được chỉ giáo thêm.
|
|
|
[Programming] Lập trình DHCP Client bằng ngôn ngữ C |
23/04/2012 21:05:40 (+0700) | #25 | 261937 |
phuongnvt
Member
|
0 |
|
|
Joined: 09/02/2011 03:35:39
Messages: 332
Offline
|
|
Bác này chắc đang dự định sản xuất card mạng đây mà. |
|
Nhiều người nhận được lời khuyên, song chỉ có những người khôn mới sử dụng lời khuyên đó
|
|
|