In comp.unix.programmer ANaiveProgrammer <(E-Mail Removed)> wrote:
> hi there
> i have defined the following two structs( Code is attached at the
> bottom of this message....) i actually want to send ARP-Request
> message to my loopback because im not attached to an Ethernet? Now
> what im doing is i have tried to sent my ethernet_frame(See code..) to
> my loopback?( Is it a legitimate way to check that ARP-request has
> been processed successfully if u r not attached to a LAN, if not then
> please tell me how can i check that my ARP-REQUEST has been
> successfully processed even if im not attached to a ethernet/LAN?)
> Now another problem is that i need to know the correct size of both
> the structs i.e. ethernet_frame and arp_request. and when i check that
> using sizeof operator then it doesn't show me the correct size.
> How will i send a struct over the wire, is the following way correct
> write(sockfd,(char *)&ef,sizeof(ef));// ef is theinstance of
> ethernet_frame
> if above is not correct, thenn who will i send the struct over a
> socket?
> lastly, i need to be sure about the structs that i have designed i.e.
> their structure and datatype and the way i have initialized them in
> set_ethernet()
> and set_request()..are my initializations correct in these two
> functions???
> I really appreciate any help, at earliest, as im very new in C under
> linux, and this is the first time im programming the link-layer.....
> I know this is a long message and will take qutie a bit of ur time.
> However i appreciate your effort and time and i hope i will get a
> reply soon
> Cheers
> CODE( in c under RED HAT Linux 8)
> --------------------------------
> #include <sys/socket.h>
> #include <sys/types.h>
> #include <netinet/in.h>
> #include <string.h>
>
> typedef struct {
> //This struct defines Arp--Request.
> uint8_t haddr_type;// For Ethernet it is 1
> uint8_t proto_type[4];// 0x800
> uint8_t hard_len;// 6 Bytes
> uint8_t proto_len;// 4 Bytes
> uint16_t operation;// 1---> for request
> uint8_t sender_hard[6];//Sender Hardware Address
> uint8_t sender_proto[4];//Sender protocol Address
> uint8_t target_ip[4];// Target IP Address
> //Target Hardware Address, to me, is optional so i didn't mention it.
> }arp_request;
>
> typedef struct{
> uint8_t destip[4];
> uint8_t sourceip[4];
> uint8_t frametype[3];// 0x806 identifies ARP message
> arp_request *req;
> } ethernet_frame;
>
> void set_ethernet(ethernet_frame *ef, arp_request *rep1){
> //This function set the values of variables defined in ethernet_frame
> struct
> uint8_t dest[4] = {127,0,0,1};
>
> int k;
> for ( k=0; k < 4; k++)
> ef->destip[k] = dest[k];
>
> uint8_t source[4] = {144,5,4,1};
> for ( k=0; k < 4; k++)
> ef->sourceip[k] = source[k];
>
> uint8_t frame[3]={0x8,0x0,0x6};
> for( k=0; k<3;k++)
> ef->frametype[k] = frame[k];
> ef->req = rep1;
> }
>
> void set_request(arp_request *req){
> //This function set the values of variables defined in arp_request
> struct
> req->haddr_type = 1;
> uint8_t ptype[4] = {0x0,0x8,0x0,0x0};
> int k;
> for ( k=0; k < 4; k++)
> req->proto_type[k] = ptype[k];
> req->operation = 1;
> uint8_t sendh[6] = {0xff,0xdd,0xcd,0xfa,0x8f,0xff};
> for ( k=0; k < 6; k++)
> req->sender_hard[k] = sendh[k];
> strcpy(req->sender_hard,sendh);
> uint8_t senderp[4]={128,0,0,1};
> int i;
> for (i=0; i < 4; ++i)
> req->sender_proto[i] = senderp[i];
>
> uint8_t tip[4] = {127,0,0,1};
> int ii;
> for ( ii =0; ii < 4; ++ii)
> req->target_ip[ii] = tip[ii];
> }
>
> int main(){
> arp_request request;
> set_request(&request);
> ethernet_frame ef;
> set_ethernet(&ef,&request);
> printf("Size of ARP---%d\n",sizeof(request));//It doesnt print
> correct size
> printf("Size of Ethernet---%d\n",sizeof(ef));//It doesnt print
> correct size
It prints the correct size - the structure just hasn't the size you
assume it to be. As I already wrote in comp.lang.c the compiler is
free to insert as many "padding bytes" between the members of the
structure as it deems necessary. So don't use structures if you
need to assemble data in a certain binary format. Take instead a
flat array of unsigned chars for the "ethernet_frame" and assemble
the data in it by memcpy()ing to the correct offsets. That's
basically the only way to guarantee that you get the binary
format right (well, modulo big-endian/little-endian issues if
you copy binary data from ints or other types that are longer
than a single byte).
> int len=0;
Do you have a C99 compiler? Otherwise defining variables after the
first executable statement isn't allowed...
> set_ethernet(&ef,&request);
Why do you do that again?
> int sockfd;
> struct sockaddr_in dest;
> sockfd = socket(AF_INET,SOCK_STREAM,0);
> dest.sin_family = AF_INET;
> char type1[4]="0800";
You need one more character in 'type1' if you want to store the
string "0800" - you need room for the termination '\0'.
>
> int i;
> for( i=0; i < strlen(type1); ++i)
> printf("%c",type1[i]);
> printf("\n");
>
> dest.sin_addr.s_addr = inet_addr("127.0.0.1");
> bind(sockfd,(struct sockaddr*)&dest ,sizeof(struct sockaddr));
Why do you call bind() when you obviously try to connect to some
server?
> printf("Trying to Connect\n");
> connect(sockfd,(struct sockaddr*)&dest,sizeof(struct sockaddr));
> printf("Connected...\n");
> write(sockfd,(char *)&ef,10);
Now things get even more weird. Where do you got the idea from that
a structure of type 'ethernet_frame' has 10 bytes? Even if there
are no padding bytes it would have at least 15 bytes. And what's
sending a pointer ('rep') over the socket good for? The other side
won't be able to do anything useful with that.
> return 0;
> }
Sorry, but I really don't understand what you're trying to do here.
From all the 'ethernet_frame' and 'ARP request' stuff in the
prgram I get the feeling that you actually want to assemble your
own packages and send them somewhere else - but then why do you use
the TCP protocol to send that?
Regards, Jens
--
\ Jens Thoms Toerring ___
(E-Mail Removed)
\__________________________
http://www.toerring.de