wrote, On 15/12/07 07:48:
> Hi all~
> I've written a network program in C.
C does not have networking support, you have written a program in C +
extra libraries.
> This program catputures ARP request packet and reply wrong ARP packet.
> Hi. I've written a small program to learn to write in C. But
> unfortunately the output is all jumbled up and not nice
> Caputuring is ok, but couldn't send ARP packet. What's wrong?
>
> ( using 2PC, this program run in Linux and moitoring other PC,Window
> XP)
> (generator packet prgram is BillSniff, monitoring program is
> WireShark)
Since you mention Linux, try compiling the program using gcc with the
options "-std=c99 -pedantic -Wall -Wextra". The compiler will tell you
about lots of problems than.
> #include <sys/socket.h>
> #include <sys/ioctl.h>
> #include <sys/time.h>
>
> #include <asm/types.h>
All the above headers are not standard C and so not topical here.
> #include <math.h>
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
unistd.c is also not standard C and so not topical here.
> #include <signal.h>
>
> #include <linux/if_packet.h>
> #include <linux/if_ether.h>
> #include <linux/if_arp.h>
The above three headers are Linux specific and so not topical here and
possibly not topical in comp.programmer.unix where the earlier headers
would have been topical. However, there are plenty of Linux groups.
> #define BUF_SIZE 42
> #define DEVICE "eth0"
> #define ETH_P_NULL 0x0
> #define ETH_MAC_LEN ETH_ALEN
> #define ETH_ARP 0x0806
>
> int s = 0; /*Socketdescriptor*/
> void* buffer = NULL;
> long total_packets = 0;
> long answered_packets = 0;
Global variable. Yuck. Horrible. Redesign your program so you do to
avoid them since as you start working on larger projects they make
things harder and messier.
Also void* is generally not a good type for a buffer, unsigned char*
would be more sensible if it is binary data.
> void sigint(int signum);
>
> struct __attribute__((packed)) arp_header
__attribute__ is gcc specific (well, Intel's compiler that aims to be
gcc compatible will accept it as well).
> {
> unsigned short arp_hd;
> unsigned short arp_pr;
> unsigned char arp_hdl;
> unsigned char arp_prl;
> unsigned short arp_op;
> unsigned char arp_sha[6];
> unsigned char arp_spa[4];
> unsigned char arp_dha[6];
> unsigned char arp_dpa[4];
> };
>
>
> int main(void) {
> buffer = (void*)malloc(BUF_SIZE); /*Buffer for Ethernet Frame*/
Don't cast the return value of malloc. It is not required and in general
casts should be avoided unless you *really* know *exactly* why they are
needed, since normally when casts are added they are not the correct
solution to the problem.
> unsigned char* etherhead = buffer; /*Pointer to Ethenet Header*/
> struct ethhdr *eh = (struct ethhdr *)etherhead; /*Another pointer to
> ethernet header*/
> unsigned char* arphead = buffer + 14;
Standard C does not allow arithmetic on void* pointers, one reason for
using unsigned char* as the type for buffer.
<snip>
> printf("Totally received: %d packets\n", total_packets);
> printf("Answered %d packets\n", answered_packets);
long and int are not the same type, %d is for int not long.
> exit(0);
> }
Most of the above problems, and a few more besides, where shown by using
the compiler options I have suggested. If you are nice to it your
compiler can be a very good friend and help you a lot.
--
Flash Gordon