tools/build-R2_19_3/fsboot/sbl/network.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *!
00003 *! FILE NAME  : network.c
00004 *!
00005 *! DESCRIPTION: Network boot stuff for boot loader.
00006 *!
00007 *! ---------------------------------------------------------------------------
00008 *! HISTORY
00009 *!
00010 *! DATE         NAME               CHANGES
00011 *! ----         ----               -------
00012 *! 1996         Ronny Raneup       Initial version
00013 *! 2002 05 02   Ronny Ranerup      Moved it into this file
00014 *! ---------------------------------------------------------------------------
00015 *! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
00016 *!     Axis Communications AB, LUND, SWEDEN
00017 *!***************************************************************************/
00018 /**************************  Include files  ********************************/
00019 
00020 #include <stdio.h>
00021 #include <pcap.h>
00022 #include <conf.h>               /* from configure  */
00023 
00024 #include <e100boot.h>
00025 #include <common.h>
00026 #include <network.h>
00027 
00028 /**************************  Constants and macros  *************************/
00029 #define CRC_LEN 4
00030 
00031 /**************************  Type definitions  *****************************/
00032 /**************************  Global variables  *****************************/
00033 udword highest_ack_received;
00034 udword last_ack_received = -1;
00035 int new_ack             = FALSE;
00036 int got_new_packet      = FALSE;
00037 
00038 /* Address that etrax receives packets to and sends from. */
00039 const unsigned char axis_000200[] = { 0x01, 0x40, 0x8c, 0x00, 0x02, 0x00 };
00040 
00041 /* Address that etrax boot rom sends first "i'm alive" packets
00042    to. Changes to sbl address as soon as cbl is loaded. */
00043 const unsigned char axis_000400[] = { 0x01, 0x40, 0x8c, 0x00, 0x04, 0x00 };
00044 
00045 /* addres of sbl host */
00046 unsigned char eth_addr_local[]     = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00047 
00048 struct sockaddr sock_addr;
00049 int             sock_fd;
00050 int pPacket = 0;
00051 pcap_t *pd;
00052 
00053 pcap_handler handler;
00054 
00055 struct packet_buf first_rec_packet;
00056 struct packet_buf *last_rec_packet = &first_rec_packet;
00057 
00058 int promisc = 1;                /* promiscuous mode */
00059 int all_ids             = TRUE;
00060 
00061 int both_addresses = FALSE;
00062 int p_packet_bpl = 8;
00063 int printPacketType = CHAR;
00064 
00065 unsigned int id = 0;
00066 int one_id_only         = TRUE;
00067 //int one_id_only       = FALSE;
00068 
00069 #define PKT_BUF_LEN 200
00070 unsigned char buf[PKT_BUF_LEN]; /* pcap buffer */
00071 
00072 const struct pcap_pkthdr *hdrG;
00073 
00074 char host1[MAX_STRING_LEN];     /* name of ethernet host */
00075 char host2[MAX_STRING_LEN];     /* name of ethernet host */
00076 
00077 /**************************  Function prototypes  **************************/
00078 
00079 int                     timeout                 (struct timeval *tvThen, int ms);
00080 int                     InitSendSocket          (char *device_name);
00081 int                     highest_seq_received    (void);
00082 struct packet_buf*      ack_on_seq              (int seq);
00083 struct packet_buf*      packet_with_seq         (int seq);
00084 struct timeval          timeval_subtract        (struct timeval *x, struct timeval *y);
00085 void                    GetNextPacket           (void);
00086 void                    PrintPacket             (const unsigned char *p, int size, int type);
00087 
00088 /****************************************************************************
00089 *#
00090 *#  FUNCTION NAME: net_init
00091 *#
00092 *#  DESCRIPTION: 
00093 *#
00094 *#---------------------------------------------------------------------------
00095 *#  HISTORY
00096 *#
00097 *#  DATE         NAME     CHANGES
00098 *#  ----         ----     -------
00099 *#  2002 05 02   ronny    Initial version
00100 *#
00101 *#***************************************************************************/
00102 void
00103 net_init(void)
00104 {
00105   char *dev;                    
00106   char errBuf[1000];
00107   
00108   GetLocalEthAddr();
00109   first_rec_packet.data = malloc(PACKET_SIZE);
00110   
00111   if ((dev = pcap_lookupdev(errBuf)) == NULL) {
00112     printf("Error, %s.\n", errBuf);
00113     exit(EXIT_FAILURE);
00114   }
00115   
00116   if ((pd = pcap_open_live(device, PKT_BUF_LEN, promisc, 10, errBuf)) == NULL) {
00117     printf("Error, %s.\n", errBuf);
00118     exit(EXIT_FAILURE);
00119   }
00120   
00121   handler = (pcap_handler) Handler;
00122   
00123   InitSendSocket(device);
00124 }
00125 
00126 /****************************************************************************
00127 *#
00128 *#  FUNCTION NAME: NetBoot
00129 *#
00130 *#  DESCRIPTION: The main network boot routine.
00131 *#
00132 *#---------------------------------------------------------------------------
00133 *#  HISTORY
00134 *#
00135 *#  DATE         NAME     CHANGES
00136 *#  ----         ----     -------
00137 *#  2000 01 07   ronny    Initial version
00138 *#  2002 05 02   ronny    Fixed segv bug
00139 *#
00140 *#***************************************************************************/
00141 
00142 void
00143 NetBoot(void)
00144 {
00145   struct packet_buf *p;
00146   struct timeval     tv;
00147   unsigned print_last = FALSE;
00148   
00149   gettimeofday(&tv, NULL);
00150 
00151   p = create_packet(0);
00152   if (p->size > 1514) {
00153     printf("Ethernet package to large (%d). A bug somewhere...\n", p->size);
00154     exit(EXIT_FAILURE);
00155   }
00156   SendToDevice(p->data, p->size);
00157 
00158   while(1) {
00159     static int all_trans = FALSE;
00160 
00161     if (got_new_packet) {
00162       got_new_packet = FALSE;
00163       
00164       if (new_ack && first_packet) {
00165         if (db4) {
00166           printf("* got ACK %d.\n", last_ack_received);
00167           printf("* ACK wanted %d.\n", first_packet->seq);
00168         }
00169         
00170         /* did we get ack on last packet? */
00171         if (last_ack_received == first_packet->seq) { 
00172 
00173           /* yes, create next packet */
00174           if ((p = create_packet(first_packet->seq+1))) {
00175             /* fill in id */
00176             ((struct packet_header_T*)p->data)->id = htonl(id);
00177             
00178             /* free old packet and move to next packet */
00179             first_packet = free_packet(first_packet);
00180           }
00181         }
00182       }
00183     }
00184     
00185     if (new_ack || timeout(&tv, 500)) {
00186       if (p) {
00187         SendToDevice(p->data, p->size);
00188       }
00189       else {
00190         if (print_last) {
00191           printf("Last packet\n");
00192           print_last = 0;
00193         }
00194       }
00195       new_ack = FALSE;
00196       gettimeofday(&tv, NULL);
00197     }
00198     
00199     GetNextPacket();
00200 
00201   }
00202 }
00203 
00204 /****************************************************************************
00205 *#
00206 *#  FUNCTION NAME: GetNextPacket
00207 *#
00208 *#  DESCRIPTION: 
00209 *#
00210 *#---------------------------------------------------------------------------
00211 *#  HISTORY
00212 *#
00213 *#  DATE     NAME     CHANGES
00214 *#  ----     ----     -------
00215 *#  961022   ronny    Initial version
00216 *#
00217 *#***************************************************************************/
00218 
00219 void
00220 GetNextPacket(void)
00221 {
00222   int ret;
00223 
00224   if (db2) printf("> GetNextPacket\n");
00225 
00226     /*    got_new_packet = FALSE;*/
00227     if ((ret = pcap_dispatch(pd, 1, handler, buf)) == -1) {
00228       pcap_perror(pd, "Error in pcap_dispatch");
00229       exit(EXIT_FAILURE);
00230     }
00231 
00232   if (db2) printf("< GetNextPacket\n");
00233 }
00234 
00235 /****************************************************************************
00236 *#
00237 *#  FUNCTION NAME: Handler
00238 *#
00239 *#  PARAMETERS: 
00240 *#
00241 *#  DESCRIPTION: 
00242 *#
00243 *#---------------------------------------------------------------------------
00244 *#  HISTORY
00245 *#
00246 *#  DATE     NAME     CHANGES
00247 *#  ----     ----     -------
00248 *#  961022   ronny    Initial version
00249 *#
00250 *#***************************************************************************/
00251 
00252 void
00253 Handler(unsigned char *buf, const struct pcap_pkthdr *hdr,
00254         const unsigned char *p)
00255 {
00256   const unsigned char *src = &p[6];
00257   const unsigned char *dst = &p[0];
00258   struct packet_header_T *h = (struct packet_header_T*)p;
00259   
00260   if (db2) printf("> Handler\n");
00261 
00262         // check, it's packet from current session?
00263         if(all_ids == FALSE) {
00264                 if(id != ntohl(h->id)) {
00265                         return;
00266                 }
00267         }
00268 
00269   got_new_packet = TRUE;
00270 
00271 #if 0
00272   if (
00273       /* from      sbl                 to             etrax                   */
00274       (!memcmp(src, eth_addr_local, 6) && !memcmp(dst, axis_000200, 6))
00275       /* from      etrax               to                   sbl unicast       */
00276       || (!memcmp(src, axis_000200, 6) && (!memcmp(dst, eth_addr_local, 6) 
00277                                    || !memcmp(dst, axis_000400, 6)))) {
00278 #endif
00279     
00280   if (
00281       /* from      etrax               to                   sbl unicast       */
00282       (!memcmp(src, axis_000200, 6) && (!memcmp(dst, eth_addr_local, 6) 
00283                                         || !memcmp(dst, axis_000400, 6)))) {
00284     /*                                                axis multicast          */
00285     if (db1) printf("#RX######################################################\n");
00286     if (db1) printf("Length: %u(0x%x)\n", (udword)hdr->len, (udword)hdr->len);
00287     if (pPacket) PrintPacket(p, hdr->caplen, printPacketType);
00288     DecodeSvintoBoot(p);
00289     if (!listenOnly) {
00290       /* should clean this up... */
00291       if ((ntohl(h->type) == ACK)) {
00292         if (all_ids || (ntohl(h->id) == id)) { 
00293           if (all_ids && one_id_only) {
00294             if (ntohl(h->id) != 0) {
00295               all_ids = FALSE;
00296               id = ntohl(h->id);
00297               printf("Connected. Booting device with random id %8.8x.\n", id);
00298             }
00299           } else {
00300 //            printf("Connected, but something strange.... Booting device with random id %8.8x.\n", id);
00301 //            printf("Connected, but something strange.... Network device id %8.8x.\n", htonl(h->id));
00302           }
00303         }
00304         else {
00305           printf("Got ACK from a new id, %8.8lx. Ignoring.\n", 
00306                  (unsigned long)ntohl(h->id));
00307           return;
00308         }
00309         new_ack = TRUE;
00310         last_ack_received = ntohl(h->seq);
00311         if (last_ack_received > highest_ack_received) {
00312           highest_ack_received = last_ack_received;
00313         }
00314       }
00315     }
00316 
00317     if (db1) printf("#########################################################\n");
00318     
00319   }
00320   if (db2) printf("< Handler\n");
00321 }
00322 
00323 /****************************************************************************
00324 *#
00325 *#  FUNCTION NAME: ack_on_seq
00326 *#
00327 *#  PARAMETERS: 
00328 *#
00329 *#  DESCRIPTION: 
00330 *#
00331 *#---------------------------------------------------------------------------
00332 *#  HISTORY
00333 *#
00334 *#  DATE     NAME     CHANGES
00335 *#  ----     ----     -------
00336 *#  980817   ronny    Initial version
00337 *#
00338 *#***************************************************************************/
00339 
00340 struct packet_buf *
00341 packet_with_seq(int seq)
00342 {
00343   static int last_seq = 0;
00344   struct packet_buf *p = first_packet;
00345   struct packet_header_T *h;
00346   
00347   if (seq < last_seq) {
00348     p = first_packet;
00349   }
00350 
00351   while(p) {
00352     h = (struct packet_header_T*)p->data;
00353     if (ntohl(h->seq) == seq) {
00354       return(p);
00355     }
00356     p = p->next;
00357   }
00358   return(NULL);
00359 }
00360 
00361 struct packet_buf *
00362 ack_on_seq(int seq)
00363 {
00364   struct packet_buf *p = &first_rec_packet;
00365   struct packet_header_T *h;
00366 
00367   if (db1) printf("***> ack_on_seq: %d.\n", seq);
00368 
00369   while (p) {
00370     /*    printf("\nPacket at %x.\n", p);*/
00371     /*    DecodeSvintoBoot(p->data);*/
00372     h = (struct packet_header_T*)p->data;
00373     if ( (ntohl(h->type) == ACK) && (ntohl(h->seq) == seq) ) {
00374       if (all_ids || ntohl(h->id) == id) {
00375         printf("***< ack_on_seq %d, ok.\n", seq);
00376         return(p);
00377       }
00378     }
00379     p = p->next;
00380   }
00381   if (db1) printf("***< ack_on_seq, no.\n");
00382   return(NULL);
00383 }
00384 
00385 int
00386 highest_seq_received(void)
00387 {
00388   struct packet_buf *p = &first_rec_packet;
00389   struct packet_header_T *h;
00390   int highest_seq = -1;
00391 
00392   if (db1) printf("***> highest_seq_received\n");
00393 
00394   while (p) {
00395     /*    printf("\nPacket at %x.\n", p);*/
00396     /*    DecodeSvintoBoot(p->data);*/
00397     h = (struct packet_header_T*)p->data;
00398     if ((ntohl(h->type) == ACK) && (all_ids || (ntohl(h->id) == id))) {
00399       if ((int)ntohl(h->seq) > highest_seq) {
00400         highest_seq = ntohl(h->seq);
00401         if (db4) printf("Highest seq: %d\n", highest_seq);
00402       }
00403     }
00404     p = p->next;
00405   }
00406 
00407   if (db1) printf("***< highest_seq_received: %d\n", highest_seq);
00408   return(highest_seq);
00409 }
00410 
00411 
00412 /****************************************************************************
00413 *#
00414 *#  FUNCTION NAME: PrintPacket
00415 *#
00416 *#  PARAMETERS: 
00417 *#
00418 *#  DESCRIPTION: 
00419 *#
00420 *#---------------------------------------------------------------------------
00421 *#  HISTORY
00422 *#
00423 *#  DATE     NAME     CHANGES
00424 *#  ----     ----     -------
00425 *#  961022   ronny    Initial version
00426 *#
00427 *#***************************************************************************/
00428 
00429 void
00430 PrintPacket(const unsigned char *p, int size, int type)
00431 {
00432   int i;
00433 
00434   /*  printf("size %d\n", size);*/
00435   for (i = 0; i != size; i++) {
00436     if (i % p_packet_bpl == 0)
00437       printf("\n%-4.4d: ", i);
00438     if (type == UDEC) {
00439       printf("%-3d ", p[i]);
00440     }
00441     else if (type == HEX) {
00442       printf("%-2.2x ", p[i]);
00443     }
00444     else if (type == CHAR) {
00445       if (isprint(p[i])) {
00446         printf("%-3c ", p[i]);
00447       }
00448       else {
00449         printf("%-3d ", p[i]);
00450       }
00451     }
00452     else if (type == ASCII) {
00453       if (isprint(p[i])) {
00454         printf("%c", p[i]);
00455       }
00456       else {
00457         printf(".");
00458       }
00459     }
00460   }
00461     printf("\n");
00462 }
00463 
00464 /****************************************************************************
00465 *#
00466 *#  FUNCTION NAME: DecodeSvintoBoot
00467 *#
00468 *#  PARAMETERS: 
00469 *#
00470 *#  DESCRIPTION: Decodes packets that follow the boot protocol.
00471 *#
00472 *#---------------------------------------------------------------------------
00473 *#  HISTORY
00474 *#
00475 *#  DATE     NAME     CHANGES
00476 *#  ----     ----     -------
00477 *#  961022   ronny    Initial version
00478 *#
00479 *#***************************************************************************/
00480 
00481 void 
00482 DecodeSvintoBoot(const unsigned char *p)
00483 {
00484   char *str;
00485   volatile struct packet_header_T *ph =  (struct packet_header_T*)p;
00486 
00487   /*  printf("size %d \n", sizeof(struct packet_header_T));*/
00488 
00489   if (db4) printf("\n>DecodeSvintoBoot. Packet at 0x%x\n", (unsigned int)p);
00490   if (db1) {
00491     printf("%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x -> ", p[6],p[7],p[8],p[9],p[10], p[11]);
00492     printf("%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x\n", p[0],p[1],p[2],p[3],p[4],  p[5]);
00493     
00494     printf("length   : %4.4lx\n", (long)ntohs(ph->length));
00495     printf("snap1    : %8.8lx\n", (long)ntohl(ph->snap1));
00496     printf("snap2    : %8.8lx\n", (long)ntohl(ph->snap2));
00497   
00498     switch (ntohl(ph->tag)) {
00499     case 0xffffffff:
00500       str = "(host > ETRAX)";
00501       break;
00502     case 0xfffffffe:
00503       str = "(ETRAX > host)";
00504       break;
00505     default:
00506       str = "(unknown)";
00507       break;
00508     }
00509     printf("tag      : %8.8lx %s\n", (unsigned long)ntohl(ph->tag), str);
00510     printf("seq      : %8.8lx\n", (unsigned long)ntohl(ph->seq));
00511   }
00512 
00513   switch (ntohl(ph->type)) {
00514 
00515   case STRING:
00516     str = "(STRING)";
00517     fprintf(stderr, "%s", &p[sizeof(struct packet_header_T)]);
00518     find_string((char*)&p[sizeof(struct packet_header_T)]);
00519     break;
00520 
00521   case NET_INT: {
00522     char search_str[20];
00523 
00524     str = "(NET_INT)";
00525     sprintf(search_str, "0x%8.8x", ntohl(*(udword*)&p[sizeof(struct packet_header_T)]));
00526     fprintf(stderr, search_str);
00527     find_string(search_str);
00528     break;
00529   }
00530 
00531   case NET_INT_NL: {
00532     char search_str[20];
00533     
00534     str = "(NET_INT_NL)";
00535     sprintf(search_str, "0x%8.8x\n", ntohl(*(udword*)&p[sizeof(struct packet_header_T)]));
00536     fprintf(stderr, search_str);
00537     find_string(search_str);
00538     break;
00539   }
00540 
00541   case ACK:
00542     str = "(ACK)";
00543     break;
00544 
00545   case BOOT_PACKET:
00546     str = "(bootpacket)";
00547     break;
00548 
00549   case FILE_PACKET:
00550     str = "(filepacket)";
00551     break;
00552 
00553   case BOOT_CMDS:
00554     str = "(bootcmds)";
00555     break;
00556 
00557   default:
00558     str = "(unknown)";
00559     break;
00560   }
00561 
00562   if (db1) {
00563     printf("(type    : %8.8lx %s)\n", (unsigned long)ntohl(ph->type), str);
00564     printf("(id      : %8.8lx)\n", (unsigned long)ntohl(ph->id));
00565     id = ntohl(ph->id);
00566   }
00567 
00568 }
00569 
00570 
00571 /****************************************************************************
00572 *#
00573 *#  FUNCTION NAME: GetLocalEthAddr
00574 *#
00575 *#  PARAMETERS: None.
00576 *#
00577 *#  DESCRIPTION: 
00578 *#
00579 *#---------------------------------------------------------------------------
00580 *#  DATE     NAME     CHANGES
00581 *#  ----     ----     -------
00582 *#  980818   ronny    Initial version
00583 *#
00584 *#***************************************************************************/
00585 
00586 void
00587 GetLocalEthAddr(void)
00588 {
00589   int fd;
00590   struct ifreq ifr;
00591 
00592   if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
00593     perror("socket (GetLocalEthAddr)");
00594     exit(EXIT_FAILURE);
00595   }
00596 
00597   strcpy(ifr.ifr_name, device);
00598   if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
00599     perror("ioctl");
00600     exit(EXIT_FAILURE);
00601   }
00602 
00603   memcpy(eth_addr_local, ifr.ifr_hwaddr.sa_data, 6);
00604   if (db1) printf("Ethernet adress for device %s is %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x\n", 
00605                   device,
00606                   eth_addr_local[0],
00607                   eth_addr_local[1],
00608                   eth_addr_local[2],
00609                   eth_addr_local[3],
00610                   eth_addr_local[4],
00611                   eth_addr_local[5]);
00612   shutdown(fd, 2);
00613 }
00614 
00615 /****************************************************************************
00616 *#
00617 *#  FUNCTION NAME: SendToDevice
00618 *#
00619 *#  PARAMETERS: 
00620 *#
00621 *#  DESCRIPTION: Send to network device or file. We actually call this function 
00622 *#  for serial boot too, if doing --tofiles. Ugly...
00623 *#
00624 *#---------------------------------------------------------------------------
00625 *#  DATE     NAME     CHANGES
00626 *#  ----     ----     -------
00627 *#  980818   ronny    Initial version
00628 *#
00629 *#***************************************************************************/
00630 
00631 void
00632 SendToDevice(unsigned char *data, int data_len)
00633 {
00634   char fName[MAX_STRING_LEN];
00635   FILE *fd;
00636   struct packet_header_T *h = (struct packet_header_T*) data;
00637 
00638   if (listenOnly) {
00639     return;
00640   }
00641 
00642   if (db2) printf("***> SendToDevice\n");
00643 
00644   if (db2) printf("Sending %d bytes at 0x%x to %s.\n", data_len, (unsigned int)data, device);
00645   if (db1) printf("#TX %3d/%3d #############################################\n",
00646                   ntohl(h->seq)+1, nrof_net_packets);
00647   if (db1) DecodeSvintoBoot(data);
00648 
00649   if (db1) printf("#########################################################\n");
00650   if (toFiles || cmdsOnly) {
00651     if (cmdsOnly) {             /* use a simpler name */
00652       sprintf(fName, "fsboot.cmds");
00653     }
00654     else {
00655       static unsigned seq = 0;
00656 
00657       if (netBoot) {
00658         seq = ntohl(h->seq);
00659       }
00660       sprintf(fName, "tx%d.pkt", seq++);
00661     }
00662     if (db2) printf("Writing packet to file '%s'.\n", fName);
00663     if ((fd = fopen(fName, "w+")) == NULL) {
00664       printf("Cannot open/create '%s'. %s.\n", fName, strerror(errno));
00665       exit(EXIT_FAILURE);
00666     }
00667     fwrite(data, data_len, 1, fd);
00668     fclose(fd);
00669   }
00670   else {  /* waitfor write ready, then write */
00671     fd_set set;
00672     struct timeval timeout;
00673     
00674     /* Initialize the file descriptor set. */
00675     FD_ZERO (&set);
00676     FD_SET (sock_fd, &set);
00677     
00678     /* Initialize the timeout data structure. */
00679     timeout.tv_sec = 0;
00680     timeout.tv_usec = 1;
00681     
00682     if (select(sock_fd+1, NULL, &set, NULL, &timeout) > 0) {
00683       if (sendto(sock_fd, data, data_len, 0, &sock_addr, sizeof(sock_addr)) < 0) {
00684         perror("Sendto failed:");
00685         exit(EXIT_FAILURE);
00686       }
00687     }
00688     else {
00689       /* We should really exit here, but it turns out that some,
00690          probably corrupt, linuxes can have temporary ENOTCONN. */
00691       //perror("select failed:");
00692       //      exit(EXIT_FAILURE);
00693     }
00694   }
00695   
00696   
00697   if (db2) printf("<*** SendToDevice\n");
00698 }
00699 
00700 /****************************************************************************
00701 *#
00702 *#  FUNCTION NAME: InitSendSocket
00703 *#
00704 *#  PARAMETERS: 
00705 *#
00706 *#  DESCRIPTION: 
00707 *#
00708 *#---------------------------------------------------------------------------
00709 *#  DATE     NAME     CHANGES
00710 *#  ----     ----     -------
00711 *#  980818   ronny    Initial version
00712 *#***************************************************************************/
00713 
00714 int
00715 InitSendSocket(char *device_name)
00716 {
00717   if ((sock_fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
00718     perror("Socket call failed:");
00719     exit(EXIT_FAILURE);
00720   }
00721 
00722   fcntl(sock_fd, F_SETFL, O_NDELAY);
00723 
00724   sock_addr.sa_family = AF_INET;
00725   strcpy(sock_addr.sa_data, device_name);
00726 
00727   return sock_fd;
00728 }
00729 
00730 /****************************************************************************
00731 *#
00732 *#  FUNCTION NAME: timeout
00733 *#
00734 *#  PARAMETERS: 
00735 *#
00736 *#  DESCRIPTION: 
00737 *#
00738 *#---------------------------------------------------------------------------
00739 *#  HISTORY
00740 *#
00741 *#  DATE     NAME     CHANGES
00742 *#  ----     ----     -------
00743 *#  980817   ronny    Initial version
00744 *#
00745 *#***************************************************************************/
00746 
00747 int
00748 timeout(struct timeval *tvThen, int ms)
00749 {
00750   struct timeval tvNow;
00751   struct timeval tvDiff;
00752 
00753   (void) gettimeofday(&tvNow, NULL);
00754   tvDiff = timeval_subtract(&tvNow, tvThen);
00755   if (db4) printf("sec %d.%d\n", (int)tvDiff.tv_sec, (int)tvDiff.tv_usec);
00756   if (ms * 1000 < (tvDiff.tv_sec * 1000000 + tvDiff.tv_usec)) {
00757     if (db4) printf("TIMEOUT\n");
00758     return(TRUE);
00759   }
00760   
00761   return(FALSE);
00762 }
00763 
00764 /****************************************************************************
00765  *#
00766  *#  FUNCTION NAME: timeval_subtract
00767  *#
00768  *#  PARAMETERS: 
00769  *#
00770  *#  DESCRIPTION: Subtract x-y, and return result.
00771  *#
00772  *#  DATE     NAME     CHANGES
00773  *#  ----     ----     -------
00774  *#  970128   ronny    Initial version
00775  *#
00776  *#***************************************************************************/
00777 
00778 struct timeval
00779 timeval_subtract(struct timeval *x, struct timeval *y)
00780 {
00781   struct timeval diff;
00782 
00783   diff.tv_sec  = x->tv_sec  - y->tv_sec;
00784   diff.tv_usec = x->tv_usec - y->tv_usec;
00785 
00786   if (diff.tv_usec < 0) {
00787     diff.tv_sec--;
00788     diff.tv_usec = 1000000 + diff.tv_usec;
00789   }
00790 
00791   return diff;
00792 }
00793 
00794 

Generated on Fri Nov 28 00:06:25 2008 for elphel by  doxygen 1.5.1