1*a3c77c67SJeff Dike #ifndef __UM_SLIP_COMMON_H 2*a3c77c67SJeff Dike #define __UM_SLIP_COMMON_H 3*a3c77c67SJeff Dike 4*a3c77c67SJeff Dike #define BUF_SIZE 1500 5*a3c77c67SJeff Dike /* two bytes each for a (pathological) max packet of escaped chars + * 6*a3c77c67SJeff Dike * terminating END char + initial END char */ 7*a3c77c67SJeff Dike #define ENC_BUF_SIZE (2 * BUF_SIZE + 2) 8*a3c77c67SJeff Dike 9*a3c77c67SJeff Dike /* SLIP protocol characters. */ 10*a3c77c67SJeff Dike #define SLIP_END 0300 /* indicates end of frame */ 11*a3c77c67SJeff Dike #define SLIP_ESC 0333 /* indicates byte stuffing */ 12*a3c77c67SJeff Dike #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ 13*a3c77c67SJeff Dike #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 14*a3c77c67SJeff Dike 15*a3c77c67SJeff Dike static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, 16*a3c77c67SJeff Dike int *esc) 17*a3c77c67SJeff Dike { 18*a3c77c67SJeff Dike int ret; 19*a3c77c67SJeff Dike 20*a3c77c67SJeff Dike switch(c){ 21*a3c77c67SJeff Dike case SLIP_END: 22*a3c77c67SJeff Dike *esc = 0; 23*a3c77c67SJeff Dike ret=*pos; 24*a3c77c67SJeff Dike *pos=0; 25*a3c77c67SJeff Dike return(ret); 26*a3c77c67SJeff Dike case SLIP_ESC: 27*a3c77c67SJeff Dike *esc = 1; 28*a3c77c67SJeff Dike return(0); 29*a3c77c67SJeff Dike case SLIP_ESC_ESC: 30*a3c77c67SJeff Dike if(*esc){ 31*a3c77c67SJeff Dike *esc = 0; 32*a3c77c67SJeff Dike c = SLIP_ESC; 33*a3c77c67SJeff Dike } 34*a3c77c67SJeff Dike break; 35*a3c77c67SJeff Dike case SLIP_ESC_END: 36*a3c77c67SJeff Dike if(*esc){ 37*a3c77c67SJeff Dike *esc = 0; 38*a3c77c67SJeff Dike c = SLIP_END; 39*a3c77c67SJeff Dike } 40*a3c77c67SJeff Dike break; 41*a3c77c67SJeff Dike } 42*a3c77c67SJeff Dike buf[(*pos)++] = c; 43*a3c77c67SJeff Dike return(0); 44*a3c77c67SJeff Dike } 45*a3c77c67SJeff Dike 46*a3c77c67SJeff Dike static inline int slip_esc(unsigned char *s, unsigned char *d, int len) 47*a3c77c67SJeff Dike { 48*a3c77c67SJeff Dike unsigned char *ptr = d; 49*a3c77c67SJeff Dike unsigned char c; 50*a3c77c67SJeff Dike 51*a3c77c67SJeff Dike /* 52*a3c77c67SJeff Dike * Send an initial END character to flush out any 53*a3c77c67SJeff Dike * data that may have accumulated in the receiver 54*a3c77c67SJeff Dike * due to line noise. 55*a3c77c67SJeff Dike */ 56*a3c77c67SJeff Dike 57*a3c77c67SJeff Dike *ptr++ = SLIP_END; 58*a3c77c67SJeff Dike 59*a3c77c67SJeff Dike /* 60*a3c77c67SJeff Dike * For each byte in the packet, send the appropriate 61*a3c77c67SJeff Dike * character sequence, according to the SLIP protocol. 62*a3c77c67SJeff Dike */ 63*a3c77c67SJeff Dike 64*a3c77c67SJeff Dike while (len-- > 0) { 65*a3c77c67SJeff Dike switch(c = *s++) { 66*a3c77c67SJeff Dike case SLIP_END: 67*a3c77c67SJeff Dike *ptr++ = SLIP_ESC; 68*a3c77c67SJeff Dike *ptr++ = SLIP_ESC_END; 69*a3c77c67SJeff Dike break; 70*a3c77c67SJeff Dike case SLIP_ESC: 71*a3c77c67SJeff Dike *ptr++ = SLIP_ESC; 72*a3c77c67SJeff Dike *ptr++ = SLIP_ESC_ESC; 73*a3c77c67SJeff Dike break; 74*a3c77c67SJeff Dike default: 75*a3c77c67SJeff Dike *ptr++ = c; 76*a3c77c67SJeff Dike break; 77*a3c77c67SJeff Dike } 78*a3c77c67SJeff Dike } 79*a3c77c67SJeff Dike *ptr++ = SLIP_END; 80*a3c77c67SJeff Dike return (ptr - d); 81*a3c77c67SJeff Dike } 82*a3c77c67SJeff Dike 83*a3c77c67SJeff Dike struct slip_proto { 84*a3c77c67SJeff Dike unsigned char ibuf[ENC_BUF_SIZE]; 85*a3c77c67SJeff Dike unsigned char obuf[ENC_BUF_SIZE]; 86*a3c77c67SJeff Dike int more; /* more data: do not read fd until ibuf has been drained */ 87*a3c77c67SJeff Dike int pos; 88*a3c77c67SJeff Dike int esc; 89*a3c77c67SJeff Dike }; 90*a3c77c67SJeff Dike 91*a3c77c67SJeff Dike #define SLIP_PROTO_INIT { \ 92*a3c77c67SJeff Dike .ibuf = { '\0' }, \ 93*a3c77c67SJeff Dike .obuf = { '\0' }, \ 94*a3c77c67SJeff Dike .more = 0, \ 95*a3c77c67SJeff Dike .pos = 0, \ 96*a3c77c67SJeff Dike .esc = 0 \ 97*a3c77c67SJeff Dike } 98*a3c77c67SJeff Dike 99*a3c77c67SJeff Dike extern int slip_proto_read(int fd, void *buf, int len, 100*a3c77c67SJeff Dike struct slip_proto *slip); 101*a3c77c67SJeff Dike extern int slip_proto_write(int fd, void *buf, int len, 102*a3c77c67SJeff Dike struct slip_proto *slip); 103*a3c77c67SJeff Dike 104*a3c77c67SJeff Dike #endif 105