• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dhcp_event_fuzzer.h"
17 #include "dhcp_event.h"
18 #include "securec.h"
19 #include <cstring>
20 #include <vector>
21 #include <string>
22 #include <memory>
23 #include <mutex>
24 #include <thread>
25 #include <chrono>
26 
27 namespace OHOS {
28     constexpr size_t MIN_FUZZ_SIZE = 4;
29     constexpr size_t MAX_FUZZ_SIZE = 4096;
30     constexpr size_t IP_ADDR_LEN = 16;
31     constexpr size_t IFNAME_MAX_LEN = 16;
32     constexpr size_t REASON_MAX_LEN = 256;
33     constexpr size_t VENDOR_MAX_LEN = 255;
34     constexpr size_t MAC_ADDR_LEN = 18;
35     constexpr size_t DEVICE_NAME_LEN = 64;
36     constexpr size_t IPV6_ADDR_LEN = 40;
37     constexpr size_t MAX_DNS_COUNT = 5;
38     constexpr size_t MAX_STATIONS_COUNT = 10;
39     constexpr size_t MAX_LEASES_COUNT = 10;
40     constexpr size_t THREAD_LOOP_COUNT = 10;
41     constexpr size_t CALLBACK_LOOP_COUNT = 5;
42     constexpr size_t IP_RANGE_MAX = 255;
43     constexpr size_t MAC_RANGE_MAX = 256;
44     constexpr size_t LARGE_TEST_COUNT = 1000;
45     constexpr size_t LONG_STRING_LEN = 1024;
46     constexpr size_t VERY_LONG_STRING_LEN = 2048;
47     constexpr size_t LARGE_VECTOR_SIZE = 1000;
48     constexpr size_t MALFORMED_STRING_LEN = 256;
49     constexpr size_t OPERATION_TYPE_COUNT = 8;
50     constexpr size_t ADDITIONAL_DATA_CHECK_SIZE = 50;
51     constexpr uint8_t PARSER_SINGLE_BYTE = 1;
52     constexpr size_t LOOP_START_INDEX = 0;
53     constexpr int32_t SUCCESS_STATUS = 0;
54     constexpr uint32_t MICROSECOND_DELAY = 1;
55     constexpr int32_t FUNCTION_SUCCESS = 0;
56 
57     // Switch case constants for fuzzing operations
58     constexpr uint8_t OP_CLIENT_SUCCESS = 0;
59     constexpr uint8_t OP_CLIENT_FAIL = 1;
60     constexpr uint8_t OP_CLIENT_REPORT_OR_SERVER = 2;
61     constexpr uint8_t OP_SERVER_CALLBACK = 3;
62     constexpr uint8_t OP_RESULT_INFO_COPY = 4;
63     constexpr uint8_t OP_CALLBACK_REGISTRATION = 5;
64     constexpr uint8_t OP_CONCURRENT_OPERATIONS = 6;
65     constexpr uint8_t OP_EDGE_CASES = 7;
66 
67     class FuzzDataParser {
68     public:
FuzzDataParser(const uint8_t * data,size_t size)69         explicit FuzzDataParser(const uint8_t* data, size_t size)
70             : data_(data), size_(size), pos_(LOOP_START_INDEX) {}
71 
HasData(size_t length) const72         bool HasData(size_t length) const
73         {
74             return pos_ + length <= size_;
75         }
76 
77         template<typename T>
Extract()78         T Extract()
79         {
80             if (!HasData(sizeof(T))) {
81                 return T{};
82             }
83             T value;
84             if (memcpy_s(&value, sizeof(T), data_ + pos_, sizeof(T)) != EOK) {
85                 return T{};
86             }
87             pos_ += sizeof(T);
88             return value;
89         }
90 
ExtractString(size_t maxLen)91         std::string ExtractString(size_t maxLen)
92         {
93             if (!HasData(PARSER_SINGLE_BYTE)) {
94                 return "";
95             }
96 
97             if (maxLen == 0) {
98                 return "";
99             }
100 
101             size_t len = Extract<uint8_t>() % maxLen;
102             if (!HasData(len)) {
103                 len = std::min(len, size_ - pos_);
104             }
105 
106             if (len == LOOP_START_INDEX) {
107                 return "";
108             }
109 
110             std::string result(reinterpret_cast<const char*>(data_ + pos_), len);
111             pos_ += len;
112 
113             // Ensure null termination and remove any embedded nulls
114             for (auto& c : result) {
115                 if (c == '\0') c = '_';
116             }
117             return result;
118         }
119 
ExtractBytes(size_t length)120         std::vector<uint8_t> ExtractBytes(size_t length)
121         {
122             if (!HasData(length)) {
123                 length = std::min(length, size_ - pos_);
124             }
125 
126             std::vector<uint8_t> result(data_ + pos_, data_ + pos_ + length);
127             pos_ += length;
128             return result;
129         }
130 
131     private:
132         const uint8_t* data_;
133         size_t size_;
134         size_t pos_;
135     };
136     // Mock callback implementations for testing
137     class MockClientCallBack {
138     public:
OnIpSuccessChanged(int status,const char * ifname,DhcpResult * result)139         static void OnIpSuccessChanged(int status, const char* ifname, DhcpResult* result)
140         {
141             // Mock implementation - just validate parameters
142             if (ifname == nullptr || result == nullptr) {
143                 return;
144             }
145             // Simulate some processing
146             volatile int dummy = status + strlen(ifname) + result->iptype;
147             (void)dummy;
148         }
149 
OnIpFailChanged(int status,const char * ifname,const char * reason)150         static void OnIpFailChanged(int status, const char* ifname, const char* reason)
151         {
152             // Mock implementation - just validate parameters
153             if (ifname == nullptr || reason == nullptr) {
154                 return;
155             }
156             // Simulate some processing
157             volatile int dummy = status + strlen(ifname) + strlen(reason);
158             (void)dummy;
159         }
160     };
161 
162     class MockDhcpClientReport {
163     public:
OnDhcpClientReport(int status,const char * ifname,DhcpResult * result)164         static void OnDhcpClientReport(int status, const char* ifname, DhcpResult* result)
165         {
166             // Mock implementation - just validate parameters
167             if (ifname == nullptr || result == nullptr) {
168                 return;
169             }
170             // Simulate some processing
171             volatile int dummy = status + strlen(ifname) + result->iptype;
172             (void)dummy;
173         }
174     };
175     class MockServerCallBack {
176     public:
OnServerSuccess(const char * ifname,DhcpStationInfo * infos,size_t size)177         static void OnServerSuccess(const char* ifname, DhcpStationInfo* infos, size_t size)
178         {
179             // Mock implementation - just validate parameters
180             if (ifname == nullptr || infos == nullptr || size <= LOOP_START_INDEX) {
181                 return;
182             }
183             // Simulate some processing
184             volatile int dummy = strlen(ifname) + size;
185             for (size_t i = LOOP_START_INDEX; i < size; i++) {
186                 dummy += strlen(infos[i].ipAddr);
187             }
188             (void)dummy;
189         }
190     };
CreateFuzzDhcpResult(FuzzDataParser & parser)191     OHOS::DHCP::DhcpResult CreateFuzzDhcpResult(FuzzDataParser& parser)
192     {
193         OHOS::DHCP::DhcpResult result;
194 
195         result.isOptSuc = parser.Extract<bool>();
196         result.iptype = parser.Extract<int32_t>();
197         result.strYourCli = parser.ExtractString(IP_ADDR_LEN);
198         result.strServer = parser.ExtractString(IP_ADDR_LEN);
199         result.strSubnet = parser.ExtractString(IP_ADDR_LEN);
200         result.strDns1 = parser.ExtractString(IP_ADDR_LEN);
201         result.strDns2 = parser.ExtractString(IP_ADDR_LEN);
202         result.strRouter1 = parser.ExtractString(IP_ADDR_LEN);
203         result.strRouter2 = parser.ExtractString(IP_ADDR_LEN);
204         result.strVendor = parser.ExtractString(VENDOR_MAX_LEN);
205         result.strLinkIpv6Addr = parser.ExtractString(IPV6_ADDR_LEN); // IPv6 address length
206         result.strRandIpv6Addr = parser.ExtractString(IPV6_ADDR_LEN);
207         result.strLocalAddr1 = parser.ExtractString(IPV6_ADDR_LEN);
208         result.strLocalAddr2 = parser.ExtractString(IPV6_ADDR_LEN);
209         result.uLeaseTime = parser.Extract<uint32_t>();
210         result.uAddTime = parser.Extract<uint32_t>();
211         result.uGetTime = parser.Extract<uint32_t>();
212 
213         // Add some DNS addresses
214         size_t dnsCount = parser.Extract<uint8_t>() % MAX_DNS_COUNT; // Max DNS addresses
215         for (size_t i = LOOP_START_INDEX; i < dnsCount; i++) {
216             std::string dns = parser.ExtractString(IP_ADDR_LEN);
217             if (!dns.empty()) {
218                 result.vectorDnsAddr.push_back(dns);
219             }
220         }
221 
222         return result;
223     }
224 
CreateFuzzStationInfos(FuzzDataParser & parser)225     std::vector<DhcpStationInfo> CreateFuzzStationInfos(FuzzDataParser& parser)
226     {
227         std::vector<DhcpStationInfo> infos;
228 
229         size_t count = parser.Extract<uint8_t>() % MAX_STATIONS_COUNT; // Max stations
230         for (size_t i = LOOP_START_INDEX; i < count; i++) {
231             DhcpStationInfo info;
232 
233             std::string ip = parser.ExtractString(IP_ADDR_LEN);
234             if (strncpy_s(info.ipAddr, sizeof(info.ipAddr), ip.c_str(), ip.length()) != EOK) {
235                 strncpy_s(info.ipAddr, sizeof(info.ipAddr), "192.168.1.100", strlen("192.168.1.100"));
236             }
237 
238             std::string mac = parser.ExtractString(MAC_ADDR_LEN);
239             if (strncpy_s(info.macAddr, sizeof(info.macAddr), mac.c_str(), mac.length()) != EOK) {
240                 strncpy_s(info.macAddr, sizeof(info.macAddr), "00:11:22:33:44:55", strlen("00:11:22:33:44:55"));
241             }
242 
243             std::string device = parser.ExtractString(DEVICE_NAME_LEN);
244             if (strncpy_s(info.deviceName, sizeof(info.deviceName), device.c_str(), device.length()) != EOK) {
245                 strncpy_s(info.deviceName, sizeof(info.deviceName), "TestDevice", strlen("TestDevice"));
246             }
247 
248             infos.push_back(info);
249         }
250 
251         return infos;
252     }
253 
FuzzClientCallBackOnIpSuccess(FuzzDataParser & parser)254     void FuzzClientCallBackOnIpSuccess(FuzzDataParser& parser)
255     {
256         DhcpClientCallBack clientCallback;
257 
258         int status = parser.Extract<int32_t>();
259         std::string ifname = parser.ExtractString(IFNAME_MAX_LEN);
260         OHOS::DHCP::DhcpResult result = CreateFuzzDhcpResult(parser);
261 
262         // Register mock callback
263         ClientCallBack mockCallback = {
264             MockClientCallBack::OnIpSuccessChanged,
265             MockClientCallBack::OnIpFailChanged
266         };
267 
268         clientCallback.RegisterCallBack(ifname, &mockCallback);
269 
270         // Test the callback
271         clientCallback.OnIpSuccessChanged(status, ifname, result);
272 
273         // Unregister
274         clientCallback.UnRegisterCallBack(ifname);
275     }
276 
FuzzClientCallBackOnIpFail(FuzzDataParser & parser)277     void FuzzClientCallBackOnIpFail(FuzzDataParser& parser)
278     {
279         DhcpClientCallBack clientCallback;
280 
281         int status = parser.Extract<int32_t>();
282         std::string ifname = parser.ExtractString(IFNAME_MAX_LEN);
283         std::string reason = parser.ExtractString(REASON_MAX_LEN);
284 
285         // Register mock callback
286         ClientCallBack mockCallback = {
287             MockClientCallBack::OnIpSuccessChanged,
288             MockClientCallBack::OnIpFailChanged
289         };
290 
291         clientCallback.RegisterCallBack(ifname, &mockCallback);
292 
293         // Test the callback
294         clientCallback.OnIpFailChanged(status, ifname, reason);
295 
296         // Unregister
297         clientCallback.UnRegisterCallBack(ifname);
298     }
299 
300 #ifndef OHOS_ARCH_LITE
FuzzClientCallBackOnDhcpOfferReport(FuzzDataParser & parser)301     void FuzzClientCallBackOnDhcpOfferReport(FuzzDataParser& parser)
302     {
303         DhcpClientCallBack clientCallback;
304 
305         int status = parser.Extract<int32_t>();
306         std::string ifname = parser.ExtractString(IFNAME_MAX_LEN);
307         OHOS::DHCP::DhcpResult result = CreateFuzzDhcpResult(parser);
308 
309         // Register mock report callback
310         DhcpClientReport mockReport = {
311             MockDhcpClientReport::OnDhcpClientReport
312         };
313 
314         clientCallback.RegisterDhcpClientReportCallBack(ifname, &mockReport);
315 
316         // Test the callback
317         clientCallback.OnDhcpOfferReport(status, ifname, result);
318     }
319 #endif
320 
FuzzServerCallBack(FuzzDataParser & parser)321     void FuzzServerCallBack(FuzzDataParser& parser)
322     {
323         DhcpServerCallBack serverCallback;
324 
325         int status = parser.Extract<int32_t>();
326         std::string ifname = parser.ExtractString(IFNAME_MAX_LEN);
327 
328         // Test OnServerStatusChanged
329         serverCallback.OnServerStatusChanged(status);
330 
331         // Test OnServerLeasesChanged
332         std::vector<std::string> leases;
333         size_t leaseCount = parser.Extract<uint8_t>() % MAX_LEASES_COUNT;
334         for (size_t i = LOOP_START_INDEX; i < leaseCount; i++) {
335             std::string lease = parser.ExtractString(REASON_MAX_LEN);
336             leases.push_back(lease);
337         }
338         serverCallback.OnServerLeasesChanged(ifname, leases);
339 
340         // Test OnServerSerExitChanged
341         serverCallback.OnServerSerExitChanged(ifname);
342 
343         // Test OnServerSuccess
344         std::vector<DhcpStationInfo> stationInfos = CreateFuzzStationInfos(parser);
345 
346         // Register mock callback
347         ServerCallBack mockCallback;
348         mockCallback.OnServerSuccess = MockServerCallBack::OnServerSuccess;
349 
350         serverCallback.RegisterCallBack(ifname, &mockCallback);
351         serverCallback.OnServerSuccess(ifname, stationInfos);
352 
353         // Unregister
354         serverCallback.UnRegisterCallBack(ifname);
355     }
356 
FuzzResultInfoCopy(FuzzDataParser & parser)357     void FuzzResultInfoCopy(FuzzDataParser& parser)
358     {
359         DhcpClientCallBack clientCallback;
360 
361         DhcpResult cResult;
362         OHOS::DHCP::DhcpResult oResult = CreateFuzzDhcpResult(parser);
363 
364         // Test ResultInfoCopy with various data
365         clientCallback.ResultInfoCopy(cResult, oResult);
366     }
367 
FuzzCallBackRegistration(FuzzDataParser & parser)368     void FuzzCallBackRegistration(FuzzDataParser& parser)
369     {
370         DhcpClientCallBack clientCallback;
371         DhcpServerCallBack serverCallback;
372 
373         std::string ifname1 = parser.ExtractString(IFNAME_MAX_LEN);
374         std::string ifname2 = parser.ExtractString(IFNAME_MAX_LEN);
375 
376         // Test client callback registration
377         ClientCallBack mockClientCallback = {
378             MockClientCallBack::OnIpSuccessChanged,
379             MockClientCallBack::OnIpFailChanged
380         };
381 
382         // Test multiple registrations with same interface
383         clientCallback.RegisterCallBack(ifname1, &mockClientCallback);
384         clientCallback.RegisterCallBack(ifname1, &mockClientCallback); // Update
385 
386         // Test registration with different interfaces
387         clientCallback.RegisterCallBack(ifname2, &mockClientCallback);
388 
389         // Test null pointer registration
390         clientCallback.RegisterCallBack(ifname1, nullptr);
391 
392         // Test unregistration
393         clientCallback.UnRegisterCallBack(ifname1);
394         clientCallback.UnRegisterCallBack(ifname2);
395         clientCallback.UnRegisterCallBack(""); // Empty interface name
396         clientCallback.UnRegisterCallBack("nonexistent"); // Non-existent interface
397 
398         // Test server callback registration
399         // Register mock callback
400         ServerCallBack mockServerCallback;
401         mockServerCallback.OnServerSuccess = MockServerCallBack::OnServerSuccess;
402 
403         serverCallback.RegisterCallBack(ifname1, &mockServerCallback);
404         serverCallback.RegisterCallBack(ifname1, &mockServerCallback); // Update
405         serverCallback.RegisterCallBack(ifname2, &mockServerCallback);
406         serverCallback.RegisterCallBack(ifname1, nullptr); // Null pointer
407 
408         serverCallback.UnRegisterCallBack(ifname1);
409         serverCallback.UnRegisterCallBack("");
410         serverCallback.UnRegisterCallBack("nonexistent");
411 
412 #ifndef OHOS_ARCH_LITE
413         // Test DHCP client report registration
414         DhcpClientReport mockReport = {
415             MockDhcpClientReport::OnDhcpClientReport
416         };
417 
418         clientCallback.RegisterDhcpClientReportCallBack(ifname1, &mockReport);
419         clientCallback.RegisterDhcpClientReportCallBack(ifname1, nullptr);
420 #endif
421     }
422 
FuzzConcurrentOperations(FuzzDataParser & parser)423     void FuzzConcurrentOperations(FuzzDataParser& parser)
424     {
425         std::shared_ptr<DhcpClientCallBack> clientCallback = std::make_shared<DhcpClientCallBack>();
426         std::shared_ptr<DhcpServerCallBack> serverCallback = std::make_shared<DhcpServerCallBack>();
427 
428         std::string ifname = parser.ExtractString(IFNAME_MAX_LEN);
429 
430         // Create mock callbacks
431         ClientCallBack mockClientCallback = {
432             MockClientCallBack::OnIpSuccessChanged,
433             MockClientCallBack::OnIpFailChanged
434         };
435 
436         // Register mock callback
437         ServerCallBack mockServerCallback;
438         mockServerCallback.OnServerSuccess = MockServerCallBack::OnServerSuccess;
439 
440         // Test concurrent registration and unregistration
441         std::vector<std::thread> threads;
442 
443         // Thread 1: Register/unregister client callbacks
444         threads.emplace_back([clientCallback, ifname, &mockClientCallback]() {
445             for (size_t i = LOOP_START_INDEX; i < THREAD_LOOP_COUNT; i++) {
446                 clientCallback->RegisterCallBack(ifname, &mockClientCallback);
447                 std::this_thread::sleep_for(std::chrono::microseconds(MICROSECOND_DELAY));
448                 clientCallback->UnRegisterCallBack(ifname);
449             }
450         });
451 
452         // Thread 2: Register/unregister server callbacks
453         threads.emplace_back([serverCallback, ifname, &mockServerCallback]() {
454             for (size_t i = LOOP_START_INDEX; i < THREAD_LOOP_COUNT; i++) {
455                 serverCallback->RegisterCallBack(ifname, &mockServerCallback);
456                 std::this_thread::sleep_for(std::chrono::microseconds(MICROSECOND_DELAY));
457                 serverCallback->UnRegisterCallBack(ifname);
458             }
459         });
460 
461         // Thread 3: Trigger callbacks
462         threads.emplace_back([clientCallback, ifname, &parser]() {
463             OHOS::DHCP::DhcpResult result = CreateFuzzDhcpResult(const_cast<FuzzDataParser&>(parser));
464             for (size_t i = LOOP_START_INDEX; i < CALLBACK_LOOP_COUNT; i++) {
465                 clientCallback->OnIpSuccessChanged(i, ifname, result);
466                 clientCallback->OnIpFailChanged(i, ifname, "test_reason");
467                 std::this_thread::sleep_for(std::chrono::microseconds(MICROSECOND_DELAY));
468             }
469         });
470 
471         // Wait for all threads to complete
472         for (auto& thread : threads) {
473             if (thread.joinable()) {
474                 thread.join();
475             }
476         }
477     }
478 
FuzzEdgeCases(FuzzDataParser & parser)479     void FuzzEdgeCases(FuzzDataParser& parser)
480     {
481         DhcpClientCallBack clientCallback;
482         DhcpServerCallBack serverCallback;
483 
484         // Test with empty strings
485         OHOS::DHCP::DhcpResult result = CreateFuzzDhcpResult(parser);
486         clientCallback.OnIpSuccessChanged(SUCCESS_STATUS, "", result);
487         clientCallback.OnIpFailChanged(SUCCESS_STATUS, "", "");
488 
489         // Test with very long strings
490         std::string longIfname(LONG_STRING_LEN, 'A');
491         std::string longReason(VERY_LONG_STRING_LEN, 'B');
492         clientCallback.OnIpFailChanged(SUCCESS_STATUS, longIfname, longReason);
493 
494         // Test with special characters
495         std::string specialIfname = "\x00\xFF\x01\x02test\n\r\t";
496         std::string specialReason = "!@#$%^&*()_+{}|:<>?test";
497         clientCallback.OnIpFailChanged(SUCCESS_STATUS, specialIfname, specialReason);
498 
499         // Test with extreme numeric values
500         clientCallback.OnIpSuccessChanged(std::numeric_limits<int32_t>::max(), "test", result);
501         clientCallback.OnIpSuccessChanged(std::numeric_limits<int32_t>::min(), "test", result);
502 
503         // Test with very large station info list
504         std::vector<DhcpStationInfo> largeStationInfos;
505         for (size_t i = LOOP_START_INDEX; i < LARGE_TEST_COUNT; i++) {
506             DhcpStationInfo info;
507             int ret = snprintf_s(info.ipAddr, sizeof(info.ipAddr), sizeof(info.ipAddr) - 1,
508                 "192.168.1.%d", i % IP_RANGE_MAX);
509             if (ret < 0) {
510                 continue; // Skip if snprintf fails
511             }
512             ret = snprintf_s(info.macAddr, sizeof(info.macAddr), sizeof(info.macAddr) - 1,
513                 "00:11:22:33:44:%02X", i % MAC_RANGE_MAX);
514             if (ret < 0) {
515                 continue; // Skip if snprintf fails
516             }
517             ret = snprintf_s(info.deviceName, sizeof(info.deviceName), sizeof(info.deviceName) - 1, "Device%d", i);
518             if (ret < 0) {
519                 continue; // Skip if snprintf fails
520             }
521             largeStationInfos.push_back(info);
522         }
523         serverCallback.OnServerSuccess("test", largeStationInfos);
524 
525         // Test ResultInfoCopy with malformed data
526         OHOS::DHCP::DhcpResult malformedResult;
527         malformedResult.strYourCli = std::string(VERY_LONG_STRING_LEN, 'X'); // Very long string
528         malformedResult.vectorDnsAddr.resize(LARGE_VECTOR_SIZE); // Very large vector
529         for (auto& dns : malformedResult.vectorDnsAddr) {
530             dns = std::string(MALFORMED_STRING_LEN, 'Y');
531         }
532 
533         DhcpResult cResult;
534         clientCallback.ResultInfoCopy(cResult, malformedResult);
535     }
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)536 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
537 {
538     // Check minimum input size
539     if (data == nullptr || size < MIN_FUZZ_SIZE || size > MAX_FUZZ_SIZE) {
540         return FUNCTION_SUCCESS;
541     }
542 
543     FuzzDataParser parser(data, size);
544 
545     // Extract operation type
546     uint8_t operation = parser.Extract<uint8_t>() % OPERATION_TYPE_COUNT;
547 
548     switch (operation) {
549         case OP_CLIENT_SUCCESS:
550             FuzzClientCallBackOnIpSuccess(parser);
551             break;
552         case OP_CLIENT_FAIL:
553             FuzzClientCallBackOnIpFail(parser);
554             break;
555         case OP_CLIENT_REPORT_OR_SERVER:
556 #ifndef OHOS_ARCH_LITE
557             FuzzClientCallBackOnDhcpOfferReport(parser);
558 #else
559             FuzzServerCallBack(parser);
560 #endif
561             break;
562         case OP_SERVER_CALLBACK:
563             FuzzServerCallBack(parser);
564             break;
565         case OP_RESULT_INFO_COPY:
566             FuzzResultInfoCopy(parser);
567             break;
568         case OP_CALLBACK_REGISTRATION:
569             FuzzCallBackRegistration(parser);
570             break;
571         case OP_CONCURRENT_OPERATIONS:
572             FuzzConcurrentOperations(parser);
573             break;
574         case OP_EDGE_CASES:
575             FuzzEdgeCases(parser);
576             break;
577         default:
578             // Fallback to basic operation
579             FuzzClientCallBackOnIpSuccess(parser);
580             break;
581     }
582     // Additional comprehensive testing
583     if (parser.HasData(ADDITIONAL_DATA_CHECK_SIZE)) {
584         // Perform multiple operations in sequence
585         FuzzResultInfoCopy(parser);
586         FuzzCallBackRegistration(parser);
587     }
588     return FUNCTION_SUCCESS;
589 }
590 }