I think your idea sounds great.
You'll need to decide if you want mobs to ever be able to guard each other, for instance based on scripts. If not, then just go ahead using player_specials. Otherwise, I'd use char_specials, both NPCs and PCs have those.
Setting up "guarding/guarded_by"-pointers is a decent way, but it limits you in some ways; only one can ever guard a particular player.
Another option would be to simply add a flag "guarded" to the one that is being protected and loop through local (in_room) players to see if they are guarding this particular target if they are being hit in a fight. The list of players in a room is short and quick to traverse. I'd disallow guarding if you were being guarded as well as guarding someone who is already guarding someone else, to prevent loops.
This would also mean an additional lookup on every disconnect through all players, but that full loop would happen much more rarely.
Yet another option is to duplicate the functionality for followers (following/follow_struct-list of followers). But this is much more complicated and error-prone; the following-mechanic has been a frequent source of bugs.