]> andersk Git - libfaim.git/blob - utils/aimdump/icbmparse.c
- Wed Nov 8 02:23:25 UTC 2000
[libfaim.git] / utils / aimdump / icbmparse.c
1
2
3 #include <faim/aim.h>
4
5 void parser_icbm_incoming(u_char *data, int len)
6 {
7   struct aim_userinfo_s userinfo;
8   u_int i = 0, j = 0, y = 0, z = 0;
9   char *msg = NULL;
10   u_int icbmflags = 0;
11   u_char cookie[8];
12   int channel;
13   struct aim_tlvlist_t *tlvlist;
14   struct aim_tlv_t *msgblocktlv, *tmptlv;
15   u_char *msgblock;
16   u_short wastebits;
17   u_short flag1,flag2;
18
19   memset(&userinfo, 0x00, sizeof(struct aim_userinfo_s));
20
21   i = 0;
22   /*
23    * Read ICBM Cookie.  And throw away.
24    */
25   for (z=0; z<8; z++,i++)
26     cookie[z] = data[i];
27   
28   /*
29    * Channel ID.
30    *
31    * Channel 0x0001 is the message channel.  There are 
32    * other channels for things called "rendevous"
33    * which represent chat and some of the other new
34    * features of AIM2/3/3.5.  We only support 
35    * standard messages; those on channel 0x0001.
36    */
37   channel = aimutil_get16(data+i);
38   i += 2;
39   if (channel != 0x0001)
40     {
41       printf("faim: icbm: ICBM received on an unsupported channel.  Ignoring.\n (chan = %04x)", channel);
42       return;
43     }
44
45   /*
46    * Source screen name.
47    */
48   memcpy(userinfo.sn, data+i+1, (int)data[i]);
49   userinfo.sn[(int)data[i]] = '\0';
50   i += 1 + (int)data[i];
51
52   /*
53    * Unknown bits.
54    */
55   wastebits = aimutil_get16(data+i);
56   i += 2;
57   wastebits = aimutil_get16(data+i);
58   i += 2;
59
60   /*
61    * Read block of TLVs.  All further data is derived
62    * from what is parsed here.
63    */
64   tlvlist = aim_readtlvchain(data+i, len-i);
65
66   /*
67    * Check Autoresponse status.  If it is an autoresponse,
68    * it will contain a second type 0x0004 TLV, with zero length.
69    */
70   if (aim_gettlv(tlvlist, 0x0004, 2))
71     icbmflags |= AIM_IMFLAGS_AWAY;
72
73   /*
74    * Check Ack Request status.
75    */
76   if (aim_gettlv(tlvlist, 0x0003, 2))
77     icbmflags |= AIM_IMFLAGS_ACK;
78
79   /*
80    * Extract the various pieces of the userinfo struct.
81    */
82   /* Class. */
83   if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1)))
84     userinfo.class = aimutil_get16(tmptlv->value);
85   /* Member-since date. */
86   if ((tmptlv = aim_gettlv(tlvlist, 0x0002, 1)))
87     {
88       /* If this is larger than 4, its probably the message block, skip */
89       if (tmptlv->length <= 4)
90         userinfo.membersince = aimutil_get32(tmptlv->value);
91     }
92   /* On-since date */
93   if ((tmptlv = aim_gettlv(tlvlist, 0x0003, 1)))
94     userinfo.onlinesince = aimutil_get32(tmptlv->value);
95   /* Idle-time */
96   if ((tmptlv = aim_gettlv(tlvlist, 0x0004, 1)))
97     userinfo.idletime = aimutil_get16(tmptlv->value);
98   /* Session Length (AIM) */
99   if ((tmptlv = aim_gettlv(tlvlist, 0x000f, 1)))
100     userinfo.sessionlen = aimutil_get16(tmptlv->value);
101   /* Session Length (AOL) */
102   if ((tmptlv = aim_gettlv(tlvlist, 0x0010, 1)))
103     userinfo.sessionlen = aimutil_get16(tmptlv->value);
104
105   /*
106    * Message block.
107    *
108    * XXX: Will the msgblock always be the second 0x0002? 
109    */
110   msgblocktlv = aim_gettlv(tlvlist, 0x0002, 1);
111   if (!msgblocktlv)
112     {
113       printf("faim: icbm: major error! no message block TLV found!\n");
114       aim_freetlvchain(&tlvlist);
115     }
116
117   /*
118    * Extracting the message from the unknown cruft.
119    * 
120    * This is a bit messy, and I'm not really qualified,
121    * even as the author, to comment on it.  At least
122    * its not as bad as a while loop shooting into infinity.
123    *
124    * "Do you believe in magic?"
125    *
126    */
127   msgblock = msgblocktlv->value;
128   j = 0;
129
130   wastebits = aimutil_get8(msgblock+j++);
131   wastebits = aimutil_get8(msgblock+j++);
132   
133   y = aimutil_get16(msgblock+j);
134   j += 2;
135   for (z = 0; z < y; z++)
136     wastebits = aimutil_get8(msgblock+j++);
137   wastebits = aimutil_get8(msgblock+j++);
138   wastebits = aimutil_get8(msgblock+j++);
139  
140   /* 
141    * Message string length, including flag words.
142    */
143   i = aimutil_get16(msgblock+j);
144   j += 2;
145
146   /*
147    * Flag words.
148    *
149    * Its rumored that these can kick in some funky
150    * 16bit-wide char stuff that used to really kill
151    * libfaim.  Hopefully the latter is no longer true.
152    *
153    * Though someone should investiagte the former.
154    *
155    */
156   flag1 = aimutil_get16(msgblock+j);
157   j += 2;
158   flag2 = aimutil_get16(msgblock+j);
159   j += 2;
160
161   if (flag1 || flag2)
162     printf("faim: icbm: **warning: encoding flags are being used! {%04x, %04x}\n", flag1, flag2);
163
164   /* 
165    * Message string. 
166    */
167   i -= 4;
168   msg = (char *)malloc(i+1);
169   memcpy(msg, msgblock+j, i);
170   msg[i] = '\0';
171
172   /*
173    * Free up the TLV chain.
174    */
175   aim_freetlvchain(&tlvlist);
176
177   printf("ICBM:\n");
178   printf("\tChannel:\t0x%04x\n", channel);
179   printf("\tSource:\t%s\n", userinfo.sn);
180   printf("\tICBM Flags:\t%s %s\n", 
181          (icbmflags & AIM_IMFLAGS_AWAY)?"Away":"", 
182          (icbmflags & AIM_IMFLAGS_ACK)?"Ack":"");
183   printf("\tEncoding Flags:\t{0x%02x, 0x%02x}\n", flag1, flag2);
184   printf("\tMessage:\n");
185   printf("\t\t%s\n", msg);
186
187   free(msg);
188
189   return;
190 }
This page took 0.050492 seconds and 5 git commands to generate.